Przeglądaj źródła

add scripts support :eyes:

Ethosa 3 lat temu
rodzic
commit
4bd60100a2

+ 6 - 2
README.md

@@ -67,7 +67,7 @@ This section contains links to documentation for all nodes.
 |[Anchor][]      |[Node][]             |[Control][]           |[Node2D][]          |[Node3D][]          |[Drawable][]        |
 |[Color][]       |[Canvas][]           |[ColorRect][]         |[Sprite][]          |[GeometryInstance][]|[GradientDrawable][]|
 |[Font][]        |[Scene][]            |[TextureRect][]       |[AnimatedSprite][]  |[Camera3D][]        |                    |
-|[Enums][]       |[AudioStreamPlayer][]|[Label][]             |[YSort][]           |                    |                    |
+|[Enums][]       |[AudioStreamPlayer][]|[Label][]             |[YSort][]           |[Sprite3D][]        |                    |
 |[Exceptions][]  |[AnimationPlayer][]  |[Button][]            |[CollisionShape2D][]|                    |                    |
 |[Image][]       |                     |[EditText][]          |[Camera2D][]        |                    |                    |
 |[Input][]       |                     |[Box][]               |[TileMap][]         |                    |                    |
@@ -81,9 +81,10 @@ This section contains links to documentation for all nodes.
 |[SceneBuilder][]|                     |[TextureButton][]     |                    |                    |                    |
 |[StyleSheet][]  |                     |[TextureProgressBar][]|                    |                    |                    |
 |[TileSet][]     |                     |[Counter][]           |                    |                    |                    |
-|                |                     |[Switch][]            |                    |                    |                    |
+|[Scripts][]     |                     |[Switch][]            |                    |                    |                    |
 |                |                     |[SubWindow][]         |                    |                    |                    |
 |                |                     |[CheckBox][]          |                    |                    |                    |
+|                |                     |[ToolTip][]           |                    |                    |                    |
 
 
 
