no more templates in the archive tool

This commit is contained in:
2021-06-26 21:41:03 -06:00
parent f64faf61fd
commit 8d98ca136c
4 changed files with 43 additions and 25 deletions

View File

@@ -2,15 +2,13 @@
[:Array<System> systems [:Array<System> systems
[] []
:Map<String,Template> templates
(new Map)
:Map<String,Entry> entries :Map<String,Entry> entries
(let [entryDir (Path.join [archiveDir "entries"]) (let [entryDir (Path.join [archiveDir "entries"])
componentDir (Path.join [archiveDir "components"])] componentDir (Path.join [archiveDir "components"])]
(FileSystem.createDirectory entryDir) (FileSystem.createDirectory entryDir)
(FileSystem.createDirectory componentDir) (FileSystem.createDirectory componentDir)
(let [entryFiles (FileSystem.readDirectory entryDir)] (let [entryFiles (FileSystem.readDirectory entryDir)]
(for file entryFiles =>(file.withoutExtension) ~(the Entry (Json.parse (File.getContent (Path.join [archiveDir "entries" file])))))))]) (for file entryFiles =>(file.withoutExtension) (the Entry (Json.parse (File.getContent (Path.join [archiveDir "entries" file])))))))])
(defmethod addSystem [:System system] (defmethod addSystem [:System system]
// Assign entries to the Systems that care about them // Assign entries to the Systems that care about them
@@ -18,18 +16,20 @@
(system.checkEntryInOrOut this entry)) (system.checkEntryInOrOut this entry))
(systems.push system)) (systems.push system))
(defmethod addTemplate [name template] (defmethod :Entry createEntry [:Entry->Dynamic initializer] // initializer returns Dynamic so ->:Void isn't required
(dictSet templates name template))
(defmethod :Entry createEntry [template]
(let [e (_newEntry)] (let [e (_newEntry)]
(.prepareEntry (dictGet templates template) e) (initializer e)
(saveEntry e) (refreshEntry e)
(doFor system systems
(system.checkEntryInOrOut this e))
e)) e))
(defmethod saveEntry [:Entry e] // After modifying an entry, this must be called. If you are writing in a createEntry initializer or a system's processEntry function, this will happen automatically.
// Otherwise, you can guarantee it happens automatically by using the (withWritableEntry) macro in Lib.kiss
(defmethod refreshEntry [:Entry e]
(_saveEntry e)
(doFor system systems
(system.checkEntryInOrOut this e)))
(defmethod _saveEntry [:Entry e]
(File.saveContent (File.saveContent
(Path.join [archiveDir "entries" (e.id.withExtension "json")]) (Path.join [archiveDir "entries" (e.id.withExtension "json")])
(Json.stringify e))) (Json.stringify e)))

View File

@@ -7,23 +7,31 @@
(defmacro _componentPath [archive e componentType] (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")])) `(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] // Changes to the object returned by (readComponent) will not be saved! Use (withWritableComponents) for making changes
(defmacro readComponent [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 // 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 (_componentPath ,archive ,e ,componentType))))) (sys.io.File.getContent (_componentPath ,archive ,e ,componentType)))))
// Components have to be saved individually after writing because the Entity only knows their ids, // 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...) // not the data they contain. This is more ergonomically done by using (withWritableComponents...)
(defmacro saveComponent [archive e componentType c] (defmacro writeComponent [archive e componentType c]
`(sys.io.File.saveContent `(sys.io.File.saveContent
(_componentPath ,archive ,e ,componentType) (_componentPath ,archive ,e ,componentType)
(tink.Json.stringify (tink.Json.stringify
(the nat.components ,componentType ,c)))) (the nat.components ,componentType ,c))))
// TODO check not overwriting a component
(defmacro addComponent [archive e componentType c]
`(let [componentId (Uuid.v4)]
(dictSet .components ,e ,(symbolName componentType) componentId)
(writeComponent ,archive ,e ,componentType ,c)
,e))
// Retrieve multiple components from an Entity with mutable access. // Retrieve multiple components from an Entity with mutable access.
// All components will be serialized after the block is done. // All components will be serialized after the block is done.
(defmacro withComponents [archive e bindings &rest body] (defmacro withWritableComponents [archive e bindings &rest body]
(let [bindingPairs (let [bindingPairs
(groups (expList bindings) 2 Throw) (groups (expList bindings) 2 Throw)
bindingList bindingList
@@ -34,16 +42,31 @@
(symbol)] (symbol)]
(doFor [name type] bindingPairs (doFor [name type] bindingPairs
(bindingList.push `&mut ,name) (bindingList.push `&mut ,name)
(bindingList.push `(getComponent ,archive ,e ,type)) (bindingList.push `(readComponent ,archive ,e ,type))
(saveList.push `(saveComponent ,archive ,e ,type ,name))) (saveList.push `(writeComponent ,archive ,e ,type ,name)))
`(let [,@bindingList `(let [,@bindingList
,retValSymbol {,@body}] ,retValSymbol {,@body}]
,@saveList ,@saveList
,retValSymbol))) ,retValSymbol)))
(defmacro withWritableEntry [archive e &rest body]
(let [retValSymbol
(symbol)]
`(let [,retValSymbol {,@body}]
(archive.refreshEntry ,e)
,retValSymbol)))
// Create a system that selects Entries according to a single string component (i.e. Name or Author) matching the given value
(defmacro stringComponentSystem [archive componentType value process]
`(new System
(lambda [archive :Entry e]
?(and (hasComponent e ,componentType)
(= ,value (readComponent ,archive e ,componentType))))
,process))
(defun tagList [archive e] (defun tagList [archive e]
(let [t (let [t
(getComponent archive e Tags)] (readComponent archive e Tags)]
(collect (t.keys)))) (collect (t.keys))))
(defun tagsMatch [archive e tagsBoolExp] (defun tagsMatch [archive e tagsBoolExp]

View File

@@ -1,5 +0,0 @@
package nat;
interface Template {
function prepareEntry(e:Entry):Void;
}

View File

@@ -26,7 +26,7 @@
(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 (withWritableComponents archive song1
[author Author [author Author
name Name] name Name]
(assert (= author "Rafael Krux")) (assert (= author "Rafael Krux"))