summaryrefslogtreecommitdiff
path: root/scene/main/scene_main_loop.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/main/scene_main_loop.cpp')
-rw-r--r--scene/main/scene_main_loop.cpp665
1 files changed, 660 insertions, 5 deletions
diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp
index 9f2fadcb4d..adf053f5c9 100644
--- a/scene/main/scene_main_loop.cpp
+++ b/scene/main/scene_main_loop.cpp
@@ -41,7 +41,9 @@
#include "scene/scene_string_names.h"
#include "io/resource_loader.h"
#include "viewport.h"
-
+#include "scene/resources/packed_scene.h"
+#include "scene/resources/material.h"
+#include "scene/resources/mesh.h"
void SceneTree::tree_changed() {
@@ -51,6 +53,9 @@ void SceneTree::tree_changed() {
void SceneTree::node_removed(Node *p_node) {
+ if (current_scene==p_node) {
+ current_scene=NULL;
+ }
emit_signal(node_removed_name,p_node);
if (call_lock>0)
call_skip.insert(p_node);
@@ -467,7 +472,6 @@ void SceneTree::init() {
input_handled=false;
- editor_hint=false;
pause=false;
root->_set_tree(this);
@@ -621,6 +625,175 @@ bool SceneTree::is_editor_hint() const {
return editor_hint;
}
+void SceneTree::set_debug_collisions_hint(bool p_enabled) {
+
+ debug_collisions_hint=p_enabled;
+}
+
+bool SceneTree::is_debugging_collisions_hint() const {
+
+ return debug_collisions_hint;
+}
+
+void SceneTree::set_debug_navigation_hint(bool p_enabled) {
+
+ debug_navigation_hint=p_enabled;
+}
+
+bool SceneTree::is_debugging_navigation_hint() const {
+
+ return debug_navigation_hint;
+}
+
+void SceneTree::set_debug_collisions_color(const Color& p_color) {
+
+ debug_collisions_color=p_color;
+}
+
+Color SceneTree::get_debug_collisions_color() const {
+
+ return debug_collisions_color;
+}
+
+void SceneTree::set_debug_collision_contact_color(const Color& p_color) {
+
+ debug_collision_contact_color=p_color;
+}
+
+Color SceneTree::get_debug_collision_contact_color() const {
+
+ return debug_collision_contact_color;
+}
+
+void SceneTree::set_debug_navigation_color(const Color& p_color) {
+
+ debug_navigation_color=p_color;
+}
+
+Color SceneTree::get_debug_navigation_color() const {
+
+ return debug_navigation_color;
+}
+
+void SceneTree::set_debug_navigation_disabled_color(const Color& p_color) {
+
+ debug_navigation_disabled_color=p_color;
+}
+
+Color SceneTree::get_debug_navigation_disabled_color() const {
+
+ return debug_navigation_disabled_color;
+}
+
+Ref<Material> SceneTree::get_debug_navigation_material() {
+
+ if (navigation_material.is_valid())
+ return navigation_material;
+
+ Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+ line_material->set_flag(Material::FLAG_UNSHADED, true);
+ line_material->set_line_width(3.0);
+ line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+ line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
+ line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_navigation_color());
+
+ navigation_material=line_material;
+
+ return navigation_material;
+
+}
+
+Ref<Material> SceneTree::get_debug_navigation_disabled_material(){
+
+ if (navigation_disabled_material.is_valid())
+ return navigation_disabled_material;
+
+ Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+ line_material->set_flag(Material::FLAG_UNSHADED, true);
+ line_material->set_line_width(3.0);
+ line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+ line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
+ line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_navigation_disabled_color());
+
+ navigation_disabled_material=line_material;
+
+ return navigation_disabled_material;
+
+}
+Ref<Material> SceneTree::get_debug_collision_material() {
+
+ if (collision_material.is_valid())
+ return collision_material;
+
+
+ Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+ line_material->set_flag(Material::FLAG_UNSHADED, true);
+ line_material->set_line_width(3.0);
+ line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+ line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
+ line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_collisions_color());
+
+ collision_material=line_material;
+
+ return collision_material;
+}
+
+Ref<Mesh> SceneTree::get_debug_contact_mesh() {
+
+ if (debug_contact_mesh.is_valid())
+ return debug_contact_mesh;
+
+ debug_contact_mesh = Ref<Mesh>( memnew( Mesh ) );
+
+ Ref<FixedMaterial> mat = memnew( FixedMaterial );
+ mat->set_flag(Material::FLAG_UNSHADED,true);
+ mat->set_flag(Material::FLAG_DOUBLE_SIDED,true);
+ mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
+ mat->set_parameter(FixedMaterial::PARAM_DIFFUSE,get_debug_collision_contact_color());
+
+ Vector3 diamond[6]={
+ Vector3(-1, 0, 0),
+ Vector3( 1, 0, 0),
+ Vector3( 0, -1, 0),
+ Vector3( 0, 1, 0),
+ Vector3( 0, 0, -1),
+ Vector3( 0, 0, 1)
+ };
+
+ int diamond_faces[8*3]={
+ 0,2,4,
+ 0,3,4,
+ 1,2,4,
+ 1,3,4,
+ 0,2,5,
+ 0,3,5,
+ 1,2,5,
+ 1,3,5,
+ };
+
+ DVector<int> indices;
+ for(int i=0;i<8*3;i++)
+ indices.push_back(diamond_faces[i]);
+
+ DVector<Vector3> vertices;
+ for(int i=0;i<6;i++)
+ vertices.push_back(diamond[i]*0.1);
+
+ Array arr;
+ arr.resize(Mesh::ARRAY_MAX);
+ arr[Mesh::ARRAY_VERTEX]=vertices;
+ arr[Mesh::ARRAY_INDEX]=indices;
+
+
+ debug_contact_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,arr);
+ debug_contact_mesh->surface_set_material(0,mat);
+
+ return debug_contact_mesh;
+
+}
+
+
+
void SceneTree::set_pause(bool p_enabled) {
if (p_enabled==pause)
@@ -984,7 +1157,428 @@ Node *SceneTree::get_edited_scene_root() const {
}
#endif
+void SceneTree::set_current_scene(Node* p_scene) {
+
+ ERR_FAIL_COND(p_scene && p_scene->get_parent()!=root);
+ current_scene=p_scene;
+}
+
+Node* SceneTree::get_current_scene() const{
+
+ return current_scene;
+}
+
+void SceneTree::_change_scene(Node* p_to) {
+
+ if (current_scene) {
+ memdelete( current_scene );
+ current_scene=NULL;
+ }
+
+ if (p_to) {
+ current_scene=p_to;
+ root->add_child(p_to);
+ }
+}
+
+Error SceneTree::change_scene(const String& p_path){
+
+ Ref<PackedScene> new_scene = ResourceLoader::load(p_path);
+ if (new_scene.is_null())
+ return ERR_CANT_OPEN;
+
+ return change_scene_to(new_scene);
+
+}
+Error SceneTree::change_scene_to(const Ref<PackedScene>& p_scene){
+
+ Node *new_scene=NULL;
+ if (p_scene.is_valid()) {
+ new_scene = p_scene->instance();
+ ERR_FAIL_COND_V(!new_scene,ERR_CANT_CREATE);
+ }
+
+ call_deferred("_change_scene",new_scene);
+ return OK;
+
+}
+Error SceneTree::reload_current_scene() {
+
+ ERR_FAIL_COND_V(!current_scene,ERR_UNCONFIGURED);
+ String fname = current_scene->get_filename();
+ return change_scene(fname);
+}
+
+void SceneTree::add_current_scene(Node * p_current) {
+
+ current_scene=p_current;
+ root->add_child(p_current);
+}
+#ifdef DEBUG_ENABLED
+
+void SceneTree::_live_edit_node_path_func(const NodePath &p_path,int p_id) {
+
+ live_edit_node_path_cache[p_id]=p_path;
+}
+
+void SceneTree::_live_edit_res_path_func(const String &p_path,int p_id) {
+
+ live_edit_resource_cache[p_id]=p_path;
+}
+
+void SceneTree::_live_edit_node_set_func(int p_id,const StringName& p_prop,const Variant& p_value) {
+
+ if (!live_edit_node_path_cache.has(p_id))
+ return;
+
+ NodePath np = live_edit_node_path_cache[p_id];
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(np))
+ continue;
+ Node *n2 = n->get_node(np);
+
+ n2->set(p_prop,p_value);
+ }
+
+}
+
+void SceneTree::_live_edit_node_set_res_func(int p_id,const StringName& p_prop,const String& p_value) {
+
+ RES r = ResourceLoader::load(p_value);
+ if (!r.is_valid())
+ return;
+ _live_edit_node_set_func(p_id,p_prop,r);
+
+}
+void SceneTree::_live_edit_node_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) {
+
+ if (!live_edit_node_path_cache.has(p_id))
+ return;
+
+ NodePath np = live_edit_node_path_cache[p_id];
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(np))
+ continue;
+ Node *n2 = n->get_node(np);
+
+ n2->call(p_method,VARIANT_ARG_PASS);
+ }
+}
+void SceneTree::_live_edit_res_set_func(int p_id,const StringName& p_prop,const Variant& p_value) {
+
+ if (!live_edit_resource_cache.has(p_id))
+ return;
+
+ String resp = live_edit_resource_cache[p_id];
+
+ if (!ResourceCache::has(resp))
+ return;
+
+ RES r = ResourceCache::get(resp);
+ if (!r.is_valid())
+ return;
+
+ r->set(p_prop,p_value);
+}
+void SceneTree::_live_edit_res_set_res_func(int p_id,const StringName& p_prop,const String& p_value) {
+
+ RES r = ResourceLoader::load(p_value);
+ if (!r.is_valid())
+ return;
+ _live_edit_res_set_func(p_id,p_prop,r);
+
+}
+void SceneTree::_live_edit_res_call_func(int p_id,const StringName& p_method,VARIANT_ARG_DECLARE) {
+
+ if (!live_edit_resource_cache.has(p_id))
+ return;
+
+ String resp = live_edit_resource_cache[p_id];
+ if (!ResourceCache::has(resp))
+ return;
+
+ RES r = ResourceCache::get(resp);
+ if (!r.is_valid())
+ return;
+
+ r->call(p_method,VARIANT_ARG_PASS);
+}
+
+void SceneTree::_live_edit_root_func(const NodePath& p_scene_path,const String& p_scene_from) {
+
+ live_edit_root=p_scene_path;
+ live_edit_scene=p_scene_from;
+}
+
+void SceneTree::_live_edit_create_node_func(const NodePath& p_parent,const String& p_type,const String& p_name) {
+
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_parent))
+ continue;
+ Node *n2 = n->get_node(p_parent);
+
+ Object *o = ObjectTypeDB::instance(p_type);
+ if (!o)
+ continue;
+ Node *no=o->cast_to<Node>();
+ no->set_name(p_name);
+
+ n2->add_child(no);
+ }
+}
+void SceneTree::_live_edit_instance_node_func(const NodePath& p_parent,const String& p_path,const String& p_name){
+
+ Ref<PackedScene> ps = ResourceLoader::load(p_path);
+
+ if (!ps.is_valid())
+ return;
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_parent))
+ continue;
+ Node *n2 = n->get_node(p_parent);
+
+
+
+ Node *no=ps->instance();
+ no->set_name(p_name);
+
+ n2->add_child(no);
+ }
+}
+void SceneTree::_live_edit_remove_node_func(const NodePath& p_at){
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;) {
+
+ Set<Node*>::Element *N=F->next();
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+ Node *n2 = n->get_node(p_at);
+
+ memdelete(n2);
+
+ F=N;
+
+ }
+}
+void SceneTree::_live_edit_remove_and_keep_node_func(const NodePath& p_at,ObjectID p_keep_id){
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+
+ for(Set<Node*>::Element *F=E->get().front();F;) {
+
+ Set<Node*>::Element *N=F->next();
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+
+ Node *n2 = n->get_node(p_at);
+
+ n2->get_parent()->remove_child(n2);
+
+ live_edit_remove_list[n][p_keep_id]=n2;
+
+ F=N;
+
+ }
+}
+void SceneTree::_live_edit_restore_node_func(ObjectID p_id,const NodePath& p_at,int p_at_pos){
+
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;) {
+
+ Set<Node*>::Element *N=F->next();
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+ Node *n2 = n->get_node(p_at);
+
+ Map<Node*,Map<ObjectID,Node*> >::Element *EN=live_edit_remove_list.find(n);
+
+ if (!EN)
+ continue;
+
+ Map<ObjectID,Node*>::Element *FN=EN->get().find(p_id);
+
+ if (!FN)
+ continue;
+ n2->add_child(FN->get());
+
+ EN->get().erase(FN);
+
+ if (EN->get().size()==0) {
+ live_edit_remove_list.erase(EN);
+ }
+
+ F=N;
+
+ }
+}
+void SceneTree::_live_edit_duplicate_node_func(const NodePath& p_at,const String& p_new_name){
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+ Node *n2 = n->get_node(p_at);
+
+ Node *dup = n2->duplicate(true);
+
+ if (!dup)
+ continue;
+
+ dup->set_name(p_new_name);
+ n2->get_parent()->add_child(dup);
+
+ }
+}
+void SceneTree::_live_edit_reparent_node_func(const NodePath& p_at,const NodePath& p_new_place,const String& p_new_name,int p_at_pos){
+
+ Node *base = NULL;
+ if (root->has_node(live_edit_root))
+ base = root->get_node(live_edit_root);
+
+ Map<String,Set<Node*> >::Element *E=live_scene_edit_cache.find(live_edit_scene);
+ if (!E)
+ return; //scene not editable
+
+ for(Set<Node*>::Element *F=E->get().front();F;F=F->next()) {
+
+ Node *n=F->get();
+
+ if (base && !base->is_a_parent_of(n))
+ continue;
+
+ if (!n->has_node(p_at))
+ continue;
+ Node *nfrom = n->get_node(p_at);
+
+ if (!n->has_node(p_new_place))
+ continue;
+ Node *nto = n->get_node(p_new_place);
+
+ nfrom->get_parent()->remove_child(nfrom);
+ nfrom->set_name(p_new_name);
+
+ nto->add_child(nfrom);
+ if (p_at_pos>=0)
+ nto->move_child(nfrom,p_at_pos);
+
+ }
+}
+
+
+#endif
void SceneTree::_bind_methods() {
@@ -1000,6 +1594,11 @@ void SceneTree::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_editor_hint","enable"),&SceneTree::set_editor_hint);
ObjectTypeDB::bind_method(_MD("is_editor_hint"),&SceneTree::is_editor_hint);
+ ObjectTypeDB::bind_method(_MD("set_debug_collisions_hint","enable"),&SceneTree::set_debug_collisions_hint);
+ ObjectTypeDB::bind_method(_MD("is_debugging_collisions_hint"),&SceneTree::is_debugging_collisions_hint);
+ ObjectTypeDB::bind_method(_MD("set_debug_navigation_hint","enable"),&SceneTree::set_debug_navigation_hint);
+ ObjectTypeDB::bind_method(_MD("is_debugging_navigation_hint"),&SceneTree::is_debugging_navigation_hint);
+
#ifdef TOOLS_ENABLED
ObjectTypeDB::bind_method(_MD("set_edited_scene_root","scene"),&SceneTree::set_edited_scene_root);
ObjectTypeDB::bind_method(_MD("get_edited_scene_root"),&SceneTree::get_edited_scene_root);
@@ -1016,10 +1615,11 @@ void SceneTree::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_screen_stretch","mode","aspect","minsize"),&SceneTree::set_screen_stretch);
-
ObjectTypeDB::bind_method(_MD("queue_delete","obj"),&SceneTree::queue_delete);
+
+
MethodInfo mi;
mi.name="call_group";
mi.arguments.push_back( PropertyInfo( Variant::INT, "flags"));
@@ -1033,10 +1633,23 @@ void SceneTree::_bind_methods() {
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_group",&SceneTree::_call_group,mi,defargs);
+ ObjectTypeDB::bind_method(_MD("set_current_scene","child_node:Node"),&SceneTree::set_current_scene);
+ ObjectTypeDB::bind_method(_MD("get_current_scene:Node"),&SceneTree::get_current_scene);
+
+ ObjectTypeDB::bind_method(_MD("change_scene","path"),&SceneTree::change_scene);
+ ObjectTypeDB::bind_method(_MD("change_scene_to","packed_scene:PackedScene"),&SceneTree::change_scene_to);
+
+ ObjectTypeDB::bind_method(_MD("reload_current_scene"),&SceneTree::reload_current_scene);
+
+ ObjectTypeDB::bind_method(_MD("_change_scene"),&SceneTree::_change_scene);
+
ADD_SIGNAL( MethodInfo("tree_changed") );
ADD_SIGNAL( MethodInfo("node_removed",PropertyInfo( Variant::OBJECT, "node") ) );
ADD_SIGNAL( MethodInfo("screen_resized") );
+ ADD_SIGNAL( MethodInfo("idle_frame"));
+ ADD_SIGNAL( MethodInfo("fixed_frame"));
+
BIND_CONSTANT( GROUP_CALL_DEFAULT );
BIND_CONSTANT( GROUP_CALL_REVERSE );
BIND_CONSTANT( GROUP_CALL_REALTIME );
@@ -1052,10 +1665,23 @@ void SceneTree::_bind_methods() {
}
+SceneTree *SceneTree::singleton=NULL;
+
SceneTree::SceneTree() {
+ singleton=this;
_quit=false;
initialized=false;
+ editor_hint=false;
+ debug_collisions_hint=false;
+ debug_navigation_hint=false;
+ debug_collisions_color=GLOBAL_DEF("debug/collision_shape_color",Color(0.0,0.6,0.7,0.5));
+ debug_collision_contact_color=GLOBAL_DEF("debug/collision_contact_color",Color(1.0,0.2,0.1,0.8));
+ debug_navigation_color=GLOBAL_DEF("debug/navigation_geometry_color",Color(0.1,1.0,0.7,0.4));
+ debug_navigation_disabled_color=GLOBAL_DEF("debug/navigation_disabled_geometry_color",Color(1.0,0.7,0.1,0.4));
+ collision_debug_contacts=GLOBAL_DEF("debug/collision_max_contacts_displayed",10000);
+
+
tree_version=1;
fixed_process_time=1;
idle_process_time=1;
@@ -1077,6 +1703,7 @@ SceneTree::SceneTree() {
//root->set_world_2d( Ref<World2D>( memnew( World2D )));
root->set_as_audio_listener(true);
root->set_as_audio_listener_2d(true);
+ current_scene=NULL;
stretch_mode=STRETCH_MODE_DISABLED;
stretch_aspect=STRETCH_ASPECT_IGNORE;
@@ -1094,8 +1721,36 @@ SceneTree::SceneTree() {
edited_scene_root=NULL;
#endif
- ADD_SIGNAL( MethodInfo("idle_frame"));
- ADD_SIGNAL( MethodInfo("fixed_frame"));
+#ifdef DEBUG_ENABLED
+
+
+ live_edit_funcs.udata=this;
+ live_edit_funcs.node_path_func=_live_edit_node_path_funcs;
+ live_edit_funcs.res_path_func=_live_edit_res_path_funcs;
+ live_edit_funcs.node_set_func=_live_edit_node_set_funcs;
+ live_edit_funcs.node_set_res_func=_live_edit_node_set_res_funcs;
+ live_edit_funcs.node_call_func=_live_edit_node_call_funcs;
+ live_edit_funcs.res_set_func=_live_edit_res_set_funcs;
+ live_edit_funcs.res_set_res_func=_live_edit_res_set_res_funcs;
+ live_edit_funcs.res_call_func=_live_edit_res_call_funcs;
+ live_edit_funcs.root_func=_live_edit_root_funcs;
+
+ live_edit_funcs.tree_create_node_func=_live_edit_create_node_funcs;
+ live_edit_funcs.tree_instance_node_func=_live_edit_instance_node_funcs;
+ live_edit_funcs.tree_remove_node_func=_live_edit_remove_node_funcs;
+ live_edit_funcs.tree_remove_and_keep_node_func=_live_edit_remove_and_keep_node_funcs;
+ live_edit_funcs.tree_restore_node_func=_live_edit_restore_node_funcs;
+ live_edit_funcs.tree_duplicate_node_func=_live_edit_duplicate_node_funcs;
+ live_edit_funcs.tree_reparent_node_func=_live_edit_reparent_node_funcs;
+
+ if (ScriptDebugger::get_singleton()) {
+ ScriptDebugger::get_singleton()->set_live_edit_funcs(&live_edit_funcs);
+ }
+
+ live_edit_root=NodePath("/root");
+
+#endif
+
}