From a1d845c264ccac828fb3d5c6f3f5b24e8b550d77 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sat, 12 Jun 2021 21:52:32 -0600 Subject: [PATCH] [nat] (saveComponent) and (withComponents) --- src/nat/Lib.kiss | 36 +++++++++++++++++-- .../{StringComponents.hx => Author.hx} | 1 - src/nat/components/Name.hx | 3 ++ src/test/TestMain.kiss | 7 +++- 4 files changed, 42 insertions(+), 5 deletions(-) rename src/nat/components/{StringComponents.hx => Author.hx} (68%) create mode 100644 src/nat/components/Name.hx diff --git a/src/nat/Lib.kiss b/src/nat/Lib.kiss index ee6cb1a..6bfed81 100644 --- a/src/nat/Lib.kiss +++ b/src/nat/Lib.kiss @@ -4,12 +4,42 @@ (defmacro hasComponent [e 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 .components ,e) ,(symbolName componentType)) ".json")])) + (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 (tink.Json.parse - (sys.io.File.getContent - (haxe.io.Path.join [.archiveDir (the nat.Archive ,archive) "components" (+ (dictGet (the Map .components ,e) ,(symbolName componentType)) ".json")]))))) + (sys.io.File.getContent (_componentPath ,archive ,e ,componentType))))) + +// 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] (let [t diff --git a/src/nat/components/StringComponents.hx b/src/nat/components/Author.hx similarity index 68% rename from src/nat/components/StringComponents.hx rename to src/nat/components/Author.hx index 838abe4..cbffd0f 100644 --- a/src/nat/components/StringComponents.hx +++ b/src/nat/components/Author.hx @@ -1,4 +1,3 @@ package nat.components; -typedef Name = String; typedef Author = String; diff --git a/src/nat/components/Name.hx b/src/nat/components/Name.hx new file mode 100644 index 0000000..6525d08 --- /dev/null +++ b/src/nat/components/Name.hx @@ -0,0 +1,3 @@ +package nat.components; + +typedef Name = String; diff --git a/src/test/TestMain.kiss b/src/test/TestMain.kiss index 93ae866..fa8c0d1 100644 --- a/src/test/TestMain.kiss +++ b/src/test/TestMain.kiss @@ -25,4 +25,9 @@ (assert !(tagsMatch archive song1 "(and song religious)")) (assert (tagsMatch archive song2 "(and song religious)")) (assert !(tagsMatch archive song2 "(and song western)")) - )) \ No newline at end of file + + (withComponents archive song1 + [author Author + name Name] + (assert (= author "Rafael Krux")) + (assert (= name "Adventure"))))) \ No newline at end of file