Browse Source

fix `scene_loader` :eyes:

Ethosa 3 years ago
parent
commit
c0acfdd14e
5 changed files with 221 additions and 168 deletions
  1. 28 12
      src/nodesnim/runtime/scene_loader.nim
  2. 25 21
      tests/test2.nim
  3. 99 83
      tests/test3.nim
  4. 51 47
      tests/test6.nim
  5. 18 5
      tests/test8.nim

+ 28 - 12
src/nodesnim/runtime/scene_loader.nim

@@ -6,6 +6,7 @@ import
   ../nodescontrol,
   ../nodes2d,
   ../nodes3d,
+  ../graphics,
 
   xmltree,
   xmlparser,
@@ -21,13 +22,20 @@ macro `mkattrs`*(properties_var, prop_list: untyped): untyped =
 
   result = newStmtList()
 
-  for property in prop_list:
-    if property[0].kind != nnkCall:
-      return
-    result.add quote do:
-      `properties_var[0]`[`property[0]`] =
-        proc(`properties_var[1]`: NodeRef, `properties_var[2]`: string) =
-          `property[1]`
+  for prop in prop_list:
+    if prop.kind != nnkCall:
+      continue
+    var
+      lambda = newProc(
+        newEmptyNode(),
+        [newEmptyNode(),
+         newIdentDefs(properties_var[1], ident("NodeRef"), newEmptyNode()),
+         newIdentDefs(properties_var[2], ident("string"), newEmptyNode())],
+        prop[1]
+      )
+    result.add(
+      newCall("[]=", properties_var[0], prop[0], lambda)
+    )
 
 
 macro mkparse*(nodes: varargs[untyped]): untyped =
@@ -44,8 +52,8 @@ macro mkparse*(nodes: varargs[untyped]): untyped =
 
 
 var
