1 module unecht.core.serialization.sceneSerialization; 2 3 import 4 unecht.core.components.sceneNode, 5 unecht.core.serialization.serializer; 6 7 import sdlang; 8 9 import std.uuid; 10 11 /// 12 struct UESceneSerializer 13 { 14 private UESerializer baseSerializer; 15 16 /// 17 alias baseSerializer this; 18 19 private Tag sceneNodesTag; 20 21 /// 22 public void serialize(UESceneNode root, UUID[] externals=null) 23 { 24 if(!sceneNodesTag) 25 { 26 sceneNodesTag = new Tag(); 27 sceneNodesTag.name = "nodes"; 28 } 29 30 if(externals) 31 baseSerializer.externals = externals; 32 33 baseSerializer.blacklist ~= root.instanceId; 34 35 foreach(rootChild; root.children) 36 { 37 serializeNode(rootChild); 38 } 39 } 40 41 private void serializeNode(UESceneNode node) 42 { 43 import unecht.core.hideFlags; 44 if(!node.hideFlags.isSet(HideFlags.hideInHirarchie)) 45 { 46 node.serialize(baseSerializer); 47 48 auto nodeTag = new Tag(sceneNodesTag); 49 nodeTag.add(Value(node.instanceId.toString())); 50 } 51 } 52 53 /// 54 public string toString() 55 { 56 auto root = new Tag; 57 58 root.add(sceneNodesTag); 59 root.add(baseSerializer.content); 60 61 return root.toSDLDocument(); 62 } 63 } 64 65 /// 66 struct UESceneDeserializer 67 { 68 UEDeserializer base; 69 70 /// 71 alias base this; 72 73 private Tag sceneNodesTag; 74 75 /// 76 this(string input) 77 { 78 base = UEDeserializer(input); 79 80 sceneNodesTag = root.all.tags["nodes"][0]; 81 assert(sceneNodesTag !is null); 82 } 83 84 /// 85 public void deserialize(UESceneNode root) 86 { 87 assert(root); 88 89 import unecht.core.logger; 90 91 foreach(Tag node; sceneNodesTag.all.tags) 92 { 93 auto id = node.values[0].get!string; 94 95 auto scenenode = cast(UESceneNode)base.findLoadedRef(id); 96 97 if(scenenode is null) 98 { 99 scenenode = new UESceneNode; 100 base.storeLoadedRef(scenenode,id); 101 scenenode.deserialize(this,id); 102 assert(scenenode.parent is null); 103 scenenode.parent = root; 104 105 /+log.logf("new node added: '%s' (%s,%s)", 106 scenenode.entity.name, 107 scenenode.parent.children.length, 108 scenenode.children.length); 109 log.logf("->: %s parent: %s", scenenode.instanceId, scenenode.parent.instanceId);+/ 110 } 111 else 112 { 113 //log.logf("node already created: '%s' (%s)", scenenode.entity.name, scenenode.instanceId); 114 115 assert(scenenode.parent is root || scenenode.parent is null); 116 if(scenenode.parent is null) 117 scenenode.parent = root; 118 } 119 } 120 121 void recursiveCreate(UESceneNode _node) 122 { 123 foreach(child; _node.children) 124 { 125 recursiveCreate(child); 126 } 127 128 foreach(comp; _node.entity.components) 129 { 130 comp.onCreate(); 131 } 132 } 133 134 foreach(Tag node; sceneNodesTag.all.tags) 135 { 136 auto id = node.values[0].get!string; 137 138 auto scenenode = cast(UESceneNode)base.findLoadedRef(id); 139 140 assert(scenenode); 141 142 recursiveCreate(scenenode); 143 } 144 145 foreach(i,lo; base.objectsLoaded) 146 { 147 import unecht.core.object; 148 import unecht.core.entity; 149 UEObject o = lo.o; 150 assert(o); 151 152 //import std.stdio; 153 //writefln("loaded [%s]: %s", i, o.instanceId); 154 155 if(cast(UESceneNode)o) 156 { 157 UESceneNode n = cast(UESceneNode)o; 158 assert(n.entity); 159 //writefln(" sceneNode -> %s ('%s')", n.children.length, n.entity.name); 160 //if(n.parent) 161 // writefln(" parent -> %s", n.parent.instanceId); 162 } 163 if(cast(UEEntity)o) 164 { 165 UEEntity e = cast(UEEntity)o; 166 assert(e.sceneNode); 167 //writefln(" entity '%s': %s", e.name, e.sceneNode.instanceId); 168 } 169 } 170 171 void val(UESceneNode n,UESceneNode root) 172 { 173 import std.format:format; 174 175 assert(n); 176 177 if(n !is root) 178 { 179 assert(n.parent, format("no parent: %s",n.instanceId)); 180 assert(n.parent.hasChild(n)); 181 } 182 183 foreach(sn; n.children) 184 { 185 assert(sn.parent is n, format("'%s'.%s !is '%s'.%s", sn.entity.name, sn.parent.instanceId, n.entity.name,n.instanceId)); 186 val(sn,root); 187 } 188 } 189 190 // validity check 191 val(root,root); 192 } 193 }