1 /*************************************************************************/
2 /* packed_scene.cpp */
3 /*************************************************************************/
4 /* This file is part of: */
5 /* GODOT ENGINE */
6 /* https://godotengine.org */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
10 /* */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the */
13 /* "Software"), to deal in the Software without restriction, including */
14 /* without limitation the rights to use, copy, modify, merge, publish, */
15 /* distribute, sublicense, and/or sell copies of the Software, and to */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions: */
18 /* */
19 /* The above copyright notice and this permission notice shall be */
20 /* included in all copies or substantial portions of the Software. */
21 /* */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29 /*************************************************************************/
30 #include "packed_scene.h"
31 #include "core/core_string_names.h"
32 #include "globals.h"
33 #include "io/resource_loader.h"
34 #include "scene/2d/node_2d.h"
35 #include "scene/3d/spatial.h"
36 #include "scene/gui/control.h"
37 #include "scene/main/instance_placeholder.h"
38 #define PACK_VERSION 2
39
can_instance() const40 bool SceneState::can_instance() const {
41
42 return nodes.size() > 0;
43 }
44
instance(bool p_gen_edit_state) const45 Node *SceneState::instance(bool p_gen_edit_state) const {
46
47 // nodes where instancing failed (because something is missing)
48 List<Node *> stray_instances;
49
50 #define NODE_FROM_ID(p_name, p_id) \
51 Node *p_name; \
52 if (p_id & FLAG_ID_IS_PATH) { \
53 NodePath np = node_paths[p_id & FLAG_MASK]; \
54 p_name = ret_nodes[0]->_get_node(np); \
55 } else { \
56 ERR_FAIL_INDEX_V(p_id &FLAG_MASK, nc, NULL); \
57 p_name = ret_nodes[p_id & FLAG_MASK]; \
58 }
59
60 int nc = nodes.size();
61 ERR_FAIL_COND_V(nc == 0, NULL);
62
63 const StringName *snames = NULL;
64 int sname_count = names.size();
65 if (sname_count)
66 snames = &names[0];
67
68 const Variant *props = NULL;
69 int prop_count = variants.size();
70 if (prop_count)
71 props = &variants[0];
72
73 //Vector<Variant> properties;
74
75 const NodeData *nd = &nodes[0];
76
77 Node **ret_nodes = (Node **)alloca(sizeof(Node *) * nc);
78
79 bool gen_node_path_cache = p_gen_edit_state && node_path_cache.empty();
80
81 for (int i = 0; i < nc; i++) {
82
83 const NodeData &n = nd[i];
84
85 Node *parent = NULL;
86
87 if (i > 0) {
88
89 NODE_FROM_ID(nparent, n.parent);
90 #ifdef DEBUG_ENABLED
91 if (!nparent && n.parent & FLAG_ID_IS_PATH) {
92
93 WARN_PRINT(String("Parent path '" + String(node_paths[n.parent & FLAG_MASK]) + "' for node '" + String(snames[n.name]) + "' has vanished when instancing: '" + get_path() + "'.").ascii().get_data());
94 }
95 #endif
96 parent = nparent;
97 }
98
99 Node *node = NULL;
100
101 if (i == 0 && base_scene_idx >= 0) {
102 //scene inheritance on root node
103 //print_line("scene inherit");
104 Ref<PackedScene> sdata = props[base_scene_idx];
105 ERR_FAIL_COND_V(!sdata.is_valid(), NULL);
106 node = sdata->instance(p_gen_edit_state);
107 ERR_FAIL_COND_V(!node, NULL);
108 if (p_gen_edit_state) {
109 node->set_scene_inherited_state(sdata->get_state());
110 }
111
112 } else if (n.instance >= 0) {
113 //instance a scene into this node
114 //print_line("instance");
115 if (n.instance & FLAG_INSTANCE_IS_PLACEHOLDER) {
116
117 String path = props[n.instance & FLAG_MASK];
118 if (disable_placeholders) {
119
120 Ref<PackedScene> sdata = ResourceLoader::load(path, "PackedScene");
121 ERR_FAIL_COND_V(!sdata.is_valid(), NULL);
122 node = sdata->instance(p_gen_edit_state);
123 ERR_FAIL_COND_V(!node, NULL);
124 } else {
125 InstancePlaceholder *ip = memnew(InstancePlaceholder);
126 ip->set_instance_path(path);
127 node = ip;
128 }
129 node->set_scene_instance_load_placeholder(true);
130 } else {
131 Ref<PackedScene> sdata = props[n.instance & FLAG_MASK];
132 ERR_FAIL_COND_V(!sdata.is_valid(), NULL);
133 node = sdata->instance(p_gen_edit_state);
134 ERR_FAIL_COND_V(!node, NULL);
135 }
136
137 } else if (n.type == TYPE_INSTANCED) {
138 //print_line("instanced");
139 //get the node from somewhere, it likely already exists from another instance
140 if (parent) {
141 node = parent->_get_child_by_name(snames[n.name]);
142 #ifdef DEBUG_ENABLED
143 if (!node) {
144 WARN_PRINT(String("Node '" + String(ret_nodes[0]->get_path_to(parent)) + "/" + String(snames[n.name]) + "' was modified from inside a instance, but it has vanished.").ascii().get_data());
145 }
146 #endif
147 }
148 } else if (ObjectTypeDB::is_type_enabled(snames[n.type])) {
149 //print_line("created");
150 //node belongs to this scene and must be created
151 Object *obj = ObjectTypeDB::instance(snames[n.type]);
152 if (!obj || !obj->cast_to<Node>()) {
153 if (obj) {
154 memdelete(obj);
155 obj = NULL;
156 }
157 WARN_PRINT(String("Warning node of type " + snames[n.type].operator String() + " does not exist.").ascii().get_data());
158 if (n.parent >= 0 && n.parent < nc && ret_nodes[n.parent]) {
159 if (ret_nodes[n.parent]->cast_to<Spatial>()) {
160 obj = memnew(Spatial);
161 } else if (ret_nodes[n.parent]->cast_to<Control>()) {
162 obj = memnew(Control);
163 } else if (ret_nodes[n.parent]->cast_to<Node2D>()) {
164 obj = memnew(Node2D);
165 }
166 }
167 if (!obj) {
168 obj = memnew(Node);
169 }
170 }
171
172 node = obj->cast_to<Node>();
173 }
174
175 if (node) {
176 // may not have found the node (part of instanced scene and removed)
177 // if found all is good, otherwise ignore
178
179 //properties
180 int nprop_count = n.properties.size();
181 if (nprop_count) {
182
183 const NodeData::Property *nprops = &n.properties[0];
184
185 for (int j = 0; j < nprop_count; j++) {
186
187 bool valid;
188 ERR_FAIL_INDEX_V(nprops[j].name, sname_count, NULL);
189 ERR_FAIL_INDEX_V(nprops[j].value, prop_count, NULL);
190
191 if (snames[nprops[j].name] == CoreStringNames::get_singleton()->_script) {
192 //work around to avoid old script variables from disappearing, should be the proper fix to:
193 //https://github.com/godotengine/godot/issues/2958
194
195 //store old state
196 List<Pair<StringName, Variant> > old_state;
197 if (node->get_script_instance()) {
198 node->get_script_instance()->get_property_state(old_state);
199 }
200
201 node->set(snames[nprops[j].name], props[nprops[j].value], &valid);
202
203 //restore old state for new script, if exists
204 for (List<Pair<StringName, Variant> >::Element *E = old_state.front(); E; E = E->next()) {
205 node->set(E->get().first, E->get().second);
206 }
207 } else {
208
209 node->set(snames[nprops[j].name], props[nprops[j].value], &valid);
210 }
211 }
212 }
213
214 //name
215
216 //groups
217 for (int j = 0; j < n.groups.size(); j++) {
218
219 ERR_FAIL_INDEX_V(n.groups[j], sname_count, NULL);
220 node->add_to_group(snames[n.groups[j]], true);
221 }
222
223 if (n.instance >= 0 || n.type != TYPE_INSTANCED || i == 0) {
224 //if node was not part of instance, must set it's name, parenthood and ownership
225 if (i > 0) {
226 if (parent) {
227 parent->_add_child_nocheck(node, snames[n.name]);
228 } else {
229 //it may be possible that an instanced scene has changed
230 //and the node has nowhere to go anymore
231 stray_instances.push_back(node); //can't be added, go to stray list
232 }
233 } else {
234 node->_set_name_nocheck(snames[n.name]);
235 }
236 }
237
238 if (n.owner >= 0) {
239
240 NODE_FROM_ID(owner, n.owner);
241 if (owner)
242 node->_set_owner_nocheck(owner);
243 }
244 }
245
246 ret_nodes[i] = node;
247
248 if (node && gen_node_path_cache && ret_nodes[0]) {
249 NodePath n = ret_nodes[0]->get_path_to(node);
250 node_path_cache[n] = i;
251 }
252 }
253
254 //do connections
255
256 int cc = connections.size();
257 const ConnectionData *cdata = connections.ptr();
258
259 for (int i = 0; i < cc; i++) {
260
261 const ConnectionData &c = cdata[i];
262 //ERR_FAIL_INDEX_V( c.from, nc, NULL );
263 //ERR_FAIL_INDEX_V( c.to, nc, NULL );
264
265 NODE_FROM_ID(cfrom, c.from);
266 NODE_FROM_ID(cto, c.to);
267
268 if (!cfrom || !cto)
269 continue;
270
271 Vector<Variant> binds;
272 if (c.binds.size()) {
273 binds.resize(c.binds.size());
274 for (int j = 0; j < c.binds.size(); j++)
275 binds[j] = props[c.binds[j]];
276 }
277
278 cfrom->connect(snames[c.signal], cto, snames[c.method], binds, CONNECT_PERSIST | c.flags);
279 }
280
281 //Node *s = ret_nodes[0];
282
283 //remove nodes that could not be added, likely as a result that
284 while (stray_instances.size()) {
285 memdelete(stray_instances.front()->get());
286 stray_instances.pop_front();
287 }
288
289 for (int i = 0; i < editable_instances.size(); i++) {
290 Node *ei = ret_nodes[0]->_get_node(editable_instances[i]);
291 if (ei) {
292 ret_nodes[0]->set_editable_instance(ei, true);
293 }
294 }
295
296 return ret_nodes[0];
297 }
298
_nm_get_string(const String & p_string,Map<StringName,int> & name_map)299 static int _nm_get_string(const String &p_string, Map<StringName, int> &name_map) {
300
301 if (name_map.has(p_string))
302 return name_map[p_string];
303
304 int idx = name_map.size();
305 name_map[p_string] = idx;
306 return idx;
307 }
308
_vm_get_variant(const Variant & p_variant,HashMap<Variant,int,VariantHasher,VariantComparator> & variant_map)309 static int _vm_get_variant(const Variant &p_variant, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map) {
310
311 if (variant_map.has(p_variant))
312 return variant_map[p_variant];
313
314 int idx = variant_map.size();
315 variant_map[p_variant] = idx;
316 return idx;
317 }
318
_parse_node(Node * p_owner,Node * p_node,int p_parent_idx,Map<StringName,int> & name_map,HashMap<Variant,int,VariantHasher,VariantComparator> & variant_map,Map<Node *,int> & node_map,Map<Node *,int> & nodepath_map)319 Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, Map<Node *, int> &node_map, Map<Node *, int> &nodepath_map) {
320
321 // this function handles all the work related to properly packing scenes, be it
322 // instanced or inherited.
323 // given the complexity of this process, an attempt will be made to properly
324 // document it. if you fail to understand something, please ask!
325
326 //discard nodes that do not belong to be processed
327 if (p_node != p_owner && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner()))
328 return OK;
329
330 // save the child instanced scenes that are chosen as editable, so they can be restored
331 // upon load back
332 if (p_node != p_owner && p_node->get_filename() != String() && p_owner->is_editable_instance(p_node))
333 editable_instances.push_back(p_owner->get_path_to(p_node));
334
335 NodeData nd;
336
337 nd.name = _nm_get_string(p_node->get_name(), name_map);
338 nd.instance = -1; //not instanced by default
339
340 // if this node is part of an instanced scene or sub-instanced scene
341 // we need to get the corresponding instance states.
342 // with the instance states, we can query for identical properties/groups
343 // and only save what has changed
344
345 List<PackState> pack_state_stack;
346
347 bool instanced_by_owner = true;
348
349 {
350 Node *n = p_node;
351
352 while (n) {
353
354 if (n == p_owner) {
355
356 Ref<SceneState> state = n->get_scene_inherited_state();
357 if (state.is_valid()) {
358 int node = state->find_node_by_path(n->get_path_to(p_node));
359 if (node >= 0) {
360 //this one has state for this node, save
361 PackState ps;
362 ps.node = node;
363 ps.state = state;
364 pack_state_stack.push_back(ps);
365 instanced_by_owner = false;
366 }
367 }
368
369 if (p_node->get_filename() != String() && p_node->get_owner() == p_owner && instanced_by_owner) {
370
371 if (p_node->get_scene_instance_load_placeholder()) {
372 //it's a placeholder, use the placeholder path
373 nd.instance = _vm_get_variant(p_node->get_filename(), variant_map);
374 nd.instance |= FLAG_INSTANCE_IS_PLACEHOLDER;
375 } else {
376 //must instance ourselves
377 Ref<PackedScene> instance = ResourceLoader::load(p_node->get_filename());
378 if (!instance.is_valid()) {
379 return ERR_CANT_OPEN;
380 }
381
382 nd.instance = _vm_get_variant(instance, variant_map);
383 }
384 }
385 n = NULL;
386 } else {
387 if (n->get_filename() != String()) {
388 //is an instance
389 Ref<SceneState> state = n->get_scene_instance_state();
390 if (state.is_valid()) {
391 int node = state->find_node_by_path(n->get_path_to(p_node));
392 if (node >= 0) {
393 //this one has state for this node, save
394 PackState ps;
395 ps.node = node;
396 ps.state = state;
397 pack_state_stack.push_back(ps);
398 }
399 }
400 }
401 n = n->get_owner();
402 }
403 }
404 }
405
406 #if 0
407
408 Ref<SceneState> base_scene = p_node->get_scene_inherited_state(); //for inheritance
409 Ref<SceneState> instance_state;
410 int instance_state_node=-1;
411
412 if (base_scene.is_valid() && (p_node==p_owner || p_node->get_owner()==p_owner)) {
413 //scene inheritance in use, see if this node is actually inherited
414 NodePath path = p_owner->get_path_to(p_node);
415 instance_state_node = base_scene->find_node_by_path(path);
416 if (instance_state_node>=0) {
417 instance_state=base_scene;
418 }
419 }
420
421 // check that this is a directly instanced scene from the scene being packed, if so
422 // this information must be saved. Of course, if using scene instancing and this node
423 // does belong to base scene, ignore.
424
425 if (instance_state.is_null() && p_node!=p_owner && p_node->get_owner()==p_owner && p_node->get_filename()!="") {
426
427 //instanced, only direct sub-scnes are supported of course
428 Ref<PackedScene> instance = ResourceLoader::load(p_node->get_filename());
429 if (!instance.is_valid()) {
430 return ERR_CANT_OPEN;
431 }
432
433 nd.instance=_vm_get_variant(instance,variant_map);
434
435 } else {
436
437 nd.instance=-1;
438 }
439
440 // finally, if this does not belong to scene inheritance, check
441 // if it belongs to scene instancing
442
443 if (instance_state.is_null() && p_node!=p_owner) {
444 //if not affected by scene inheritance, this may be
445 if (p_node->get_owner()==p_owner && p_node->get_filename()!=String()) {
446 instance_state=p_node->get_scene_instance_state();
447 if (instance_state.is_valid()) {
448 instance_state_node=instance_state->find_node_by_path(p_node->get_path_to(p_node));
449 }
450
451 } else if (p_node->get_owner()!=p_owner && p_owner->is_editable_instance(p_node->get_owner())) {
452 instance_state=p_node->get_owner()->get_scene_instance_state();
453 if (instance_state.is_valid()) {
454 instance_state_node=instance_state->find_node_by_path(p_node->get_owner()->get_path_to(p_node));
455 }
456 }
457 }
458 #endif
459
460 // all setup, we then proceed to check all properties for the node
461 // and save the ones that are worth saving
462
463 List<PropertyInfo> plist;
464 p_node->get_property_list(&plist);
465
466 for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
467
468 if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
469 continue;
470 }
471
472 String name = E->get().name;
473 Variant value = p_node->get(E->get().name);
474
475 bool isdefault = ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && value.is_zero()) || ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && value.is_one());
476
477 if (E->get().usage & PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE) {
478 isdefault = true; //is script default value
479 }
480 // if (nd.instance<0 && ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && value.is_zero()) || ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && value.is_one())) {
481 // continue;
482 // }
483
484 //print_line("PASSED!");
485 //print_line("at: "+String(p_node->get_name())+"::"+name+": - nz: "+itos(E->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO)+" no: "+itos(E->get().usage&PROPERTY_USAGE_STORE_IF_NONONE));
486 //print_line("value: "+String(value)+" is zero: "+itos(value.is_zero())+" is one" +itos(value.is_one()));
487
488 if (pack_state_stack.size()) {
489 // we are on part of an instanced subscene
490 // or part of instanced scene.
491 // only save what has been changed
492 // only save changed properties in instance
493
494 if (E->get().usage & PROPERTY_USAGE_NO_INSTANCE_STATE || E->get().name == "__meta__") {
495 //property has requested that no instance state is saved, sorry
496 //also, meta won't be overriden or saved
497 continue;
498 }
499
500 bool exists = false;
501 Variant original;
502
503 for (List<PackState>::Element *F = pack_state_stack.back(); F; F = F->prev()) {
504 //check all levels of pack to see if the property exists somewhere
505 const PackState &ps = F->get();
506
507 original = ps.state->get_property_value(ps.node, E->get().name, exists);
508 if (exists) {
509 break;
510 }
511 }
512
513 if (exists) {
514
515 //check if already exists and did not change
516 if (value.get_type() == Variant::REAL && original.get_type() == Variant::REAL) {
517 //this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
518 float a = value;
519 float b = original;
520
521 if (Math::abs(a - b) < CMP_EPSILON)
522 continue;
523 } else if (bool(Variant::evaluate(Variant::OP_EQUAL, value, original))) {
524
525 continue;
526 }
527 }
528
529 if (!exists && isdefault) {
530 //does not exist in original node, but it's the default value
531 //so safe to skip too.
532 continue;
533 }
534
535 } else {
536
537 if (isdefault) {
538 //it's the default value, no point in saving it
539 continue;
540 }
541 }
542
543 NodeData::Property prop;
544 prop.name = _nm_get_string(name, name_map);
545 prop.value = _vm_get_variant(value, variant_map);
546 nd.properties.push_back(prop);
547 }
548
549 // save the groups this node is into
550 // discard groups that come from the original scene
551
552 List<Node::GroupInfo> groups;
553 p_node->get_groups(&groups);
554 for (List<Node::GroupInfo>::Element *E = groups.front(); E; E = E->next()) {
555 Node::GroupInfo &gi = E->get();
556
557 if (!gi.persistent)
558 continue;
559 // if (instance_state_node>=0 && instance_state->is_node_in_group(instance_state_node,gi.name))
560 // continue; //group was instanced, don't add here
561
562 bool skip = false;
563 for (List<PackState>::Element *F = pack_state_stack.front(); F; F = F->next()) {
564 //check all levels of pack to see if the group was added somewhere
565 const PackState &ps = F->get();
566 if (ps.state->is_node_in_group(ps.node, gi.name)) {
567 skip = true;
568 break;
569 }
570 }
571
572 if (skip)
573 continue;
574
575 nd.groups.push_back(_nm_get_string(gi.name, name_map));
576 }
577
578 // save the right owner
579 // for the saved scene root this is -1
580 // for nodes of the saved scene this is 0
581 // for nodes of instanced scenes this is >0
582
583 if (p_node == p_owner) {
584 //saved scene root
585 nd.owner = -1;
586 } else if (p_node->get_owner() == p_owner) {
587 //part of saved scene
588 nd.owner = 0;
589 } else {
590
591 nd.owner = -1;
592 #if 0
593 // this is pointless, if this was instanced by something else,
594 // the owner will already be set.
595
596 if (node_map.has(p_node->get_owner())) {
597 //maybe an existing saved node
598 nd.owner=node_map[p_node->get_owner()];
599 } else {
600 //not saved, use nodepath map
601 int sidx;
602 if (nodepath_map.has(p_node->get_owner())) {
603 sidx=nodepath_map[p_node->get_owner()];
604 } else {
605 sidx=nodepath_map.size();
606 nodepath_map[p_node->get_owner()]=sidx;
607 }
608
609 nd.owner=FLAG_ID_IS_PATH|sidx;
610
611 }
612 #endif
613 }
614
615 // Save the right type. If this node was created by an instance
616 // then flag that the node should not be created but reused
617 if (pack_state_stack.empty()) {
618 //this node is not part of an instancing process, so save the type
619 nd.type = _nm_get_string(p_node->get_type(), name_map);
620 } else {
621 // this node is part of an instanced process, so do not save the type.
622 // instead, save that it was instanced
623 nd.type = TYPE_INSTANCED;
624 }
625
626 // determine whether to save this node or not
627 // if this node is part of an instanced sub-scene, we can skip storing it if basically
628 // no properties changed and no groups were added to it.
629 // below condition is true for all nodes of the scene being saved, and ones in subscenes
630 // that hold changes
631
632 bool save_node = nd.properties.size() || nd.groups.size(); // some local properties or groups exist
633 save_node = save_node || p_node == p_owner; // owner is always saved
634 save_node = save_node || (p_node->get_owner() == p_owner && instanced_by_owner); //part of scene and not instanced
635
636 int idx = nodes.size();
637 int parent_node = NO_PARENT_SAVED;
638
639 if (save_node) {
640
641 //don't save the node if nothing and subscene
642
643 node_map[p_node] = idx;
644
645 //ok validate parent node
646 if (p_parent_idx == NO_PARENT_SAVED) {
647
648 int sidx;
649 if (nodepath_map.has(p_node->get_parent())) {
650 sidx = nodepath_map[p_node->get_parent()];
651 } else {
652 sidx = nodepath_map.size();
653 nodepath_map[p_node->get_parent()] = sidx;
654 }
655
656 nd.parent = FLAG_ID_IS_PATH | sidx;
657 } else {
658 nd.parent = p_parent_idx;
659 }
660
661 parent_node = idx;
662 nodes.push_back(nd);
663 }
664
665 for (int i = 0; i < p_node->get_child_count(); i++) {
666
667 Node *c = p_node->get_child(i);
668 Error err = _parse_node(p_owner, c, parent_node, name_map, variant_map, node_map, nodepath_map);
669 if (err)
670 return err;
671 }
672
673 return OK;
674 }
675
_parse_connections(Node * p_owner,Node * p_node,Map<StringName,int> & name_map,HashMap<Variant,int,VariantHasher,VariantComparator> & variant_map,Map<Node *,int> & node_map,Map<Node *,int> & nodepath_map)676 Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, Map<Node *, int> &node_map, Map<Node *, int> &nodepath_map) {
677
678 if (p_node != p_owner && p_node->get_owner() && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner()))
679 return OK;
680
681 List<MethodInfo> _signals;
682 p_node->get_signal_list(&_signals);
683 _signals.sort();
684
685 //ERR_FAIL_COND_V( !node_map.has(p_node), ERR_BUG);
686 //NodeData &nd = nodes[node_map[p_node]];
687
688 for (List<MethodInfo>::Element *E = _signals.front(); E; E = E->next()) {
689
690 List<Node::Connection> conns;
691 p_node->get_signal_connection_list(E->get().name, &conns);
692
693 conns.sort();
694
695 for (List<Node::Connection>::Element *F = conns.front(); F; F = F->next()) {
696
697 const Node::Connection &c = F->get();
698
699 if (!(c.flags & CONNECT_PERSIST)) //only persistent connections get saved
700 continue;
701
702 // only connections that originate or end into main saved scene are saved
703 // everything else is discarded
704
705 Node *target = c.target->cast_to<Node>();
706
707 if (!target) {
708 continue;
709 }
710
711 //find if this connection already exists
712 Node *common_parent = target->find_common_parent_with(p_node);
713
714 ERR_CONTINUE(!common_parent);
715
716 if (common_parent != p_owner && common_parent->get_filename() == String()) {
717 common_parent = common_parent->get_owner();
718 }
719
720 bool exists = false;
721
722 //go through ownership chain to see if this exists
723 while (common_parent) {
724
725 Ref<SceneState> ps;
726
727 if (common_parent == p_owner)
728 ps = common_parent->get_scene_inherited_state();
729 else
730 ps = common_parent->get_scene_instance_state();
731
732 if (ps.is_valid()) {
733
734 NodePath signal_from = common_parent->get_path_to(p_node);
735 NodePath signal_to = common_parent->get_path_to(target);
736
737 if (ps->has_connection(signal_from, c.signal, signal_to, c.method)) {
738 exists = true;
739 break;
740 }
741 }
742
743 if (common_parent == p_owner)
744 break;
745 else
746 common_parent = common_parent->get_owner();
747 }
748
749 if (exists) { //already exists (comes from instance or inheritance), so don't save
750 continue;
751 }
752
753 {
754 Node *nl = p_node;
755
756 bool exists = false;
757
758 while (nl) {
759
760 if (nl == p_owner) {
761
762 Ref<SceneState> state = nl->get_scene_inherited_state();
763 if (state.is_valid()) {
764 int from_node = state->find_node_by_path(nl->get_path_to(p_node));
765 int to_node = state->find_node_by_path(nl->get_path_to(target));
766
767 if (from_node >= 0 && to_node >= 0) {
768 //this one has state for this node, save
769 if (state->is_connection(from_node, c.signal, to_node, c.method)) {
770 exists = true;
771 break;
772 }
773 }
774 }
775
776 nl = NULL;
777 } else {
778 if (nl->get_filename() != String()) {
779 //is an instance
780 Ref<SceneState> state = nl->get_scene_instance_state();
781 if (state.is_valid()) {
782 int from_node = state->find_node_by_path(nl->get_path_to(p_node));
783 int to_node = state->find_node_by_path(nl->get_path_to(target));
784
785 if (from_node >= 0 && to_node >= 0) {
786 //this one has state for this node, save
787 if (state->is_connection(from_node, c.signal, to_node, c.method)) {
788 exists = true;
789 break;
790 }
791 }
792 }
793 }
794 nl = nl->get_owner();
795 }
796 }
797
798 if (exists) {
799 continue;
800 }
801 }
802
803 int src_id;
804
805 if (node_map.has(p_node)) {
806 src_id = node_map[p_node];
807 } else {
808 if (nodepath_map.has(p_node)) {
809 src_id = FLAG_ID_IS_PATH | nodepath_map[p_node];
810 } else {
811 int sidx = nodepath_map.size();
812 nodepath_map[p_node] = sidx;
813 src_id = FLAG_ID_IS_PATH | sidx;
814 }
815 }
816
817 int target_id;
818
819 if (node_map.has(target)) {
820 target_id = node_map[target];
821 } else {
822 if (nodepath_map.has(target)) {
823 target_id = FLAG_ID_IS_PATH | nodepath_map[target];
824 } else {
825 int sidx = nodepath_map.size();
826 nodepath_map[target] = sidx;
827 target_id = FLAG_ID_IS_PATH | sidx;
828 }
829 }
830
831 ConnectionData cd;
832 cd.from = src_id;
833 cd.to = target_id;
834 cd.method = _nm_get_string(c.method, name_map);
835 cd.signal = _nm_get_string(c.signal, name_map);
836 cd.flags = c.flags;
837 for (int i = 0; i < c.binds.size(); i++) {
838
839 cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map));
840 }
841 connections.push_back(cd);
842 }
843 }
844
845 for (int i = 0; i < p_node->get_child_count(); i++) {
846
847 Node *c = p_node->get_child(i);
848 Error err = _parse_connections(p_owner, c, name_map, variant_map, node_map, nodepath_map);
849 if (err)
850 return err;
851 }
852
853 return OK;
854 }
855
pack(Node * p_scene)856 Error SceneState::pack(Node *p_scene) {
857 ERR_FAIL_NULL_V(p_scene, ERR_INVALID_PARAMETER);
858
859 clear();
860
861 Node *scene = p_scene;
862
863 Map<StringName, int> name_map;
864 HashMap<Variant, int, VariantHasher, VariantComparator> variant_map;
865 Map<Node *, int> node_map;
866 Map<Node *, int> nodepath_map;
867
868 //if using scene inheritance, pack the scene it inherits from
869 if (scene->get_scene_inherited_state().is_valid()) {
870 String path = scene->get_scene_inherited_state()->get_path();
871 Ref<PackedScene> instance = ResourceLoader::load(path);
872 if (instance.is_valid()) {
873
874 base_scene_idx = _vm_get_variant(instance, variant_map);
875 }
876 }
877 //instanced, only direct sub-scnes are supported of course
878
879 Error err = _parse_node(scene, scene, -1, name_map, variant_map, node_map, nodepath_map);
880 if (err) {
881 clear();
882 ERR_FAIL_V(err);
883 }
884
885 err = _parse_connections(scene, scene, name_map, variant_map, node_map, nodepath_map);
886 if (err) {
887 clear();
888 ERR_FAIL_V(err);
889 }
890
891 names.resize(name_map.size());
892
893 for (Map<StringName, int>::Element *E = name_map.front(); E; E = E->next()) {
894
895 names[E->get()] = E->key();
896 }
897
898 variants.resize(variant_map.size());
899 const Variant *K = NULL;
900 while ((K = variant_map.next(K))) {
901
902 int idx = variant_map[*K];
903 variants[idx] = *K;
904 }
905
906 node_paths.resize(nodepath_map.size());
907 for (Map<Node *, int>::Element *E = nodepath_map.front(); E; E = E->next()) {
908
909 node_paths[E->get()] = scene->get_path_to(E->key());
910 }
911
912 return OK;
913 }
914
set_path(const String & p_path)915 void SceneState::set_path(const String &p_path) {
916
917 path = p_path;
918 }
919
get_path() const920 String SceneState::get_path() const {
921
922 return path;
923 }
924
clear()925 void SceneState::clear() {
926
927 names.clear();
928 variants.clear();
929 nodes.clear();
930 connections.clear();
931 node_path_cache.clear();
932 node_paths.clear();
933 editable_instances.clear();
934 base_scene_idx = -1;
935 }
936
_get_base_scene_state() const937 Ref<SceneState> SceneState::_get_base_scene_state() const {
938
939 if (base_scene_idx >= 0) {
940
941 Ref<PackedScene> ps = variants[base_scene_idx];
942 if (ps.is_valid()) {
943 return ps->get_state();
944 }
945 }
946
947 return Ref<SceneState>();
948 }
949
find_node_by_path(const NodePath & p_node) const950 int SceneState::find_node_by_path(const NodePath &p_node) const {
951
952 if (!node_path_cache.has(p_node)) {
953 if (_get_base_scene_state().is_valid()) {
954 int idx = _get_base_scene_state()->find_node_by_path(p_node);
955 if (idx >= 0) {
956 int rkey = _find_base_scene_node_remap_key(idx);
957 if (rkey == -1) {
958 rkey = nodes.size() + base_scene_node_remap.size();
959 base_scene_node_remap[rkey] = idx;
960 }
961 return rkey;
962 }
963 }
964 return -1;
965 }
966
967 int nid = node_path_cache[p_node];
968
969 if (_get_base_scene_state().is_valid() && !base_scene_node_remap.has(nid)) {
970 //for nodes that _do_ exist in current scene, still try to look for
971 //the node in the instanced scene, as a property may be missing
972 //from the local one
973 int idx = _get_base_scene_state()->find_node_by_path(p_node);
974 if (idx != -1) {
975 base_scene_node_remap[nid] = idx;
976 }
977 }
978
979 return nid;
980 }
981
_find_base_scene_node_remap_key(int p_idx) const982 int SceneState::_find_base_scene_node_remap_key(int p_idx) const {
983
984 for (Map<int, int>::Element *E = base_scene_node_remap.front(); E; E = E->next()) {
985 if (E->value() == p_idx) {
986 return E->key();
987 }
988 }
989 return -1;
990 }
991
get_property_value(int p_node,const StringName & p_property,bool & found) const992 Variant SceneState::get_property_value(int p_node, const StringName &p_property, bool &found) const {
993
994 found = false;
995
996 ERR_FAIL_COND_V(p_node < 0, Variant());
997
998 if (p_node < nodes.size()) {
999 //find in built-in nodes
1000 int pc = nodes[p_node].properties.size();
1001 const StringName *namep = names.ptr();
1002
1003 const NodeData::Property *p = nodes[p_node].properties.ptr();
1004 for (int i = 0; i < pc; i++) {
1005 if (p_property == namep[p[i].name]) {
1006 found = true;
1007 return variants[p[i].value];
1008 }
1009 }
1010 }
1011
1012 //property not found, try on instance
1013
1014 if (base_scene_node_remap.has(p_node)) {
1015 return _get_base_scene_state()->get_property_value(base_scene_node_remap[p_node], p_property, found);
1016 }
1017
1018 return Variant();
1019 }
1020
is_node_in_group(int p_node,const StringName & p_group) const1021 bool SceneState::is_node_in_group(int p_node, const StringName &p_group) const {
1022
1023 ERR_FAIL_COND_V(p_node < 0, false);
1024
1025 if (p_node < nodes.size()) {
1026 const StringName *namep = names.ptr();
1027 for (int i = 0; i < nodes[p_node].groups.size(); i++) {
1028 if (namep[nodes[p_node].groups[i]] == p_group)
1029 return true;
1030 }
1031 }
1032
1033 if (base_scene_node_remap.has(p_node)) {
1034 return _get_base_scene_state()->is_node_in_group(base_scene_node_remap[p_node], p_group);
1035 }
1036
1037 return false;
1038 }
1039
1040 bool SceneState::disable_placeholders = false;
1041
set_disable_placeholders(bool p_disable)1042 void SceneState::set_disable_placeholders(bool p_disable) {
1043
1044 disable_placeholders = p_disable;
1045 }
1046
is_connection(int p_node,const StringName & p_signal,int p_to_node,const StringName & p_to_method) const1047 bool SceneState::is_connection(int p_node, const StringName &p_signal, int p_to_node, const StringName &p_to_method) const {
1048
1049 ERR_FAIL_COND_V(p_node < 0, false);
1050 ERR_FAIL_COND_V(p_to_node < 0, false);
1051
1052 if (p_node < nodes.size() && p_to_node < nodes.size()) {
1053
1054 int signal_idx = -1;
1055 int method_idx = -1;
1056 for (int i = 0; i < names.size(); i++) {
1057 if (names[i] == p_signal) {
1058 signal_idx = i;
1059 } else if (names[i] == p_to_method) {
1060 method_idx = i;
1061 }
1062 }
1063
1064 if (signal_idx >= 0 && method_idx >= 0) {
1065 //signal and method strings are stored..
1066
1067 for (int i = 0; i < connections.size(); i++) {
1068
1069 if (connections[i].from == p_node && connections[i].to == p_to_node && connections[i].signal == signal_idx && connections[i].method == method_idx) {
1070
1071 return true;
1072 }
1073 }
1074 }
1075 }
1076
1077 if (base_scene_node_remap.has(p_node) && base_scene_node_remap.has(p_to_node)) {
1078 return _get_base_scene_state()->is_connection(base_scene_node_remap[p_node], p_signal, base_scene_node_remap[p_to_node], p_to_method);
1079 }
1080
1081 return false;
1082 }
1083
set_bundled_scene(const Dictionary & d)1084 void SceneState::set_bundled_scene(const Dictionary &d) {
1085
1086 ERR_FAIL_COND(!d.has("names"));
1087 ERR_FAIL_COND(!d.has("variants"));
1088 ERR_FAIL_COND(!d.has("node_count"));
1089 ERR_FAIL_COND(!d.has("nodes"));
1090 ERR_FAIL_COND(!d.has("conn_count"));
1091 ERR_FAIL_COND(!d.has("conns"));
1092 // ERR_FAIL_COND( !d.has("path"));
1093
1094 int version = 1;
1095 if (d.has("version"))
1096 version = d["version"];
1097
1098 if (version > PACK_VERSION) {
1099 ERR_EXPLAIN("Save format version too new!");
1100 ERR_FAIL();
1101 }
1102
1103 DVector<String> snames = d["names"];
1104 if (snames.size()) {
1105
1106 int namecount = snames.size();
1107 names.resize(namecount);
1108 DVector<String>::Read r = snames.read();
1109 for (int i = 0; i < names.size(); i++)
1110 names[i] = r[i];
1111 }
1112
1113 Array svariants = d["variants"];
1114
1115 if (svariants.size()) {
1116 int varcount = svariants.size();
1117 variants.resize(varcount);
1118 for (int i = 0; i < varcount; i++) {
1119
1120 variants[i] = svariants[i];
1121 }
1122
1123 } else {
1124 variants.clear();
1125 }
1126
1127 nodes.resize(d["node_count"]);
1128 int nc = nodes.size();
1129 if (nc) {
1130 DVector<int> snodes = d["nodes"];
1131 DVector<int>::Read r = snodes.read();
1132 int idx = 0;
1133 for (int i = 0; i < nc; i++) {
1134 NodeData &nd = nodes[i];
1135 nd.parent = r[idx++];
1136 nd.owner = r[idx++];
1137 nd.type = r[idx++];
1138 nd.name = r[idx++];
1139 nd.instance = r[idx++];
1140 nd.properties.resize(r[idx++]);
1141 for (int j = 0; j < nd.properties.size(); j++) {
1142
1143 nd.properties[j].name = r[idx++];
1144 nd.properties[j].value = r[idx++];
1145 }
1146 nd.groups.resize(r[idx++]);
1147 for (int j = 0; j < nd.groups.size(); j++) {
1148
1149 nd.groups[j] = r[idx++];
1150 }
1151 }
1152 }
1153
1154 connections.resize(d["conn_count"]);
1155 int cc = connections.size();
1156
1157 if (cc) {
1158
1159 DVector<int> sconns = d["conns"];
1160 DVector<int>::Read r = sconns.read();
1161 int idx = 0;
1162 for (int i = 0; i < cc; i++) {
1163 ConnectionData &cd = connections[i];
1164 cd.from = r[idx++];
1165 cd.to = r[idx++];
1166 cd.signal = r[idx++];
1167 cd.method = r[idx++];
1168 cd.flags = r[idx++];
1169 cd.binds.resize(r[idx++]);
1170
1171 for (int j = 0; j < cd.binds.size(); j++) {
1172
1173 cd.binds[j] = r[idx++];
1174 }
1175 }
1176 }
1177
1178 Array np;
1179 if (d.has("node_paths")) {
1180 np = d["node_paths"];
1181 }
1182 node_paths.resize(np.size());
1183 for (int i = 0; i < np.size(); i++) {
1184 node_paths[i] = np[i];
1185 }
1186
1187 Array ei;
1188 if (d.has("editable_instances")) {
1189 ei = d["editable_instances"];
1190 }
1191
1192 if (d.has("base_scene")) {
1193 base_scene_idx = d["base_scene"];
1194 }
1195
1196 editable_instances.resize(ei.size());
1197 for (int i = 0; i < editable_instances.size(); i++) {
1198 editable_instances[i] = ei[i];
1199 }
1200
1201 // path=d["path"];
1202 }
1203
get_bundled_scene() const1204 Dictionary SceneState::get_bundled_scene() const {
1205
1206 DVector<String> rnames;
1207 rnames.resize(names.size());
1208
1209 if (names.size()) {
1210
1211 DVector<String>::Write r = rnames.write();
1212
1213 for (int i = 0; i < names.size(); i++)
1214 r[i] = names[i];
1215 }
1216
1217 Dictionary d;
1218 d["names"] = rnames;
1219 d["variants"] = variants;
1220
1221 Vector<int> rnodes;
1222 d["node_count"] = nodes.size();
1223
1224 for (int i = 0; i < nodes.size(); i++) {
1225
1226 const NodeData &nd = nodes[i];
1227 rnodes.push_back(nd.parent);
1228 rnodes.push_back(nd.owner);
1229 rnodes.push_back(nd.type);
1230 rnodes.push_back(nd.name);
1231 rnodes.push_back(nd.instance);
1232 rnodes.push_back(nd.properties.size());
1233 for (int j = 0; j < nd.properties.size(); j++) {
1234
1235 rnodes.push_back(nd.properties[j].name);
1236 rnodes.push_back(nd.properties[j].value);
1237 }
1238 rnodes.push_back(nd.groups.size());
1239 for (int j = 0; j < nd.groups.size(); j++) {
1240
1241 rnodes.push_back(nd.groups[j]);
1242 }
1243 }
1244
1245 d["nodes"] = rnodes;
1246
1247 Vector<int> rconns;
1248 d["conn_count"] = connections.size();
1249
1250 for (int i = 0; i < connections.size(); i++) {
1251
1252 const ConnectionData &cd = connections[i];
1253 rconns.push_back(cd.from);
1254 rconns.push_back(cd.to);
1255 rconns.push_back(cd.signal);
1256 rconns.push_back(cd.method);
1257 rconns.push_back(cd.flags);
1258 rconns.push_back(cd.binds.size());
1259 for (int j = 0; j < cd.binds.size(); j++)
1260 rconns.push_back(cd.binds[j]);
1261 }
1262
1263 d["conns"] = rconns;
1264
1265 Array rnode_paths;
1266 rnode_paths.resize(node_paths.size());
1267 for (int i = 0; i < node_paths.size(); i++) {
1268 rnode_paths[i] = node_paths[i];
1269 }
1270 d["node_paths"] = rnode_paths;
1271
1272 Array reditable_instances;
1273 reditable_instances.resize(editable_instances.size());
1274 for (int i = 0; i < editable_instances.size(); i++) {
1275 reditable_instances[i] = editable_instances[i];
1276 }
1277 d["editable_instances"] = reditable_instances;
1278 if (base_scene_idx >= 0) {
1279 d["base_scene"] = base_scene_idx;
1280 }
1281
1282 d["version"] = PACK_VERSION;
1283
1284 // d["path"]=path;
1285
1286 return d;
1287 }
1288
get_node_count() const1289 int SceneState::get_node_count() const {
1290
1291 return nodes.size();
1292 }
1293
get_node_type(int p_idx) const1294 StringName SceneState::get_node_type(int p_idx) const {
1295
1296 ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
1297 if (nodes[p_idx].type == TYPE_INSTANCED)
1298 return StringName();
1299 return names[nodes[p_idx].type];
1300 }
1301
get_node_name(int p_idx) const1302 StringName SceneState::get_node_name(int p_idx) const {
1303
1304 ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
1305 return names[nodes[p_idx].name];
1306 }
1307
is_node_instance_placeholder(int p_idx) const1308 bool SceneState::is_node_instance_placeholder(int p_idx) const {
1309
1310 ERR_FAIL_INDEX_V(p_idx, nodes.size(), false);
1311
1312 return nodes[p_idx].instance >= 0 && nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER;
1313 }
1314
get_node_instance(int p_idx) const1315 Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
1316 ERR_FAIL_INDEX_V(p_idx, nodes.size(), Ref<PackedScene>());
1317
1318 if (nodes[p_idx].instance >= 0) {
1319 if (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER)
1320 return Ref<PackedScene>();
1321 else
1322 return variants[nodes[p_idx].instance & FLAG_MASK];
1323 } else if (nodes[p_idx].parent < 0 || nodes[p_idx].parent == NO_PARENT_SAVED) {
1324
1325 if (base_scene_idx >= 0) {
1326 return variants[base_scene_idx];
1327 }
1328 }
1329
1330 return Ref<PackedScene>();
1331 }
1332
get_node_instance_placeholder(int p_idx) const1333 String SceneState::get_node_instance_placeholder(int p_idx) const {
1334
1335 ERR_FAIL_INDEX_V(p_idx, nodes.size(), String());
1336
1337 if (nodes[p_idx].instance >= 0 && nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER) {
1338 return variants[nodes[p_idx].instance & FLAG_MASK];
1339 }
1340
1341 return String();
1342 }
1343
get_node_groups(int p_idx) const1344 Vector<StringName> SceneState::get_node_groups(int p_idx) const {
1345 ERR_FAIL_INDEX_V(p_idx, nodes.size(), Vector<StringName>());
1346 Vector<StringName> groups;
1347 for (int i = 0; i < nodes[p_idx].groups.size(); i++) {
1348 groups.push_back(names[nodes[p_idx].groups[i]]);
1349 }
1350 return groups;
1351 }
1352
get_node_path(int p_idx,bool p_for_parent) const1353 NodePath SceneState::get_node_path(int p_idx, bool p_for_parent) const {
1354
1355 ERR_FAIL_INDEX_V(p_idx, nodes.size(), NodePath());
1356
1357 if (nodes[p_idx].parent < 0 || nodes[p_idx].parent == NO_PARENT_SAVED) {
1358 if (p_for_parent) {
1359 return NodePath();
1360 } else {
1361 return NodePath(".");
1362 }
1363 }
1364
1365 Vector<StringName> sub_path;
1366 NodePath base_path;
1367 int nidx = p_idx;
1368 while (true) {
1369 if (nodes[nidx].parent == NO_PARENT_SAVED || nodes[nidx].parent < 0) {
1370
1371 sub_path.insert(0, ".");
1372 break;
1373 }
1374
1375 if (!p_for_parent || p_idx != nidx) {
1376 sub_path.insert(0, names[nodes[nidx].name]);
1377 }
1378
1379 if (nodes[nidx].parent & FLAG_ID_IS_PATH) {
1380 base_path = node_paths[nodes[nidx].parent & FLAG_MASK];
1381 break;
1382 } else {
1383 nidx = nodes[nidx].parent & FLAG_MASK;
1384 }
1385 }
1386
1387 for (int i = base_path.get_name_count() - 1; i >= 0; i--) {
1388 sub_path.insert(0, base_path.get_name(i));
1389 }
1390
1391 if (sub_path.empty()) {
1392 return NodePath(".");
1393 }
1394
1395 return NodePath(sub_path, false);
1396 }
1397
get_node_property_count(int p_idx) const1398 int SceneState::get_node_property_count(int p_idx) const {
1399
1400 ERR_FAIL_INDEX_V(p_idx, nodes.size(), -1);
1401 return nodes[p_idx].properties.size();
1402 }
get_node_property_name(int p_idx,int p_prop) const1403 StringName SceneState::get_node_property_name(int p_idx, int p_prop) const {
1404 ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
1405 ERR_FAIL_INDEX_V(p_prop, nodes[p_idx].properties.size(), StringName());
1406 return names[nodes[p_idx].properties[p_prop].name];
1407 }
get_node_property_value(int p_idx,int p_prop) const1408 Variant SceneState::get_node_property_value(int p_idx, int p_prop) const {
1409 ERR_FAIL_INDEX_V(p_idx, nodes.size(), Variant());
1410 ERR_FAIL_INDEX_V(p_prop, nodes[p_idx].properties.size(), Variant());
1411
1412 return variants[nodes[p_idx].properties[p_prop].value];
1413 }
1414
get_node_owner_path(int p_idx) const1415 NodePath SceneState::get_node_owner_path(int p_idx) const {
1416
1417 ERR_FAIL_INDEX_V(p_idx, nodes.size(), NodePath());
1418 if (nodes[p_idx].owner < 0 || nodes[p_idx].owner == NO_PARENT_SAVED)
1419 return NodePath(); //root likely
1420 if (nodes[p_idx].owner & FLAG_ID_IS_PATH) {
1421 return node_paths[nodes[p_idx].owner & FLAG_MASK];
1422 } else {
1423 return get_node_path(nodes[p_idx].owner & FLAG_MASK);
1424 }
1425 }
1426
get_connection_count() const1427 int SceneState::get_connection_count() const {
1428
1429 return connections.size();
1430 }
get_connection_source(int p_idx) const1431 NodePath SceneState::get_connection_source(int p_idx) const {
1432
1433 ERR_FAIL_INDEX_V(p_idx, connections.size(), NodePath());
1434 if (connections[p_idx].from & FLAG_ID_IS_PATH) {
1435 return node_paths[connections[p_idx].from & FLAG_MASK];
1436 } else {
1437 return get_node_path(connections[p_idx].from & FLAG_MASK);
1438 }
1439 }
1440
get_connection_signal(int p_idx) const1441 StringName SceneState::get_connection_signal(int p_idx) const {
1442
1443 ERR_FAIL_INDEX_V(p_idx, connections.size(), StringName());
1444 return names[connections[p_idx].signal];
1445 }
get_connection_target(int p_idx) const1446 NodePath SceneState::get_connection_target(int p_idx) const {
1447
1448 ERR_FAIL_INDEX_V(p_idx, connections.size(), NodePath());
1449 if (connections[p_idx].to & FLAG_ID_IS_PATH) {
1450 return node_paths[connections[p_idx].to & FLAG_MASK];
1451 } else {
1452 return get_node_path(connections[p_idx].to & FLAG_MASK);
1453 }
1454 }
get_connection_method(int p_idx) const1455 StringName SceneState::get_connection_method(int p_idx) const {
1456
1457 ERR_FAIL_INDEX_V(p_idx, connections.size(), StringName());
1458 return names[connections[p_idx].method];
1459 }
1460
get_connection_flags(int p_idx) const1461 int SceneState::get_connection_flags(int p_idx) const {
1462
1463 ERR_FAIL_INDEX_V(p_idx, connections.size(), -1);
1464 return connections[p_idx].flags;
1465 }
1466
get_connection_binds(int p_idx) const1467 Array SceneState::get_connection_binds(int p_idx) const {
1468
1469 ERR_FAIL_INDEX_V(p_idx, connections.size(), Array());
1470 Array binds;
1471 for (int i = 0; i < connections[p_idx].binds.size(); i++) {
1472 binds.push_back(variants[connections[p_idx].binds[i]]);
1473 }
1474 return binds;
1475 }
1476
has_connection(const NodePath & p_node_from,const StringName & p_signal,const NodePath & p_node_to,const StringName & p_method)1477 bool SceneState::has_connection(const NodePath &p_node_from, const StringName &p_signal, const NodePath &p_node_to, const StringName &p_method) {
1478
1479 // this method cannot be const because of this
1480 Ref<SceneState> ss = this;
1481
1482 do {
1483 for (int i = 0; i < ss->connections.size(); i++) {
1484 const ConnectionData &c = ss->connections[i];
1485
1486 NodePath np_from;
1487
1488 if (c.from & FLAG_ID_IS_PATH) {
1489 np_from = ss->node_paths[c.from & FLAG_MASK];
1490 } else {
1491 np_from = ss->get_node_path(c.from);
1492 }
1493
1494 NodePath np_to;
1495
1496 if (c.to & FLAG_ID_IS_PATH) {
1497 np_to = ss->node_paths[c.to & FLAG_MASK];
1498 } else {
1499 np_to = ss->get_node_path(c.to);
1500 }
1501
1502 StringName sn_signal = ss->names[c.signal];
1503 StringName sn_method = ss->names[c.method];
1504
1505 if (np_from == p_node_from && sn_signal == p_signal && np_to == p_node_to && sn_method == p_method) {
1506 return true;
1507 }
1508 }
1509
1510 ss = ss->_get_base_scene_state();
1511 } while (ss.is_valid());
1512
1513 return false;
1514 }
1515
get_editable_instances() const1516 Vector<NodePath> SceneState::get_editable_instances() const {
1517 return editable_instances;
1518 }
1519 //add
1520
add_name(const StringName & p_name)1521 int SceneState::add_name(const StringName &p_name) {
1522
1523 names.push_back(p_name);
1524 return names.size() - 1;
1525 }
1526
find_name(const StringName & p_name) const1527 int SceneState::find_name(const StringName &p_name) const {
1528
1529 for (int i = 0; i < names.size(); i++) {
1530 if (names[i] == p_name)
1531 return i;
1532 }
1533
1534 return -1;
1535 }
1536
add_value(const Variant & p_value)1537 int SceneState::add_value(const Variant &p_value) {
1538
1539 variants.push_back(p_value);
1540 return variants.size() - 1;
1541 }
1542
add_node_path(const NodePath & p_path)1543 int SceneState::add_node_path(const NodePath &p_path) {
1544
1545 node_paths.push_back(p_path);
1546 return (node_paths.size() - 1) | FLAG_ID_IS_PATH;
1547 }
add_node(int p_parent,int p_owner,int p_type,int p_name,int p_instance)1548 int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance) {
1549
1550 NodeData nd;
1551 nd.parent = p_parent;
1552 nd.owner = p_owner;
1553 nd.type = p_type;
1554 nd.name = p_name;
1555 nd.instance = p_instance;
1556
1557 nodes.push_back(nd);
1558
1559 return nodes.size() - 1;
1560 }
add_node_property(int p_node,int p_name,int p_value)1561 void SceneState::add_node_property(int p_node, int p_name, int p_value) {
1562
1563 ERR_FAIL_INDEX(p_node, nodes.size());
1564 ERR_FAIL_INDEX(p_name, names.size());
1565 ERR_FAIL_INDEX(p_value, variants.size());
1566
1567 NodeData::Property prop;
1568 prop.name = p_name;
1569 prop.value = p_value;
1570 nodes[p_node].properties.push_back(prop);
1571 }
add_node_group(int p_node,int p_group)1572 void SceneState::add_node_group(int p_node, int p_group) {
1573
1574 ERR_FAIL_INDEX(p_node, nodes.size());
1575 ERR_FAIL_INDEX(p_group, names.size());
1576 nodes[p_node].groups.push_back(p_group);
1577 }
set_base_scene(int p_idx)1578 void SceneState::set_base_scene(int p_idx) {
1579
1580 ERR_FAIL_INDEX(p_idx, variants.size());
1581 base_scene_idx = p_idx;
1582 }
add_connection(int p_from,int p_to,int p_signal,int p_method,int p_flags,const Vector<int> & p_binds)1583 void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds) {
1584
1585 ERR_FAIL_INDEX(p_signal, names.size());
1586 ERR_FAIL_INDEX(p_method, names.size());
1587
1588 for (int i = 0; i < p_binds.size(); i++) {
1589 ERR_FAIL_INDEX(p_binds[i], variants.size());
1590 }
1591 ConnectionData c;
1592 c.from = p_from;
1593 c.to = p_to;
1594 c.signal = p_signal;
1595 c.method = p_method;
1596 c.flags = p_flags;
1597 c.binds = p_binds;
1598 connections.push_back(c);
1599 }
add_editable_instance(const NodePath & p_path)1600 void SceneState::add_editable_instance(const NodePath &p_path) {
1601
1602 editable_instances.push_back(p_path);
1603 }
1604
_get_node_groups(int p_idx) const1605 DVector<String> SceneState::_get_node_groups(int p_idx) const {
1606
1607 Vector<StringName> groups = get_node_groups(p_idx);
1608 DVector<String> ret;
1609
1610 for (int i = 0; i < groups.size(); i++)
1611 ret.push_back(groups[i]);
1612
1613 return ret;
1614 }
1615
_bind_methods()1616 void SceneState::_bind_methods() {
1617
1618 //unbuild API
1619
1620 ObjectTypeDB::bind_method(_MD("get_node_count"), &SceneState::get_node_count);
1621 ObjectTypeDB::bind_method(_MD("get_node_type", "idx"), &SceneState::get_node_type);
1622 ObjectTypeDB::bind_method(_MD("get_node_name", "idx"), &SceneState::get_node_name);
1623 ObjectTypeDB::bind_method(_MD("get_node_path", "idx", "for_parent"), &SceneState::get_node_path, DEFVAL(false));
1624 ObjectTypeDB::bind_method(_MD("get_node_owner_path", "idx"), &SceneState::get_node_owner_path);
1625 ObjectTypeDB::bind_method(_MD("is_node_instance_placeholder", "idx"), &SceneState::is_node_instance_placeholder);
1626 ObjectTypeDB::bind_method(_MD("get_node_instance_placeholder", "idx"), &SceneState::get_node_instance_placeholder);
1627 ObjectTypeDB::bind_method(_MD("get_node_instance:PackedScene", "idx"), &SceneState::get_node_instance);
1628 ObjectTypeDB::bind_method(_MD("get_node_groups", "idx"), &SceneState::_get_node_groups);
1629 ObjectTypeDB::bind_method(_MD("get_node_property_count", "idx"), &SceneState::get_node_property_count);
1630 ObjectTypeDB::bind_method(_MD("get_node_property_name", "idx", "prop_idx"), &SceneState::get_node_property_name);
1631 ObjectTypeDB::bind_method(_MD("get_node_property_value", "idx", "prop_idx"), &SceneState::get_node_property_value);
1632 ObjectTypeDB::bind_method(_MD("get_connection_count"), &SceneState::get_connection_count);
1633 ObjectTypeDB::bind_method(_MD("get_connection_source", "idx"), &SceneState::get_connection_source);
1634 ObjectTypeDB::bind_method(_MD("get_connection_signal", "idx"), &SceneState::get_connection_signal);
1635 ObjectTypeDB::bind_method(_MD("get_connection_target", "idx"), &SceneState::get_connection_target);
1636 ObjectTypeDB::bind_method(_MD("get_connection_method", "idx"), &SceneState::get_connection_method);
1637 ObjectTypeDB::bind_method(_MD("get_connection_flags", "idx"), &SceneState::get_connection_flags);
1638 ObjectTypeDB::bind_method(_MD("get_connection_binds", "idx"), &SceneState::get_connection_binds);
1639 }
1640
SceneState()1641 SceneState::SceneState() {
1642
1643 base_scene_idx = -1;
1644 last_modified_time = 0;
1645 }
1646
1647 ////////////////
1648
_set_bundled_scene(const Dictionary & d)1649 void PackedScene::_set_bundled_scene(const Dictionary &d) {
1650
1651 state->set_bundled_scene(d);
1652 }
1653
_get_bundled_scene() const1654 Dictionary PackedScene::_get_bundled_scene() const {
1655
1656 return state->get_bundled_scene();
1657 }
1658
pack(Node * p_scene)1659 Error PackedScene::pack(Node *p_scene) {
1660
1661 return state->pack(p_scene);
1662 }
1663
clear()1664 void PackedScene::clear() {
1665
1666 state->clear();
1667 }
1668
can_instance() const1669 bool PackedScene::can_instance() const {
1670
1671 return state->can_instance();
1672 }
1673
instance(bool p_gen_edit_state) const1674 Node *PackedScene::instance(bool p_gen_edit_state) const {
1675
1676 #ifndef TOOLS_ENABLED
1677 if (p_gen_edit_state) {
1678 ERR_EXPLAIN("Edit state is only for editors, does not work without tools compiled");
1679 ERR_FAIL_COND_V(p_gen_edit_state, NULL);
1680 }
1681 #endif
1682
1683 Node *s = state->instance(p_gen_edit_state);
1684 if (!s)
1685 return NULL;
1686
1687 if (p_gen_edit_state) {
1688 s->set_scene_instance_state(state);
1689 }
1690
1691 if (get_path() != "" && get_path().find("::") == -1)
1692 s->set_filename(get_path());
1693
1694 s->notification(Node::NOTIFICATION_INSTANCED);
1695
1696 return s;
1697 }
1698
replace_state(Ref<SceneState> p_by)1699 void PackedScene::replace_state(Ref<SceneState> p_by) {
1700
1701 state = p_by;
1702 state->set_path(get_path());
1703 #ifdef TOOLS_ENABLED
1704 state->set_last_modified_time(get_last_modified_time());
1705 #endif
1706 }
1707
recreate_state()1708 void PackedScene::recreate_state() {
1709
1710 state = Ref<SceneState>(memnew(SceneState));
1711 state->set_path(get_path());
1712 #ifdef TOOLS_ENABLED
1713 state->set_last_modified_time(get_last_modified_time());
1714 #endif
1715 }
1716
get_state()1717 Ref<SceneState> PackedScene::get_state() {
1718
1719 return state;
1720 }
1721
set_path(const String & p_path,bool p_take_over)1722 void PackedScene::set_path(const String &p_path, bool p_take_over) {
1723
1724 state->set_path(p_path);
1725 Resource::set_path(p_path, p_take_over);
1726 }
1727
_bind_methods()1728 void PackedScene::_bind_methods() {
1729
1730 ObjectTypeDB::bind_method(_MD("pack", "path:Node"), &PackedScene::pack);
1731 ObjectTypeDB::bind_method(_MD("instance:Node", "gen_edit_state"), &PackedScene::instance, DEFVAL(false));
1732 ObjectTypeDB::bind_method(_MD("can_instance"), &PackedScene::can_instance);
1733 ObjectTypeDB::bind_method(_MD("_set_bundled_scene"), &PackedScene::_set_bundled_scene);
1734 ObjectTypeDB::bind_method(_MD("_get_bundled_scene"), &PackedScene::_get_bundled_scene);
1735 ObjectTypeDB::bind_method(_MD("get_state:SceneState"), &PackedScene::get_state);
1736
1737 ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_bundled"), _SCS("_set_bundled_scene"), _SCS("_get_bundled_scene"));
1738 }
1739
PackedScene()1740 PackedScene::PackedScene() {
1741
1742 state = Ref<SceneState>(memnew(SceneState));
1743 }
1744