-  parsable = initTable[system.string, proc (name: string): NodeRef]()
-  properties = initTable[system.string, proc (node: NodeRef, value: string)]()
+  parsable* = initTable[system.string, proc (name: string): NodeRef]()
+  attrs* = initTable[system.string, proc (node: NodeRef, value: string)]()
 
 mkparse(Node, Scene, AudioStreamPlayer, AnimationPlayer)
 mkparse(Control, Box, VBox, HBox, ColorRect, Label, SubWindow, ToolTip,
@@ -54,7 +62,7 @@ mkparse(Control, Box, VBox, HBox, ColorRect, Label, SubWindow, ToolTip,
 mkparse(Node2D, Sprite, AnimatedSprite, KinematicBody2D, CollisionShape2D, TileMap, Camera2D, YSort)
 mkparse(Node3D, Sprite3D, GeometryInstance)
 
-mkattrs properties(node, value):
+mkattrs attrs(node, value):
   "color":
     node.ColorRectRef.color = Color(value)
   "name":
@@ -91,7 +99,7 @@ mkattrs properties(node, value):
       if matchColor(i):
         node.ControlRef.setBackgroundColor(Color(i))
       elif i.matchBackgroundImage(matches):
-        node.ControlRef.setBackgroundImage(matches[0])
+        node.ControlRef.background.loadTexture(matches[0])
 
   "size_anchor":
     let val = value.split(Whitespace)
@@ -112,7 +120,7 @@ mkattrs properties(node, value):
 
 proc xmlAttr(xml: XmlNode, node: NodeRef) =
   if not xml.attrs.isNil():
-    for attr, fn in properties.pairs:
+    for attr, fn in attrs.pairs:
       if xml.attrs.hasKey(attr):
         fn(node, xml.attrs[attr])
 
@@ -145,3 +153,11 @@ proc loadScene*(file: string): NodeRef =
     level: seq[NodeRef] = @[]
   level.add(result)
   xmlNode(xml, level)
+
+proc loadSceneFromString*(scene_name, source: string): NodeRef =
+  result = Scene(scene_name)
+  var
+    xml = parseXml(source)
+    level: seq[NodeRef] = @[]
+  level.add(result)
+  xmlNode(xml, level)

+ 25 - 21
tests/test2.nim

@@ -17,17 +17,18 @@ suite "Work with default nodes.":
   test "Canvas test":
     build:
       - Canvas canvas:
-        call resize(256, 256)
-        call fill(Color("#ffaacc"))
-        call point(5, 5, Color("#64ffff"))
-        call line(8, 16, 128, 64, Color("#ffff64ff"))
-        call circle(0, 240, 32, Color("#aaff6456"))
-        call line(200, -150, 0, 256, Color("#0e1317ff"))
-        call bezier(0, 0, 256, 0, 256, 256, Color("#227"))
-        call cubic_bezier(0, 0, 256, 0, 0, 256, 256, 256, Color("#272"))
-        call move(74.4, 89.4)
-        call text("hello!,\nworld!", 64, 64, Vector2(1, 1))
-        call saveAs("assets/canvas.png")  # save result in file.
+        call:
+          resize(256, 256)
+          fill(Color("#ffaacc"))
+          point(5, 5, Color("#64ffff"))
+          line(8, 16, 128, 64, Color("#ffff64ff"))
+          circle(0, 240, 32, Color("#aaff6456"))
+          line(200, -150, 0, 256, Color("#0e1317ff"))
+          bezier(0, 0, 256, 0, 256, 256, Color("#227"))
+          cubic_bezier(0, 0, 256, 0, 0, 256, 256, 256, Color("#272"))
+          move(74.4, 89.4)
+          text("hello!,\nworld!", 64, 64, Vector2(1, 1))
+          saveAs("assets/canvas.png")  # save result in file.
     getSceneByName("main").addChild(canvas)
 
   test "AudioStreamPlayer test":
@@ -58,22 +59,25 @@ suite "Work with default nodes.":
         call resize(100, 100)
         call move(0, 300)
       - AnimationPlayer animation:
-        call addState(rect.color.r.addr, @[(tick: 0, value: 0.0), (tick: 200, value: 1.0)])
-        call addState(rect.position.x.addr, @[(tick: 0, value: 0.0), (tick: 100, value: 250.0)])
-        call setDuration(200)
-        call play()
         mode: ANIMATION_NORMAL  # Default animation mode.
+        call:
+          addState(rect.color.r.addr, @[(tick: 0, value: 0.0), (tick: 200, value: 1.0)])
+          addState(rect.position.x.addr, @[(tick: 0, value: 0.0), (tick: 100, value: 250.0)])
+          setDuration(200)
+          play()
       - AnimationPlayer animation1:
-        call addState(rect1.position.x.addr, @[(tick: 0, value: 0.0), (tick: 100, value: 250.0)])
-        call setDuration(200)
-        call play()
         mode: ANIMATION_EASE
+        call:
+          addState(rect1.position.x.addr, @[(tick: 0, value: 0.0), (tick: 100, value: 250.0)])
+          setDuration(200)
+          play()
       - AnimationPlayer animation2:
-        call addState(rect2.position.x.addr, @[(tick: 0, value: 0.0), (tick: 100, value: 250.0)])
-        call setDuration(200)
-        call play()
         mode: ANIMATION_BEZIER
         bezier: (0.8, 0.9)
+        call:
+          addState(rect2.position.x.addr, @[(tick: 0, value: 0.0), (tick: 100, value: 250.0)])
+          setDuration(200)
+          play()
     getSceneByName("main").addChildren(rect, rect1, rect2, animation, animation1, animation2)
 
   test "Launch window":

+ 99 - 83
tests/test3.nim

@@ -84,20 +84,23 @@ suite "Work with Control nodes.":
       - TextureRect texturerect1:
         texture_mode: TEXTURE_KEEP_ASPECT_RATIO
         texture_anchor: Anchor(0.5, 0.5, 0.5, 0.5)
-        call setTexture(load("assets/sharp.jpg"))
-        call resize(100, 100)
-        call move(120, 0)
+        call:
+          setTexture(load("assets/sharp.jpg"))
+          resize(100, 100)
+          move(120, 0)
       - TextureRect texturerect2:
         texture_mode: TEXTURE_CROP
         texture_anchor: Anchor(0.5, 0.5, 0.5, 0.5)
-        call setTexture(load("assets/sharp.jpg"))
-        call resize(100, 100)
-        call move(220, 0)
+        call:
+          setTexture(load("assets/sharp.jpg"))
+          resize(100, 100)
+          move(220, 0)
       - TextureRect texturerect3:
         texture_mode: TEXTURE_FILL_XY
-        call setTexture(load("assets/sharp.jpg"))
-        call resize(100, 100)
-        call move(320, 0)
+        call:
+          setTexture(load("assets/sharp.jpg"))
+          resize(100, 100)
+          move(320, 0)
     getSceneByName("main").addChildren(texturerect1, texturerect2, texturerect3)
 
 
@@ -117,9 +120,10 @@ suite "Work with Control nodes.":
   test "Button test":
     build:
       - Button btn:
-        call setText("Press me ^^")
-        call resize(196, 32)
-        call move(420, 0)
+        call:
+          setText("Press me ^^")
+          resize(196, 32)
+          move(420, 0)
     btn@onTouch(self, x, y):
       echo "clicked btn!"
       echo btn.text.chars[0].color
@@ -133,10 +137,11 @@ suite "Work with Control nodes.":
   test "Box test":
     build:
       - Box box:
-        call setChildAnchor(0.5, 0.5, 0.5, 0.5)
-        call setPadding(2, 4, 8, 16)
-        call move(420, 30)
-        call setBackgroundColor(Color(1f, 1f, 1f))
+        call:
+          setChildAnchor(0.5, 0.5, 0.5, 0.5)
+          setPadding(2, 4, 8, 16)
+          move(420, 30)
+          setBackgroundColor(Color(1f, 1f, 1f))
         - ColorRect first:
           color: Color(0xff6699ff'u32)
           call resize(80, 80)
@@ -151,10 +156,11 @@ suite "Work with Control nodes.":
   test "HBox test":
     build:
       - HBox hbox:
-        call setChildAnchor(1, 1, 1, 1)
-        call setPadding(2, 4, 8, 16)
-        call move(520, 30)
-        call setBackgroundColor(Color(1f, 1f, 1f))
+        call:
+          setChildAnchor(1, 1, 1, 1)
+          setPadding(2, 4, 8, 16)
+          move(520, 30)
+          setBackgroundColor(Color(1f, 1f, 1f))
         - ColorRect first:
           color: Color(0xff6699ff'u32)
           call resize(80, 80)
@@ -169,10 +175,11 @@ suite "Work with Control nodes.":
   test "VBox test":
     build:
       - VBox vbox:
-        call setChildAnchor(1, 1, 1, 1)
-        call setPadding(2, 4, 8, 16)
-        call move(420, 144)
-        call setBackgroundColor(Color(1f, 1f, 1f))
+        call:
+          setChildAnchor(1, 1, 1, 1)
+          setPadding(2, 4, 8, 16)
+          move(420, 144)
+          setBackgroundColor(Color(1f, 1f, 1f))
         - ColorRect first:
           color: Color(0xff6699ff'u32)
           call resize(80, 80)
@@ -187,10 +194,11 @@ suite "Work with Control nodes.":
   test "GridBox test":
     build:
       - GridBox grid:
-        call setPadding(2, 4, 8, 16)
-        call move(530, 144)
-        call setRow(3)
-        call setBackgroundColor(Color(1f, 1f, 1f))
+        call:
+          setPadding(2, 4, 8, 16)
+          move(530, 144)
+          setRow(3)
+          setBackgroundColor(Color(1f, 1f, 1f))
         - ColorRect first(color: Color(0xff6699ff'u32))
         - ColorRect second(color: Color(0xff64ffff'u32))
         - ColorRect third(color: Color(0xffaa00ff'u32))
@@ -213,9 +221,10 @@ suite "Work with Control nodes.":
       - Scroll scroll:
         call setAnchor(1, 0, 1, 0)
         - GridBox grid:
-          call setPadding(2, 4, 8, 16)
-          call setRow(3)
-          call setBackgroundColor(Color(1f, 1f, 1f))
+          call:
+            setPadding(2, 4, 8, 16)
+            setRow(3)
+            setBackgroundColor(Color(1f, 1f, 1f))
           - ColorRect first(color: Color(0xff6699ff'u32), rect_size: Vector2(100, 200))
           - ColorRect second(color: Color(0xff64ffff'u32))
           - ColorRect third(color: Color(0xffaa00ff'u32))
@@ -230,21 +239,24 @@ suite "Work with Control nodes.":
       - ProgressBar bar1:
         progress_type: PROGRESS_BAR_HORIZONTAL
         indeterminate: true
-        call setProgress(50)
-        call move(120, 110)
-        call resize(100, 20)
+        call:
+          setProgress(50)
+          move(120, 110)
+          resize(100, 20)
       - ProgressBar bar2:
         progress_type: PROGRESS_BAR_VERTICAL
         indeterminate: true
-        call setProgress(50)
-        call move(220, 100)
-        call resize(20, 110)
+        call:
+          setProgress(50)
+          move(220, 100)
+          resize(20, 110)
       - ProgressBar bar3:
         progress_type: PROGRESS_BAR_CIRCLE
         indeterminate: true
-        call setProgress(50)
-        call move(320, 110)
-        call resize(100, 100)
+        call:
+          setProgress(50)
+          move(320, 110)
+          resize(100, 100)
     getSceneByName("main").addChildren(bar1, bar2, bar3)
 
 
@@ -263,23 +275,25 @@ suite "Work with Control nodes.":
   test "TextureButton test":
     build:
       - TextureButton button:
-        call setNormalTexture(load("assets/button_normal.png", GL_RGBA))
-        call setHoverTexture(load("assets/button_hover.png", GL_RGBA))
-        call setPressTexture(load("assets/button_press.png", GL_RGBA))
-        call resize(256, 64)
-        call move(120, 220)
-        call setText("Texture button")
+        call:
+          setNormalTexture(load("assets/button_normal.png", GL_RGBA))
+          setHoverTexture(load("assets/button_hover.png", GL_RGBA))
+          setPressTexture(load("assets/button_press.png", GL_RGBA))
+          resize(256, 64)
+          move(120, 220)
+          setText("Texture button")
     getSceneByName("main").addChild(button)
 
 
   test "TextureProgressBar test":
     build:
       - TextureProgressBar progress:
-        call setProgressTexture(load("assets/texture_progress_1.png", GL_RGBA))
-        call setBackgroundTexture(load("assets/texture_progress_0.png", GL_RGBA))
-        call setProgress(50)
-        call resize(256, 85)
-        call move(100, 300)
+        call:
+          setProgressTexture(load("assets/texture_progress_1.png", GL_RGBA))
+          setBackgroundTexture(load("assets/texture_progress_0.png", GL_RGBA))
+          setProgress(50)
+          resize(256, 85)
+          move(100, 300)
     getSceneByName("main").addChild(progress)
 
 
@@ -301,19 +315,21 @@ suite "Work with Control nodes.":
   test "CheckBox test":
     build:
       - CheckBox check:
-        call setText("smth checkbox")
-        call enable()
-        call move(700, 300)
+        call:
+          setText("smth checkbox")
+          enable()
+          move(700, 300)
     getSceneByName("main").addChild(check)
 
 
   test "SubWindow test":
     build:
       - SubWindow window1:
-        call setIcon("assets/anim/0.jpg")
-        call setTitle("subwindow")
-        call move(500, 400)
-        call open()
+        call:
+          setIcon("assets/anim/0.jpg")
+          setTitle("subwindow")
+          move(500, 400)
+          open()
     getSceneByName("main").addChild(window1)
 
 
@@ -340,43 +356,43 @@ suite "Work with Control nodes.":
   test "Line & Bar chart test":
     build:
       - Chart my_chart:
-        call addChartData(
-          newChartData(
-            @["one", "two", "three", "four", "five", "six"],
-            @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent_dark, BAR_CHART))
-        call addChartData(
-          newChartData(
-            @["one", "two", "three", "four", "five", "six"],
-            @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent, LINE_CHART))
-
-        call move(100, 450)
-        call resize(320, 196)
+        call:
+          addChartData(
+            newChartData(
+              @["one", "two", "three", "four", "five", "six"],
+              @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent_dark, BAR_CHART))
+          addChartData(
+            newChartData(
+              @["one", "two", "three", "four", "five", "six"],
+              @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent, LINE_CHART))
+          move(100, 450)
+          resize(320, 196)
 
     getSceneByName("main").addChildren(my_chart)
 
   test "Pie chart test":
     build:
       - Chart circle_chart:
-        call addChartData(
-          newChartData(
-            @["one", "two", "three", "four", "five", "six"],
-            @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent_dark, PIE_CHART))
-
-        call move(900, 450)
-        call resize(128, 128)
+        call:
+          addChartData(
+            newChartData(
+              @["one", "two", "three", "four", "five", "six"],
+              @[1, 8, 18, 32, 4, 16], "myData", current_theme~accent_dark, PIE_CHART))
+          move(900, 450)
+          resize(128, 128)
 
     getSceneByName("main").addChildren(circle_chart)
 
   test "Radar chart test":
     build:
       - Chart spiderweb_chart:
-        call addChartData(
-          newChartData(
-            @["one", "two", "three", "four", "five"],
-            @[10, 24, 18, 32, 4], "myData", current_theme~accent_dark, RADAR_CHART))
-
-        call move(700, 450)
-        call resize(128, 128)
+        call:
+          addChartData(
+            newChartData(
+              @["one", "two", "three", "four", "five"],
+              @[10, 24, 18, 32, 4], "myData", current_theme~accent_dark, RADAR_CHART))
+          move(700, 450)
+          resize(128, 128)
 
     getSceneByName("main").addChildren(spiderweb_chart)
 

+ 51 - 47
tests/test6.nim

@@ -44,13 +44,14 @@ suite "Work with 2D nodes.":
       - AnimatedSprite animation:
         centered: false
         z_index: -10
-        call addFrame("default", load("assets/anim/0.jpg"))
-        call addFrame("default", load("assets/anim/1.jpg"))
-        call addFrame("default", load("assets/anim/2.jpg"))
-        call addFrame("default", load("assets/anim/3.jpg"))
-        call addFrame("default", load("assets/anim/4.jpg"))
-        call play(name = "", backward = false)
-        call setSpeed("default", 5)  # name, frames-per-second
+        call:
+          addFrame("default", load("assets/anim/0.jpg"))
+          addFrame("default", load("assets/anim/1.jpg"))
+          addFrame("default", load("assets/anim/2.jpg"))
+          addFrame("default", load("assets/anim/3.jpg"))
+          addFrame("default", load("assets/anim/4.jpg"))
+          play(name = "", backward = false)
+          setSpeed("default", 5)  # name, frames-per-second
     getSceneByName("main").addChild(animation)
 
 
@@ -110,10 +111,11 @@ suite "Work with 2D nodes.":
           filter: Color("#555")
           call loadTexture("assets/anim/2.jpg")
       - Camera2D camera:
-        call setTarget(player)
-        call setLimit(-2048, -1024, 2048, 1024)
-        call setCurrent()
-        call enableSmooth()
+        call:
+          setTarget(player)
+          setLimit(-2048, -1024, 2048, 1024)
+          setCurrent()
+          enableSmooth()
     player@onProcess(self):
       if isActionPressed("w"):
         player.move(0, -10)
@@ -131,16 +133,17 @@ suite "Work with 2D nodes.":
     build:
       - TileMap map:
         z_index: -100
-        call setTileSet(tileset)
-        call move(-2048, -1024)
-        #                         map size   layer count
-        call resizeMap(Vector2(512, 128), 1)
-        call fill(Vector2(1, 0))
-        call drawRect(3, 3, 10, 5, Vector2(9, 7))
-        call drawTile(0, 0, Vector2(3, 0))
-        call drawTile(1, 0, Vector2(7, 4.5))
-        call drawTile(0, 1, Vector2(6.5, 5))
-        call drawTile(1, 1, Vector2(7, 5))
+        call:
+          setTileSet(tileset)
+          move(-2048, -1024)
+          #                 map size   layer count
+          resizeMap(Vector2(512, 128), 1)
+          fill(Vector2(1, 0))
+          drawRect(3, 3, 10, 5, Vector2(9, 7))
+          drawTile(0, 0, Vector2(3, 0))
+          drawTile(1, 0, Vector2(7, 4.5))
+          drawTile(0, 1, Vector2(6.5, 5))
+          drawTile(1, 1, Vector2(7, 5))
     getSceneByName("main").addChild(map)
 
 
@@ -149,32 +152,33 @@ suite "Work with 2D nodes.":
     build:
       - TileMap map:
         z_index: -80
-        call setMode(TILEMAP_ISOMETRIC)
-        call setTileSet(tileset)
-        call move(-2048, -1024)
-        #                         map size   layer count
-        call resizeMap(Vector2(32, 32), layer_count=4)
-        call fill(Vector2(1, 0))
-        call drawRect(3, 3, 10, 5, Vector2(15, 1))
-
-        # platform
-        call drawTile(2, 4, Vector2(0, 27), 1)
-        call drawTile(1, 5, Vector2(0, 28), 1)
-
-        # cross
-        call drawTile(4, 6, Vector2(14, 13), 1)
-        call drawTile(3, 7, Vector2(14, 14), 1)
-
-        # sign
-        call drawTile(4, 5, Vector2(11, 12), 1)
-        call drawTile(4, 5, Vector2(11, 13), 2)
-        call drawTile(4, 5, Vector2(11, 14), 3)
-
-        # magic
-        call drawTile(5, 10, Vector2(2, 33), 1)
-        call drawTile(6, 11, Vector2(3, 33), 1)
-        call drawTile(4, 11, Vector2(2, 34), 1)
-        call drawTile(5, 12, Vector2(3, 34), 1)
+        call:
+          setMode(TILEMAP_ISOMETRIC)
+          setTileSet(tileset)
+          move(-2048, -1024)
+          #                         map size   layer count
+          resizeMap(Vector2(32, 32), layer_count=4)
+          fill(Vector2(1, 0))
+          drawRect(3, 3, 10, 5, Vector2(15, 1))
+
+          # platform
+          drawTile(2, 4, Vector2(0, 27), 1)
+          drawTile(1, 5, Vector2(0, 28), 1)
+
+          # cross
+          drawTile(4, 6, Vector2(14, 13), 1)
+          drawTile(3, 7, Vector2(14, 14), 1)
+
+          # sign
+          drawTile(4, 5, Vector2(11, 12), 1)
+          drawTile(4, 5, Vector2(11, 13), 2)
+          drawTile(4, 5, Vector2(11, 14), 3)
+
+          # magic
+          drawTile(5, 10, Vector2(2, 33), 1)
+          drawTile(6, 11, Vector2(3, 33), 1)
+          drawTile(4, 11, Vector2(2, 34), 1)
+          drawTile(5, 12, Vector2(3, 34), 1)
     getSceneByName("main").addChild(map)
 
 

+ 18 - 5
tests/test8.nim

@@ -1,21 +1,34 @@
 # --- Test 8. Make your own node. --- #
-import nodesnim
+import
+  nodesnim,
+  nodesnim/runtime/scene_loader,  # For runtime load your node from XML scene file.
+  strutils,
+  tables
 
 
 type
-  MyOwnNodeRef = ref MyOwnNodeObj
-  MyOwnNodeObj = object of NodeRef  # NodeRef/Node2DRef/ControlRef/Node3DRef
-    property: int
+  MyOwnNodeObj* = object of NodeObj  # NodeObj/Node2DObj/ControlObj/Node3DObj
+    property*: int
+  MyOwnNodeRef* = ref MyOwnNodeObj
 
 
-proc MyOwnNode(name: string = "MyOwnNode"): MyOwnNodeRef =
+proc MyOwnNode*(name: string = "MyOwnNode"): MyOwnNodeRef =
   nodepattern(MyOwnNodeRef)
   # controlpattern()/node2dpattern()/node3dpattern()
   result.property = 100
 
+# For XML scene files.
+mkparse(MyOwnNode)
+mkattrs attrs(node, value):
+  "property":
+    node.MyOwnNodeRef.property = value.parseInt()
+
 
 build:
   - MyOwnNode node:
     property: 10
 
 echo node.property
+
+var source = "<MyOwnNode name=\"node1\" property=\"7\"></MyOwnNode>"
+echo loadSceneFromString("TestScene", source)[0].MyOwnNodeRef.property