Skip to content

Commit

Permalink
TypeDB and GDScript 'Scripts' global added.
Browse files Browse the repository at this point in the history
  • Loading branch information
willnationsdev committed Jun 28, 2018
1 parent 25275de commit 1b53ceb
Show file tree
Hide file tree
Showing 40 changed files with 1,853 additions and 222 deletions.
13 changes: 13 additions & 0 deletions core/script_language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ bool ScriptServer::scripting_enabled = true;
bool ScriptServer::reload_scripts_on_save = false;
ScriptEditRequestFunction ScriptServer::edit_request_func = NULL;

Dictionary Script::get_script_metadata() {
if (has_method("_get_script_metadata")) {
Variant::CallError ce;
Variant ret = call("_get_script_metadata", NULL, 0, ce);
if (ce.error = Variant::CallError::CALL_OK) {
return (Dictionary)ret;
}
}
return Dictionary();
}

void Script::_notification(int p_what) {

if (p_what == NOTIFICATION_POSTINITIALIZE) {
Expand All @@ -62,6 +73,8 @@ void Script::_bind_methods() {

ClassDB::bind_method(D_METHOD("is_tool"), &Script::is_tool);

ClassDB::add_virtual_method(get_class_static(), MethodInfo("_get_script_metadata"));

ADD_PROPERTY(PropertyInfo(Variant::STRING, "source_code", PROPERTY_HINT_NONE, "", 0), "set_source_code", "get_source_code");
}

Expand Down
4 changes: 3 additions & 1 deletion core/script_language.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,15 @@ class Script : public Resource {

virtual void update_exports() {} //editor tool
virtual void get_script_method_list(List<MethodInfo> *p_list) const = 0;
virtual void get_script_property_list(List<PropertyInfo> *p_list) const = 0;
virtual void get_script_property_list(List<PropertyInfo> *p_list, bool p_no_inherited = false) const = 0;

virtual int get_member_line(const StringName &p_member) const { return -1; }

virtual void get_constants(Map<StringName, Variant> *p_constants) {}
virtual void get_members(Set<StringName> *p_constants) {}

virtual Dictionary get_script_metadata();

Script() {}
};

Expand Down
17 changes: 17 additions & 0 deletions core/ustring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,23 @@ String String::camelcase_to_underscore(bool lowercase) const {
return lowercase ? new_string.to_lower() : new_string;
}

String String::typenamify() const {
String name = get_file().get_basename().strip_edges();
String result;

for (int i = 0; i < name.length() && name[i] == '_'; i++) {
result += '_';
}

result += name.capitalize().replace("_", "").replace(" ", "");

for (int i = name.length() - 1; i > 0 && name[i] == '_'; i++) {
result += '_';
}

return result;
}

int String::get_slice_count(String p_splitter) const {

if (empty())
Expand Down
1 change: 1 addition & 0 deletions core/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ class String : public Vector<CharType> {
static int64_t to_int(const CharType *p_str, int p_len = -1);
String capitalize() const;
String camelcase_to_underscore(bool lowercase = true) const;
String typenamify() const;

int get_slice_count(String p_splitter) const;
String get_slice(String p_splitter, int p_slice) const;
Expand Down
172 changes: 113 additions & 59 deletions editor/create_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) {

update_types();

recent->clear();

FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::READ);
Expand All @@ -53,6 +55,9 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) {

if (l != String()) {

if (!ClassDB::class_exists(l) && !EditorNode::get_singleton()->get_editor_data().get_type_db().class_exists(l)) {
continue;
}
TreeItem *ti = recent->create_item(root);
ti->set_text(0, l);
ti->set_icon(0, _get_editor_icon(l));
Expand All @@ -74,6 +79,9 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode) {
String l = f->get_line().strip_edges();

if (l != String()) {
if (!ClassDB::class_exists(l) && !EditorNode::get_singleton()->get_editor_data().get_type_db().class_exists(l)) {
continue;
}
favorite_list.push_back(l);
}
}
Expand Down Expand Up @@ -133,6 +141,13 @@ void CreateDialog::_text_changed(const String &p_newtext) {
_update_search();
}

void CreateDialog::update_types() {
type_list.clear();
ClassDB::get_class_list(&type_list);
EditorNode::get_singleton()->get_editor_data().get_type_db().get_class_list(&type_list);
type_list.sort_custom<StringName::AlphCompare>();
}

void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {

Ref<InputEventKey> k = p_ie;
Expand All @@ -152,31 +167,32 @@ Ref<Texture> CreateDialog::_get_editor_icon(const String &p_type) const {
return get_icon(p_type, "EditorIcons");
}

const Map<String, Vector<EditorData::CustomType> > &p_map = EditorNode::get_editor_data().get_custom_types();
for (const Map<String, Vector<EditorData::CustomType> >::Element *E = p_map.front(); E; E = E->next()) {
const Vector<EditorData::CustomType> &ct = E->value();
for (int i = 0; i < ct.size(); ++i) {
if (ct[i].name == p_type) {
if (ct[i].icon.is_valid()) {
return ct[i].icon;
} else {
return get_icon("Object", "EditorIcons");
}
}
}
EditorData::TypeDbTypes db_type = (EditorData::TypeDbTypes)(EditorData::TYPEDB_TYPE_SCRIPT | EditorData::TYPEDB_TYPE_SCENE);
if (EditorNode::get_editor_data().get_type_db().class_exists(p_type, db_type)) {
const EditorData::TypeInfo *ti = EditorNode::get_editor_data().get_type_db().get_type_info(p_type, db_type);
Ref<Texture> icon = ti->icon;
if (icon.is_valid())
return icon;
if (has_icon(ti->base, "EditorIcons"))
return get_icon(ti->base, "EditorIcons");
}

return get_icon("Object", "EditorIcons");
}

void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select) {

EditorData::TypeDB &tdb = EditorNode::get_editor_data().get_type_db();

if (p_types.has(p_type))
return;
if (!ClassDB::is_parent_class(p_type, base_type) || p_type == base_type)
if (p_type == base_type)
return;
if (ClassDB::class_exists(p_type) ? !ClassDB::is_parent_class(p_type, base_type) : !tdb.is_parent_class(p_type, base_type)) {
return;
}

String inherits = ClassDB::get_parent_class(p_type);
String inherits = ClassDB::class_exists(p_type) ? ClassDB::get_parent_class(p_type) : tdb.get_parent_class(p_type);

TreeItem *parent = p_root;

Expand All @@ -191,20 +207,29 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
parent = p_types[inherits];
}

String type_text = p_type;

TreeItem *item = search_options->create_item(parent);
item->set_text(0, p_type);
if (!ClassDB::can_instance(p_type)) {
item->set_text(0, type_text);
if (tdb.is_custom(p_type, EditorData::TYPEDB_TYPE_ALL))
item->set_metadata(0, p_type);
if ((ClassDB::class_exists(p_type) && !ClassDB::can_instance(p_type)) || (tdb.class_exists(p_type) && !tdb.can_instance(p_type))) {
item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
item->set_selectable(0, false);
} else {
bool is_search_subsequence = search_box->get_text().is_subsequence_ofi(p_type);
String to_select_type = *to_select ? (*to_select)->get_text(0) : "";
bool current_item_is_preffered = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(to_select_type, preferred_search_result_type);
bool current_item_is_preferred;
if (tdb.class_exists(p_type)) {
current_item_is_preferred = tdb.is_parent_class(p_type, preferred_search_result_type) && !tdb.is_parent_class(to_select_type, preferred_search_result_type);
} else {
current_item_is_preferred = ClassDB::is_parent_class(p_type, preferred_search_result_type) && !ClassDB::is_parent_class(to_select_type, preferred_search_result_type);
}
if (*to_select && p_type.length() < (*to_select)->get_text(0).length()) {
current_item_is_preffered = true;
current_item_is_preferred = true;
}

if (((!*to_select || current_item_is_preffered) && is_search_subsequence) || search_box->get_text() == p_type) {
if (((!*to_select || current_item_is_preferred) && is_search_subsequence) || search_box->get_text() == p_type) {
*to_select = item;
}
}
Expand All @@ -217,18 +242,17 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
// don't collapse the root node
collapse &= (item != p_root);
// don't collapse abstract nodes on the first tree level
collapse &= ((parent != p_root) || (ClassDB::can_instance(p_type)));
collapse &= ((parent != p_root) || (tdb.can_instance(p_type)));
item->set_collapsed(collapse);
}

const String &description = EditorHelp::get_doc_data()->class_list[p_type].brief_description;
item->set_tooltip(0, description);

if (has_icon(p_type, "EditorIcons")) {

item->set_icon(0, get_icon(p_type, "EditorIcons"));
if (EditorHelp::get_doc_data()->class_list.has(p_type)) {
const String &description = EditorHelp::get_doc_data()->class_list[p_type].brief_description;
item->set_tooltip(0, description);
}

item->set_icon(0, _get_editor_icon(p_type));

p_types[p_type] = item;
}

Expand All @@ -244,6 +268,7 @@ void CreateDialog::_update_search() {
*/

HashMap<String, TreeItem *> types;
EditorData::TypeDB &tdb = EditorNode::get_singleton()->get_editor_data().get_type_db();

TreeItem *root = search_options->create_item();

Expand All @@ -259,68 +284,80 @@ void CreateDialog::_update_search() {

String type = I->get();

bool is_tdb_type = tdb.class_exists(type);

if (base_type == "Node" && type.begins_with("Editor"))
continue; // do not show editor nodes

if (base_type == "Resource" && ClassDB::is_parent_class(type, "PluginScript"))
if (base_type == "Resource" && ClassDB::class_exists(type) && ClassDB::is_parent_class(type, "PluginScript"))
// PluginScript must be initialized before use, which is not possible here
continue;

if (!ClassDB::can_instance(type))
if (is_tdb_type) {
if (!tdb.is_custom(type) || !tdb.can_instance(type))
continue;
} else if (!ClassDB::can_instance(type))
continue; // can't create what can't be instanced

if (search_box->get_text() == "") {
add_type(type, types, root, &to_select);
} else {

bool found = false;
String type = I->get();
while (type != "" && ClassDB::is_parent_class(type, base_type) && type != base_type) {
while (type != "" && type != base_type && (is_tdb_type && tdb.is_parent_class(type, base_type)) || (!is_tdb_type && ClassDB::is_parent_class(type, base_type))) {
if (search_box->get_text().is_subsequence_ofi(type)) {

found = true;
break;
}

type = ClassDB::get_parent_class(type);
String new_type = tdb.get_parent_class(type);
if (new_type.empty())
new_type = ClassDB::class_exists(type) ? ClassDB::get_parent_class(type) : "";
type = new_type;
}

if (found)
add_type(I->get(), types, root, &to_select);
}

if (EditorNode::get_editor_data().get_custom_types().has(type) && ClassDB::is_parent_class(type, base_type)) {
//there are custom types based on this... cool.
//if (EditorNode::get_editor_data().get_custom_type_db().class_exists(type) && ClassDB::is_parent_class(type, base_type)) {
// //there are custom types based on this... cool.

const Vector<EditorData::CustomType> &ct = EditorNode::get_editor_data().get_custom_types()[type];
for (int i = 0; i < ct.size(); i++) {
// const HashMap<StringName, EditorData::CustomType, StringNameHasher> *cts = &EditorNode::get_editor_data().get_custom_types();
// const EditorData::CustomType &ct = (*cts)[type];

bool show = search_box->get_text().is_subsequence_ofi(ct[i].name);
// for (int i = 0; i < ct.sub_types.size(); i++) {

if (!show)
continue;
// StringName sn = ct.sub_types[i];
// const EditorData::CustomType &sub = (*cts)[sn];

if (!types.has(type))
add_type(type, types, root, &to_select);
// bool show = search_box->get_text().is_subsequence_ofi(sub.name);

TreeItem *ti;
if (types.has(type))
ti = types[type];
else
ti = search_options->get_root();
// if (!show)
// continue;

TreeItem *item = search_options->create_item(ti);
item->set_metadata(0, type);
item->set_text(0, ct[i].name);
if (ct[i].icon.is_valid()) {
item->set_icon(0, ct[i].icon);
}
// if (!types.has(type))
// add_type(type, types, root, &to_select);

if (!to_select || ct[i].name == search_box->get_text()) {
to_select = item;
}
}
}
// TreeItem *ti;
// if (types.has(type))
// ti = types[type];
// else
// ti = search_options->get_root();

// TreeItem *item = search_options->create_item(ti);
// item->set_metadata(0, type);
// item->set_text(0, sub.name);
// if (sub.icon.is_valid()) {
// item->set_icon(0, sub.icon);
// }

// if (!to_select || sub.name == search_box->get_text()) {
// to_select = item;
// }
// }
//}
}

if (search_box->get_text() == "") {
Expand Down Expand Up @@ -440,7 +477,24 @@ Object *CreateDialog::instance_selected() {
custom = md;

if (custom != String()) {
return EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom);
const EditorData::TypeDB &tdb = EditorNode::get_editor_data().get_type_db();
EditorData::TypeDbTypes db_type = EditorData::TYPEDB_TYPE_SCRIPT;
if (tdb.class_exists(custom, db_type)) {

const EditorData::TypeInfo *ti = tdb.get_type_info(custom, db_type);
Object *ob = ClassDB::instance(ti->base);
ERR_FAIL_COND_V(!ob, NULL);

RES r(ResourceLoader::load(ti->path));
ob->set_script(r.get_ref_ptr());

if (ob->is_class("Node"))
ob->call("set_name", String(ti->type_name).get_file());
if (ti->icon.is_valid())
ob->set_meta("_editor_icon", ti->icon);

return ob;
}
} else {
return ClassDB::instance(selected->get_text(0));
}
Expand Down Expand Up @@ -629,6 +683,7 @@ void CreateDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_favorite_selected"), &CreateDialog::_favorite_selected);
ClassDB::bind_method(D_METHOD("_history_activated"), &CreateDialog::_history_activated);
ClassDB::bind_method(D_METHOD("_favorite_activated"), &CreateDialog::_favorite_activated);
ClassDB::bind_method(D_METHOD("update_types"), &CreateDialog::update_types);

ClassDB::bind_method("get_drag_data_fw", &CreateDialog::get_drag_data_fw);
ClassDB::bind_method("can_drop_data_fw", &CreateDialog::can_drop_data_fw);
Expand All @@ -641,8 +696,7 @@ CreateDialog::CreateDialog() {

is_replace_mode = false;

ClassDB::get_class_list(&type_list);
type_list.sort_custom<StringName::AlphCompare>();
update_types();

set_resizable(true);

Expand Down
2 changes: 2 additions & 0 deletions editor/create_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class CreateDialog : public ConfirmationDialog {

void popup_create(bool p_dont_clear, bool p_replace_mode = false);

void update_types();

CreateDialog();
};

Expand Down
Loading

0 comments on commit 1b53ceb

Please sign in to comment.