@@ -154,6 +155,7 @@ Also use [`niminst`](https://github.com/nim-lang/niminst) tool for generate an i
 [Font]:https://ethosa.github.io/nodesnim/nodesnim/core/font.html
 [StyleSheet]:https://ethosa.github.io/nodesnim/nodesnim/core/stylesheet.html
 [TileSet]:https://ethosa.github.io/nodesnim/nodesnim/core/tileset.html
+[Scripts]:https://ethosa.github.io/nodesnim/nodesnim/core/scripts.html
 
 [Node]:https://ethosa.github.io/nodesnim/nodesnim/nodes/node.html
 [Canvas]:https://ethosa.github.io/nodesnim/nodesnim/nodes/canvas.html
@@ -183,6 +185,7 @@ Also use [`niminst`](https://github.com/nim-lang/niminst) tool for generate an i
 [Switch]:https://ethosa.github.io/nodesnim/nodesnim/nodescontrol/switch.html
 [SubWindow]:https://ethosa.github.io/nodesnim/nodesnim/nodescontrol/subwindow.html
 [CheckBox]:https://ethosa.github.io/nodesnim/nodesnim/nodescontrol/checkbox.html
+[ToolTip]:https://ethosa.github.io/nodesnim/nodesnim/nodescontrol/tooltip.html
 
 [Node2D]:https://ethosa.github.io/nodesnim/nodesnim/nodes2d/node2d.html
 [Sprite]:https://ethosa.github.io/nodesnim/nodesnim/nodes2d/sprite.html
@@ -197,6 +200,7 @@ Also use [`niminst`](https://github.com/nim-lang/niminst) tool for generate an i
 [Node3D]:https://ethosa.github.io/nodesnim/nodesnim/nodes3d/node3d.html
 [GeometryInstance]:https://ethosa.github.io/nodesnim/nodesnim/nodes3d/geometry_instance.html
 [Camera3D]:https://ethosa.github.io/nodesnim/nodesnim/nodes3d/camera3d.html
+[Sprite3D]:https://ethosa.github.io/nodesnim/nodesnim/nodes3d/sprite3d.html
 
 [Drawable]:https://ethosa.github.io/nodesnim/nodesnim/graphics/drawable.html
 [GradientDrawable]:https://ethosa.github.io/nodesnim/nodesnim/graphics/gradient_drawable.html

+ 1 - 0
nodesnim.nimble

@@ -8,3 +8,4 @@ srcDir = "src"
 
 [Deps]
 Requires: "nim >= 1.0.0"
+Requires: "compiler >= 1.0.0"

+ 1 - 0
src/nodesnim/core/exceptions.nim

@@ -3,4 +3,5 @@
 type
   ResourceError* {.size: sizeof(int8).} = object of ValueError
   SceneError* {.size: sizeof(int8).} = object of ValueError
+  VMError* {.size: sizeof(int8).} = object of ValueError
   WindowError* {.size: sizeof(int8).} = object of ValueError

+ 124 - 0
src/nodesnim/core/scripts.nim

@@ -0,0 +1,124 @@
+# author: Ethosa
+## It provides runtime scripts loader.
+import
+  compiler / [
+    astalgo, ast, vmdef, vm, options,
+    modulegraphs, idents, modules,
+    pathutils, llstream, passes, sem,
+    condsyms
+  ],
+
+  exceptions,
+
+  os
+
+
+type
+  CompiledScript = ref object
+    pctx*: PCtx
+    graph*: ModuleGraph
+    module*: PSym
+    filename*: string
+
+
+var
+  ident_cache = newIdentCache()
+  cfg = newConfigRef()
+
+once:
+  # Search .nimble/lib folder 👀
+  cfg.libpath = AbsoluteDir(getHomeDir() / ".nimble" / "lib")
+  cfg.searchPaths.add(cfg.libpath)
+  cfg.searchPaths.add(AbsoluteDir($cfg.libpath / "pure"))
+
+
+# --- Convert default Nim types to PNode --- #
+converter toNode*(x: float): PNode = newFloatNode(nkFloatLit, x)
+converter toNode*(x: int): PNode = newIntNode(nkIntLit, x)
+converter toNode*(x: string): PNode = newStrNode(nkStrLit, x)
+converter toNode*(x: bool): PNode = x.ord.toNode()
+converter toNode*(x: enum): PNode = x.ord.toNode()
+
+converter toNode*(x: openarray[int|float|string|bool|enum]): PNode =
+  result = newNode(nkBracket)
+  result.sons.initialize(x.len)
+  for i in x.low..x.high:
+    result[i] = x[i].toNode()
+converter toNode*(x: tuple | object): PNode =
+  result = newTree(nkPar)
+  for field in x.fields:
+    result.sons.add(field.toNode())
+converter toNode*(x: ref tuple | ref object): PNode =
+  result = newTree(nkPar)
+  if x.isNil():
+    return result
+  for field in x.fields:
+    result.sons.add(field.toNode())
+
+
+proc setupModule(self: CompiledScript) =
+  self.graph.connectCallbacks()
+  initDefines(cfg.symbols)
+  defineSymbol(cfg.symbols, "nimscript")
+  defineSymbol(cfg.symbols, "nimconfig")
+  self.graph.registerPass(semPass)
+  self.graph.registerPass(evalPass)
+
+
+proc cleanupModule(self: CompiledScript) =
+  initDefines(cfg.symbols)
+  undefSymbol(cfg.symbols, "nimscript")
+  undefSymbol(cfg.symbols, "nimconfig")
+  clearPasses(self.graph)
+
+
+proc compileScript*(file: string): CompiledScript =
+  ## Compiles script with std module.
+  new result
+  result.filename = file
+  result.graph = newModuleGraph(ident_cache, cfg)
+  result.setupModule()
+  result.module = makeModule(result.graph, file)
+
+  # Create context
+  incl(result.module.flags, sfMainModule)
+  result.pctx = newCtx(result.module, identCache, result.graph)
+  result.pctx.mode = emRepl
+
+  # Setup context
+  setupGlobalCtx(result.module, result.graph)
+  registerAdditionalOps(result.pctx)
+
+  # Compile std
+  compileSystemModule(result.graph)
+
+  # Compile module
+  if not processModule(result.graph, result.module, llStreamOpen(AbsoluteFile(file), fmRead)):
+    raise newException(VMError, "Failed to process `" & file & "`")
+
+  # Cleanup
+  setupGlobalCtx(nil, result.graph)
+  result.cleanupModule()
+
+
+proc getProc*(self: CompiledScript, routine: string): PSym =
+  strTableGet(self.module.tab, getIdent(identCache, routine))
+
+proc hasProc*(self: CompiledScript, routine: string): bool =
+  ## Returns true, if `routine` available.
+  not self.getProc(routine).isNil()
+
+
+proc call*(self: CompiledScript, routine: string,
+           args: varargs[PNode]): PNode {.discardable.} =
+  ## Calls routine by name
+  # Setup context
+  setupGlobalCtx(self.module, self.graph)
+
+  # Find routine
+  let prc = self.getProc(routine)
+  if prc.isNil():
+    raise newException(VMError, "\nUnable to locate proc `" & routine & "` in `" & self.filename & "`")
+
+  # Call routine
+  result = execProc(self.pctx, prc, args)

+ 1 - 1
src/nodesnim/nodescontrol/tooltip.nim

@@ -42,7 +42,7 @@ proc ToolTip*(name: string = "ToolTip",
   result.hide()
 
 
-method draw*(self: ToolTipRef, w, h: GLfloat) =
+method postdraw*(self: ToolTipRef, w, h: GLfloat) =
   procCall self.ControlRef.draw(w, h)
   let
     x = -w/2 + self.global_position.x