-fixes and more fixes to new scene system, seems stable now..
BUT DONT TRUST ME IT MAY STILL BREAK, USE WITH CARE!!
This commit is contained in:
parent
6b20ee4324
commit
078a474135
|
@ -0,0 +1,74 @@
|
|||
#include "instance_placeholder.h"
|
||||
|
||||
#include "scene/resources/packed_scene.h"
|
||||
#include "io/resource_loader.h"
|
||||
|
||||
bool InstancePlaceholder::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
PropSet ps;
|
||||
ps.name=p_name;
|
||||
ps.value=p_value;
|
||||
stored_values.push_back(ps);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InstancePlaceholder::_get(const StringName& p_name,Variant &r_ret) const{
|
||||
|
||||
return false;
|
||||
}
|
||||
void InstancePlaceholder::_get_property_list( List<PropertyInfo> *p_list) const{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void InstancePlaceholder::set_path(const String& p_name) {
|
||||
|
||||
path=p_name;
|
||||
}
|
||||
|
||||
String InstancePlaceholder::get_path() const {
|
||||
|
||||
return path;
|
||||
}
|
||||
void InstancePlaceholder::replace_by_instance(const Ref<PackedScene> &p_custom_scene){
|
||||
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
|
||||
Node *base = get_parent();
|
||||
if (!base)
|
||||
return;
|
||||
|
||||
Ref<PackedScene> ps;
|
||||
if (p_custom_scene.is_valid())
|
||||
ps = p_custom_scene;
|
||||
else
|
||||
ps = ResourceLoader::load(path,"PackedScene");
|
||||
|
||||
if (!ps.is_valid())
|
||||
return;
|
||||
Node *scene = ps->instance();
|
||||
scene->set_name(get_name());
|
||||
int pos = get_position_in_parent();
|
||||
|
||||
for(List<PropSet>::Element *E=stored_values.front();E;E=E->next()) {
|
||||
scene->set(E->get().name,E->get().value);
|
||||
}
|
||||
|
||||
queue_delete();
|
||||
|
||||
base->remove_child(this);
|
||||
base->add_child(scene);
|
||||
base->move_child(scene,pos);
|
||||
|
||||
}
|
||||
|
||||
void InstancePlaceholder::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("replace_by_instance","custom_scene:PackedScene"),&InstancePlaceholder::replace_by_instance,DEFVAL(Variant()));
|
||||
}
|
||||
|
||||
InstancePlaceholder::InstancePlaceholder() {
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef INSTANCE_PLACEHOLDER_H
|
||||
#define INSTANCE_PLACEHOLDER_H
|
||||
|
||||
#include "scene/main/node.h"
|
||||
|
||||
class PackedScene;
|
||||
|
||||
class InstancePlaceholder : public Node {
|
||||
|
||||
OBJ_TYPE(InstancePlaceholder,Node);
|
||||
|
||||
String path;
|
||||
struct PropSet {
|
||||
StringName name;
|
||||
Variant value;
|
||||
};
|
||||
|
||||
List<PropSet> stored_values;
|
||||
|
||||
protected:
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
void _get_property_list( List<PropertyInfo> *p_list) const;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void set_path(const String& p_name);
|
||||
String get_path() const;
|
||||
|
||||
void replace_by_instance(const Ref<PackedScene>& p_custom_scene=Ref<PackedScene>());
|
||||
|
||||
InstancePlaceholder();
|
||||
};
|
||||
|
||||
#endif // INSTANCE_PLACEHOLDER_H
|
|
@ -1052,6 +1052,7 @@ void Node::get_owned_by(Node *p_by,List<Node*> *p_owned) {
|
|||
|
||||
void Node::_set_owner_nocheck(Node* p_owner) {
|
||||
|
||||
ERR_FAIL_COND(data.owner);
|
||||
data.owner=p_owner;
|
||||
data.owner->data.owned.push_back( this );
|
||||
data.OW = data.owner->data.owned.back();
|
||||
|
@ -1443,13 +1444,14 @@ Ref<SceneState> Node::get_scene_inherited_state() const{
|
|||
return data.inherited_state;
|
||||
}
|
||||
|
||||
Vector<StringName> Node::get_instance_groups() const {
|
||||
void Node::set_scene_instance_load_placeholder(bool p_enable) {
|
||||
|
||||
return data.instance_groups;
|
||||
data.use_placeholder=p_enable;
|
||||
}
|
||||
Vector<Node::Connection> Node::get_instance_connections() const{
|
||||
|
||||
return data.instance_connections;
|
||||
bool Node::get_scene_instance_load_placeholder() const{
|
||||
|
||||
return data.use_placeholder;
|
||||
}
|
||||
|
||||
int Node::get_position_in_parent() const {
|
||||
|
@ -2109,6 +2111,7 @@ Node::Node() {
|
|||
data.parent_owned=false;
|
||||
data.in_constructor=true;
|
||||
data.viewport=NULL;
|
||||
data.use_placeholder=false;
|
||||
}
|
||||
|
||||
Node::~Node() {
|
||||
|
@ -2125,3 +2128,4 @@ Node::~Node() {
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
|
|
|
@ -75,9 +75,6 @@ private:
|
|||
|
||||
HashMap<NodePath,int> editable_instances;
|
||||
|
||||
Vector<StringName> instance_groups;
|
||||
Vector<Connection> instance_connections;
|
||||
|
||||
Node *parent;
|
||||
Node *owner;
|
||||
Vector<Node*> children; // list of children
|
||||
|
@ -111,6 +108,8 @@ private:
|
|||
|
||||
bool parent_owned;
|
||||
bool in_constructor;
|
||||
bool use_placeholder;
|
||||
|
||||
|
||||
} data;
|
||||
|
||||
|
@ -241,6 +240,7 @@ public:
|
|||
void set_editable_instance(Node* p_node,bool p_editable);
|
||||
bool is_editable_instance(Node* p_node) const;
|
||||
|
||||
|
||||
/* NOTIFICATIONS */
|
||||
|
||||
void propagate_notification(int p_notification);
|
||||
|
@ -278,8 +278,8 @@ public:
|
|||
void set_scene_inherited_state(const Ref<SceneState>& p_state);
|
||||
Ref<SceneState> get_scene_inherited_state() const;
|
||||
|
||||
Vector<StringName> get_instance_groups() const;
|
||||
Vector<Connection> get_instance_connections() const;
|
||||
void set_scene_instance_load_placeholder(bool p_enable);
|
||||
bool get_scene_instance_load_placeholder() const;
|
||||
|
||||
static Vector<Variant> make_binds(VARIANT_ARG_LIST);
|
||||
|
||||
|
@ -322,6 +322,4 @@ public:
|
|||
typedef Set<Node*,Node::Comparator> NodeSet;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "resources/default_theme/default_theme.h"
|
||||
#include "object_type_db.h"
|
||||
#include "scene/main/canvas_layer.h"
|
||||
#include "scene/main/instance_placeholder.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/gui/texture_progress.h"
|
||||
|
@ -269,6 +270,7 @@ void register_scene_types() {
|
|||
ObjectTypeDB::register_type<Object>();
|
||||
|
||||
ObjectTypeDB::register_type<Node>();
|
||||
ObjectTypeDB::register_virtual_type<InstancePlaceholder>();
|
||||
|
||||
ObjectTypeDB::register_type<Viewport>();
|
||||
ObjectTypeDB::register_virtual_type<RenderTargetTexture>();
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "scene/3d/spatial.h"
|
||||
#include "scene/gui/control.h"
|
||||
#include "scene/2d/node_2d.h"
|
||||
#include "scene/main/instance_placeholder.h"
|
||||
|
||||
#define PACK_VERSION 2
|
||||
|
||||
|
@ -100,6 +101,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
|
|||
|
||||
if (i==0 && base_scene_idx>=0) {
|
||||
//scene inheritance on root node
|
||||
print_line("scene inherit");
|
||||
Ref<PackedScene> sdata = props[ base_scene_idx ];
|
||||
ERR_FAIL_COND_V( !sdata.is_valid(), NULL);
|
||||
node = sdata->instance(p_gen_edit_state);
|
||||
|
@ -110,12 +112,32 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
|
|||
|
||||
} else if (n.instance>=0) {
|
||||
//instance a scene into this node
|
||||
Ref<PackedScene> sdata = props[ n.instance ];
|
||||
ERR_FAIL_COND_V( !sdata.is_valid(), NULL);
|
||||
node = sdata->instance(p_gen_edit_state);
|
||||
ERR_FAIL_COND_V(!node,NULL);
|
||||
print_line("instance");
|
||||
if (n.instance&FLAG_INSTANCE_IS_PLACEHOLDER) {
|
||||
|
||||
String path = props[n.instance&FLAG_MASK];
|
||||
if (disable_placeholders) {
|
||||
|
||||
Ref<PackedScene> sdata = ResourceLoader::load(path,"PackedScene");
|
||||
ERR_FAIL_COND_V( !sdata.is_valid(), NULL);
|
||||
node = sdata->instance(p_gen_edit_state);
|
||||
ERR_FAIL_COND_V(!node,NULL);
|
||||
} else {
|
||||
InstancePlaceholder *ip = memnew( InstancePlaceholder );
|
||||
ip->set_path(path);
|
||||
node=ip;
|
||||
}
|
||||
node->set_scene_instance_load_placeholder(true);
|
||||
} else {
|
||||
Ref<PackedScene> sdata = props[ n.instance&FLAG_MASK ];
|
||||
ERR_FAIL_COND_V( !sdata.is_valid(), NULL);
|
||||
node = sdata->instance(p_gen_edit_state);
|
||||
ERR_FAIL_COND_V(!node,NULL);
|
||||
|
||||
}
|
||||
|
||||
} else if (n.type==TYPE_INSTANCED) {
|
||||
//print_line("instanced");
|
||||
//get the node from somewhere, it likely already exists from another instance
|
||||
if (parent) {
|
||||
node=parent->_get_child_by_name(snames[n.name]);
|
||||
|
@ -126,6 +148,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
|
|||
#endif
|
||||
}
|
||||
} else if (ObjectTypeDB::is_type_enabled(snames[n.type])) {
|
||||
print_line("created");
|
||||
//node belongs to this scene and must be created
|
||||
Object * obj = ObjectTypeDB::instance(snames[ n.type ]);
|
||||
if (!obj || !obj->cast_to<Node>()) {
|
||||
|
@ -339,13 +362,20 @@ Error SceneState::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map<S
|
|||
}
|
||||
|
||||
if (p_node->get_filename()!=String() && p_node->get_owner()==p_owner && instanced_by_owner) {
|
||||
//must instance ourselves
|
||||
Ref<PackedScene> instance = ResourceLoader::load(p_node->get_filename());
|
||||
if (!instance.is_valid()) {
|
||||
return ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
nd.instance=_vm_get_variant(instance,variant_map);
|
||||
if (p_node->get_scene_instance_load_placeholder()) {
|
||||
//it's a placeholder, use the placeholder path
|
||||
nd.instance=_vm_get_variant(p_node->get_filename(),variant_map);
|
||||
nd.instance|=FLAG_INSTANCE_IS_PLACEHOLDER;
|
||||
} else {
|
||||
//must instance ourselves
|
||||
Ref<PackedScene> instance = ResourceLoader::load(p_node->get_filename());
|
||||
if (!instance.is_valid()) {
|
||||
return ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
nd.instance=_vm_get_variant(instance,variant_map);
|
||||
}
|
||||
}
|
||||
n=NULL;
|
||||
} else {
|
||||
|
@ -971,6 +1001,13 @@ bool SceneState::is_node_in_group(int p_node,const StringName& p_group) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool SceneState::disable_placeholders=false;
|
||||
|
||||
void SceneState::set_disable_placeholders(bool p_disable) {
|
||||
|
||||
disable_placeholders=p_disable;
|
||||
}
|
||||
|
||||
bool SceneState::is_connection(int p_node,const StringName& p_signal,int p_to_node,const StringName& p_to_method) const {
|
||||
|
||||
ERR_FAIL_COND_V(p_node<0,false);
|
||||
|
|
|
@ -45,13 +45,9 @@ class SceneState : public Reference {
|
|||
|
||||
int base_scene_idx;
|
||||
|
||||
//missing - instances
|
||||
//missing groups
|
||||
//missing - owner
|
||||
//missing - override names and values
|
||||
|
||||
enum {
|
||||
FLAG_ID_IS_PATH=(1<<30),
|
||||
FLAG_INSTANCE_IS_PLACEHOLDER=(1<<30),
|
||||
FLAG_MASK=(1<<24)-1,
|
||||
NO_PARENT_SAVED=0x7FFFFFFF,
|
||||
TYPE_INSTANCED=0x7FFFFFFF,
|
||||
|
@ -105,8 +101,11 @@ class SceneState : public Reference {
|
|||
|
||||
_FORCE_INLINE_ Ref<SceneState> _get_base_scene_state() const;
|
||||
|
||||
static bool disable_placeholders;
|
||||
public:
|
||||
|
||||
static void set_disable_placeholders(bool p_disable);
|
||||
|
||||
int find_node_by_path(const NodePath& p_node) const;
|
||||
Variant get_property_value(int p_node,const StringName& p_property,bool &found) const;
|
||||
bool is_node_in_group(int p_node,const StringName& p_group) const;
|
||||
|
|
|
@ -4417,6 +4417,7 @@ void EditorNode::_scene_tab_changed(int p_tab) {
|
|||
EditorNode::EditorNode() {
|
||||
|
||||
EditorHelp::generate_doc(); //before any editor classes are crated
|
||||
SceneState::set_disable_placeholders(true);
|
||||
|
||||
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
|
||||
|
||||
|
|
|
@ -67,6 +67,26 @@ void SceneTreeEditor::_subscene_option(int p_idx) {
|
|||
//node->set_instance_children_editable(editable);
|
||||
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,editable);
|
||||
instance_menu->set_item_checked(0,editable);
|
||||
if (editable) {
|
||||
node->set_scene_instance_load_placeholder(false);
|
||||
instance_menu->set_item_checked(1,false);
|
||||
}
|
||||
|
||||
_update_tree();
|
||||
|
||||
} break;
|
||||
case SCENE_MENU_USE_PLACEHOLDER: {
|
||||
|
||||
bool placeholder = node->get_scene_instance_load_placeholder();
|
||||
placeholder = !placeholder;
|
||||
|
||||
//node->set_instance_children_editable(editable);
|
||||
if (placeholder) {
|
||||
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node,false);
|
||||
}
|
||||
node->set_scene_instance_load_placeholder(placeholder);
|
||||
instance_menu->set_item_checked(0,false);
|
||||
instance_menu->set_item_checked(1,placeholder);
|
||||
|
||||
_update_tree();
|
||||
|
||||
|
@ -127,6 +147,15 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id)
|
|||
else
|
||||
instance_menu->set_item_checked(0,false);
|
||||
|
||||
if (n->get_owner()==get_scene_node()) {
|
||||
instance_menu->set_item_checked(1,n->get_scene_instance_load_placeholder());
|
||||
instance_menu->set_item_disabled(1,false);
|
||||
} else {
|
||||
|
||||
instance_menu->set_item_checked(1,false);
|
||||
instance_menu->set_item_disabled(1,true);
|
||||
}
|
||||
|
||||
instance_menu->popup();
|
||||
instance_node=n->get_instance_ID();
|
||||
}
|
||||
|
@ -520,7 +549,7 @@ void SceneTreeEditor::_notification(int p_what) {
|
|||
|
||||
get_tree()->connect("tree_changed",this,"_tree_changed");
|
||||
get_tree()->connect("node_removed",this,"_node_removed");
|
||||
instance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
|
||||
instance_menu->set_item_icon(3,get_icon("Load","EditorIcons"));
|
||||
tree->connect("item_collapsed",this,"_cell_collapsed");
|
||||
inheritance_menu->set_item_icon(2,get_icon("Load","EditorIcons"));
|
||||
clear_inherit_confirm->connect("confirmed",this,"_subscene_option",varray(SCENE_MENU_CLEAR_INHERITANCE_CONFIRM));
|
||||
|
@ -826,6 +855,7 @@ SceneTreeEditor::SceneTreeEditor(bool p_label,bool p_can_rename, bool p_can_open
|
|||
|
||||
instance_menu = memnew( PopupMenu );
|
||||
instance_menu->add_check_item("Editable Children",SCENE_MENU_EDITABLE_CHILDREN);
|
||||
instance_menu->add_check_item("Load As Placeholder",SCENE_MENU_USE_PLACEHOLDER);
|
||||
instance_menu->add_separator();
|
||||
instance_menu->add_item("Open in Editor",SCENE_MENU_OPEN);
|
||||
instance_menu->connect("item_pressed",this,"_subscene_option");
|
||||
|
|
|
@ -53,6 +53,7 @@ class SceneTreeEditor : public Control {
|
|||
|
||||
enum {
|
||||
SCENE_MENU_EDITABLE_CHILDREN,
|
||||
SCENE_MENU_USE_PLACEHOLDER,
|
||||
SCENE_MENU_OPEN,
|
||||
SCENE_MENU_CLEAR_INHERITANCE,
|
||||
SCENE_MENU_OPEN_INHERITED,
|
||||
|
|
Loading…
Reference in New Issue