[nat] (saveComponent) and (withComponents)

This commit is contained in:
2021-06-12 21:52:32 -06:00
parent d8372d7359
commit 7a3f6c76b7
4 changed files with 42 additions and 5 deletions

View File

@@ -4,12 +4,42 @@
(defmacro hasComponent [e componentType] (defmacro hasComponent [e componentType]
`(.exists .components ,e ,(symbolName componentType))) `(.exists .components ,e ,(symbolName componentType)))
// TODO add to the documentation a hint that macros should use fully qualified paths so macro caller classes don't need to import everything (defmacro _componentPath [archive e componentType]
`(haxe.io.Path.join [.archiveDir (the nat.Archive ,archive) "components" (+ (dictGet (the Map<String,String> .components ,e) ,(symbolName componentType)) ".json")]))
(defmacro getComponent [archive e componentType] (defmacro getComponent [archive e componentType]
// TODO add to the documentation a hint that macros should use fully qualified type paths so macro caller classes don't need to import everything
`(the nat.components ,componentType `(the nat.components ,componentType
(tink.Json.parse (tink.Json.parse
(sys.io.File.getContent (sys.io.File.getContent (_componentPath ,archive ,e ,componentType)))))
(haxe.io.Path.join [.archiveDir (the nat.Archive ,archive) "components" (+ (dictGet (the Map<String,String> .components ,e) ,(symbolName componentType)) ".json")])))))
// Components have to be saved individually after writing because the Entity only knows their ids,
// not the data they contain. This is more ergonomically done by using (withComponents...)
(defmacro saveComponent [archive e componentType c]
`(sys.io.File.saveContent
(_componentPath ,archive ,e ,componentType)
(tink.Json.stringify
(the nat.components ,componentType ,c))))
// Retrieve multiple components from an Entity with mutable access.
// All components will be serialized after the block is done.
(defmacro withComponents [archive e bindings &rest body]
(let [bindingPairs
(groups (expList bindings) 2 Throw)
bindingList
[]
saveList
[]
retValSymbol
(symbol)]
(doFor [name type] bindingPairs
(bindingList.push `&mut ,name)
(bindingList.push `(getComponent ,archive ,e ,type))
(saveList.push `(saveComponent ,archive ,e ,type ,name)))
`(let [,@bindingList
,retValSymbol {,@body}]
,@saveList
,retValSymbol)))
(defun tagList [archive e] (defun tagList [archive e]
(let [t (let [t

View File

@@ -1,4 +1,3 @@
package nat.components; package nat.components;
typedef Name = String;
typedef Author = String; typedef Author = String;

View File

@@ -0,0 +1,3 @@
package nat.components;
typedef Name = String;

View File

@@ -25,4 +25,9 @@
(assert !(tagsMatch archive song1 "(and song religious)")) (assert !(tagsMatch archive song1 "(and song religious)"))
(assert (tagsMatch archive song2 "(and song religious)")) (assert (tagsMatch archive song2 "(and song religious)"))
(assert !(tagsMatch archive song2 "(and song western)")) (assert !(tagsMatch archive song2 "(and song western)"))
))
(withComponents archive song1
[author Author
name Name]
(assert (= author "Rafael Krux"))
(assert (= name "Adventure")))))