From b6b346e8aeaa4b31f4a89b0711e48a08fa802cf5 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Sun, 17 May 2015 16:33:35 -0300 Subject: [PATCH] added a built-in scene changer API, closes #1928 --- demos/misc/scene_changer/engine.cfg | 4 ++ demos/misc/scene_changer/scene_a.gd | 17 ++++++ demos/misc/scene_changer/scene_a.scn | Bin 0 -> 1459 bytes demos/misc/scene_changer/scene_b.gd | 17 ++++++ demos/misc/scene_changer/scene_b.scn | Bin 0 -> 1448 bytes main/main.cpp | 3 +- scene/main/scene_main_loop.cpp | 76 ++++++++++++++++++++++++++- scene/main/scene_main_loop.h | 15 +++++- 8 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 demos/misc/scene_changer/engine.cfg create mode 100644 demos/misc/scene_changer/scene_a.gd create mode 100644 demos/misc/scene_changer/scene_a.scn create mode 100644 demos/misc/scene_changer/scene_b.gd create mode 100644 demos/misc/scene_changer/scene_b.scn diff --git a/demos/misc/scene_changer/engine.cfg b/demos/misc/scene_changer/engine.cfg new file mode 100644 index 00000000000..1ba1a411671 --- /dev/null +++ b/demos/misc/scene_changer/engine.cfg @@ -0,0 +1,4 @@ +[application] + +name="Scene Changer" +main_scene="res://scene_a.scn" diff --git a/demos/misc/scene_changer/scene_a.gd b/demos/misc/scene_changer/scene_a.gd new file mode 100644 index 00000000000..956878b0f74 --- /dev/null +++ b/demos/misc/scene_changer/scene_a.gd @@ -0,0 +1,17 @@ + +extends Panel + +# member variables here, example: +# var a=2 +# var b="textvar" + +func _ready(): + # Initalization here + pass + + + + +func _on_goto_scene_pressed(): + get_tree().change_scene("res://scene_b.scn") + pass # replace with function body diff --git a/demos/misc/scene_changer/scene_a.scn b/demos/misc/scene_changer/scene_a.scn new file mode 100644 index 0000000000000000000000000000000000000000..61727a57bab5c55780ce11b2a3ae377dbf537b17 GIT binary patch literal 1459 zcmXw3Yitx%6h5=FyVLIW1$5ayD81WmTfx90Eir*u&de^fJmk?L2-M8X&feWlI-S|f z%(kUK+y;zBNDP=*U*ICf8bkck#7IKoQcc7JB0-6XL>yx^1pkPE2nNy14^Q%)lXK3! zIggxt1B1yVJeE3uH^Kn#1OPYykK;fqg`kQEp&hC=LNkLJH7Tj~)&TfPFK~qCpoZ`@ zHg&9mt6f!ABaPiSQsW1Q>#Z$5(w0w2?|^XMP3YOD`xb z!5yke4Om1Xp)uXj)4HL%2NFt%GpHvl=B>P{k)<3oc!3puhZ-43XaSc&<5#PUoc_NtPAyCr~wCIu@{OK zhal>O8cP&!DYPb`=S<6{@~BmCC@d&H#U&iFuT+mp$k8XMoHf*(lOPv@`lMyLs-c|p ze2xAwYP)*uGzX1jqvwlOIj&7zZCJKdSGSZuryj&^N`m^ZQkF-ltI9Hj$vS_|axGas zrC#KuLaY%?^;Te1wR5^TRfo$;wd9<-zf@CvB)w9qE8UYQpV1vP_AO+TZGP9vT{__^6`Zb-BhuDb5Zv@JvVzOYN~r2~2X%^EFAgaSh(698+yw zHC+dml5O}1m*DQ?yX^jo>v<^Fir313?FiV6Vd*+{x8E=E! z)GkkGfONTGp4%138CF^~%2C|OtxhS&F@(p(Vr5>RpoZ+2YF;_UT4_R_o3z?L6nFCd z&;Q(ubr|+pStq?nxFBAid-l%k9GiGMbQkyGPq+|yeln}tN;ePical9`@5@?aioo0+ z2^Xb)502?{Ja5@&zQGQ0wKRe;@x8Xo;KqA_Dogm;Wib&OkoYHL+j5l%f1~#6&&v@w z;6cRK-94*Bq`U3+K_=8cY~?Jo{en2jn(PsKaH&AeG2OPzQSr3Lx8m!*yya+HJRZFI z8CJiDIOGLp5XupcV+JGMKQrE&Gvddo@wxMzV#nU3klI;p5i&HZ77SPJSk>i|wwGI^ zdlk;GH7@6DJ>&Ts`+ij#I}gW)Jb$y)@0&E~+2{BxmoGnqdg`lrILX2^L2Y$__)QmqsGVi;ST*>;4 zOGN?dN&**37HdJ#?u)&FK8v^((Wf~gDVNyKt$2GQFlr!VA*2~K{96K1V)2>{e!Pir z@epe4o;I+^CT35gkUE1;;w=!0gC zfM><0*%-hQ>lg&wj<6|=(;Gj*>He!YE&hPh>|ob12>-)toyB8#F!d=4&`b_7y@Uvu xgchd%>f4P`XeG6*`jPS%ILjjEr%qutUP0JA1~F0*_Az#TECYiB$pJ>!{{douys!WO literal 0 HcmV?d00001 diff --git a/demos/misc/scene_changer/scene_b.gd b/demos/misc/scene_changer/scene_b.gd new file mode 100644 index 00000000000..4f94d6bb8f6 --- /dev/null +++ b/demos/misc/scene_changer/scene_b.gd @@ -0,0 +1,17 @@ + +extends Panel + +# member variables here, example: +# var a=2 +# var b="textvar" + +func _ready(): + # Initalization here + pass + + + + +func _on_goto_scene_pressed(): + get_tree().change_scene("res://scene_a.scn") + pass # replace with function body diff --git a/demos/misc/scene_changer/scene_b.scn b/demos/misc/scene_changer/scene_b.scn new file mode 100644 index 0000000000000000000000000000000000000000..ae09eeff88389528d5fe1b014bb978668ac788c0 GIT binary patch literal 1448 zcmXw3Yitx%6h5=FyVLIW#ben%XnUtG1OuxSVu0A5ncdP_5J;;KDLOMdd%K-5omppQ z+fq=rLB&WkiiuStWD$}oA>l`jVnX6l{ecN2hDVHoWQfEx#2=y|z7W0q@Fd?kIp^G) z^T^3JFqllj1E~RcF$(Zz2!I3dIS%w<1S*IS*{12cX=YHT7A2MbT7V$w0*>$;R1v<) zp{|{GbegcVQ3~Z`fuN-GR>q_mwJGfCj*;^cg|NC7TLQhQK{d`n4M`A*Tc02zd7oF( zt5&FO5FzoPY3rIv>H?3z52O;o7tZ5L5FoWsPk0a*LJVQT<7)vIT1YvxGQW)Q#b?#V z@HWk&CM+Vc$e7_8X~Q(UJqb0!nba4S@ODnqNfQUPerRRTrRK0wYJi1)s6ntT#j|rz zNn%mW(noA3;TYKwPpd4}2x;5%>`{o37Gc=d^RB`c&;n_(H=Ho(um_9%NG%S+5PS7}wk$Xd2Tl~FtIQdm%WluNi|XK^vA5!aZc%CMrzJAlI@V-1K_hqZ6K5#u+*}Aa54K;H3|dm0V6yn`MR5OtD{c5q)m1 zu!-bkN8Lf9*o)QTYR)yt4&cc?`3%PKTe3TBDY~7vJin|SEON>Z)XTSVEnX`h(;P#y zJQteC7QBy3aeMLuc7KI#9tzdcr4nE(0ybb&zKWf=?Z?H3lPa#k7o?6vkS^8Y$K2|a>R|*uX{0=7Oi)vCEiI=GvHJDMbCY)K8`3(y{L1UyScB1kJ?v_K z3umRPb5GuxonvEeh0elGJdF#H=O>3XNA2VR{z|gP-GO0yOcj{BM#e>{%i%GDj^}LW z*k{--)ysn@N(Wm$0k5qCsJfJ&T`o#kizGOqIJT$8_-oZ)e^H9T9v@LYrObWavAkVM3aNFaMj=CowY=#m?X?}Z<*lVg`EHpzVvj3X$H@4> zy55UwT?cJT`N0OcFEDA*<4^M!FI;#WjnwH|Fv&Ujw($`4Jj2R89uXY`!XGr zj?~N7@gTp_ByE|L+MXQ6ln>vqM!IfQ+zjdtrB>TbB)0k z(*KaULcKQeY+~%^h@_rpKR4s;o_WRxge-(K zz^w>EC<1Fb>V6 mnpHng`VwbZoXlika3DFrIQlget_root()->add_child(scene); + //sml->get_root()->add_child(scene); + sml->add_current_scene(scene); String iconpath = GLOBAL_DEF("application/icon","Variant()"""); if (iconpath!="") { diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index 9f2fadcb4d0..4113fd1998d 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -41,7 +41,7 @@ #include "scene/scene_string_names.h" #include "io/resource_loader.h" #include "viewport.h" - +#include "scene/resources/packed_scene.h" void SceneTree::tree_changed() { @@ -51,6 +51,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); @@ -984,6 +987,63 @@ 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 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& 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); +} void SceneTree::_bind_methods() { @@ -1016,10 +1076,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,6 +1094,16 @@ 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"),&SceneTree::set_current_scene); + ObjectTypeDB::bind_method(_MD("get_current_scene"),&SceneTree::get_current_scene); + + ObjectTypeDB::bind_method(_MD("change_scene","path"),&SceneTree::change_scene); + ObjectTypeDB::bind_method(_MD("change_scene_to","packed_scene"),&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") ); @@ -1077,6 +1148,7 @@ SceneTree::SceneTree() { //root->set_world_2d( Ref( 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; diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index fec4dd39083..e49c150fbf6 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -42,7 +42,7 @@ class SceneTree; - +class PackedScene; class Node; class Viewport; @@ -136,7 +136,9 @@ private: Array _get_nodes_in_group(const StringName& p_group); + Node *current_scene; + void _change_scene(Node* p_to); //void _call_group(uint32_t p_call_flags,const StringName& p_group,const StringName& p_function,const Variant& p_arg1,const Variant& p_arg2); friend class Node; @@ -234,6 +236,17 @@ public: Node *get_edited_scene_root() const; #endif + void set_current_scene(Node* p_scene); + Node* get_current_scene() const; + Error change_scene(const String& p_path); + Error change_scene_to(const Ref& p_scene); + Error reload_current_scene(); + + //used by Main::start, don't use otherwise + void add_current_scene(Node * p_current); + + + SceneTree(); ~SceneTree();