2
0
Эх сурвалжийг харах

Merge pull request #9158 from Hinsbart/script_templates

Add ability to use custom script templates.
Rémi Verschelde 8 жил өмнө
parent
commit
19017a760c

+ 2 - 0
core/script_language.h

@@ -196,6 +196,8 @@ public:
 	virtual void get_comment_delimiters(List<String> *p_delimiters) const = 0;
 	virtual void get_comment_delimiters(List<String> *p_delimiters) const = 0;
 	virtual void get_string_delimiters(List<String> *p_delimiters) const = 0;
 	virtual void get_string_delimiters(List<String> *p_delimiters) const = 0;
 	virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const = 0;
 	virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const = 0;
+	virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {}
+	virtual bool is_using_templates() { return false; }
 	virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const = 0;
 	virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const = 0;
 	virtual Script *create_script() const = 0;
 	virtual Script *create_script() const = 0;
 	virtual bool has_named_classes() const = 0;
 	virtual bool has_named_classes() const = 0;

+ 25 - 0
editor/editor_settings.cpp

@@ -292,6 +292,12 @@ void EditorSettings::create() {
 			dir->change_dir("..");
 			dir->change_dir("..");
 		}
 		}
 
 
+		if (dir->change_dir("script_templates") != OK) {
+			dir->make_dir("script_templates");
+		} else {
+			dir->change_dir("..");
+		}
+
 		if (dir->change_dir("tmp") != OK) {
 		if (dir->change_dir("tmp") != OK) {
 			dir->make_dir("tmp");
 			dir->make_dir("tmp");
 		} else {
 		} else {
@@ -946,6 +952,25 @@ bool EditorSettings::save_text_editor_theme_as(String p_file) {
 	return false;
 	return false;
 }
 }
 
 
+Vector<String> EditorSettings::get_script_templates(const String &p_extension) {
+
+	Vector<String> templates;
+	DirAccess *d = DirAccess::open(settings_path + "/script_templates");
+	if (d) {
+		d->list_dir_begin();
+		String file = d->get_next();
+		while (file != String()) {
+			if (file.get_extension() == p_extension) {
+				templates.push_back(file.get_basename());
+			}
+			file = d->get_next();
+		}
+		d->list_dir_end();
+		memdelete(d);
+	}
+	return templates;
+}
+
 bool EditorSettings::_save_text_editor_theme(String p_file) {
 bool EditorSettings::_save_text_editor_theme(String p_file) {
 	String theme_section = "color_theme";
 	String theme_section = "color_theme";
 	Ref<ConfigFile> cf = memnew(ConfigFile); // hex is better?
 	Ref<ConfigFile> cf = memnew(ConfigFile); // hex is better?

+ 2 - 0
editor/editor_settings.h

@@ -159,6 +159,8 @@ public:
 	bool save_text_editor_theme();
 	bool save_text_editor_theme();
 	bool save_text_editor_theme_as(String p_file);
 	bool save_text_editor_theme_as(String p_file);
 
 
+	Vector<String> get_script_templates(const String &p_extension);
+
 	void add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut);
 	void add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut);
 	bool is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const;
 	bool is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const;
 	Ref<ShortCut> get_shortcut(const String &p_name) const;
 	Ref<ShortCut> get_shortcut(const String &p_name) const;

+ 46 - 4
editor/script_create_dialog.cpp

@@ -116,6 +116,18 @@ void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
 	_update_dialog();
 	_update_dialog();
 }
 }
 
 
+void ScriptCreateDialog::_template_changed(int p_template) {
+
+	if (p_template == 0) {
+		//default
+		script_template = "";
+		return;
+	}
+	String ext = ScriptServer::get_language(language_menu->get_selected())->get_extension();
+	String name = template_menu->get_item_text(p_template) + "." + ext;
+	script_template = EditorSettings::get_singleton()->get_settings_path() + "/script_templates/" + name;
+}
+
 void ScriptCreateDialog::ok_pressed() {
 void ScriptCreateDialog::ok_pressed() {
 
 
 	if (is_new_script_created) {
 	if (is_new_script_created) {
@@ -134,7 +146,13 @@ void ScriptCreateDialog::_create_new() {
 	if (has_named_classes)
 	if (has_named_classes)
 		cname = class_name->get_text();
 		cname = class_name->get_text();
 
 
-	Ref<Script> scr = ScriptServer::get_language(language_menu->get_selected())->get_template(cname, parent_name->get_text());
+	Ref<Script> scr;
+	if (script_template != "") {
+		scr = ResourceLoader::load(script_template)->duplicate();
+		ScriptServer::get_language(language_menu->get_selected())->make_template(cname, parent_name->get_text(), scr);
+	} else {
+		scr = ScriptServer::get_language(language_menu->get_selected())->get_template(cname, parent_name->get_text());
+	}
 
 
 	String selected_language = language_menu->get_item_text(language_menu->get_selected());
 	String selected_language = language_menu->get_item_text(language_menu->get_selected());
 	editor_settings->set_project_metadata("script_setup", "last_selected_language", selected_language);
 	editor_settings->set_project_metadata("script_setup", "last_selected_language", selected_language);
@@ -175,7 +193,8 @@ void ScriptCreateDialog::_load_exist() {
 void ScriptCreateDialog::_lang_changed(int l) {
 void ScriptCreateDialog::_lang_changed(int l) {
 
 
 	l = language_menu->get_selected();
 	l = language_menu->get_selected();
-	if (ScriptServer::get_language(l)->has_named_classes()) {
+	ScriptLanguage *language = ScriptServer::get_language(l);
+	if (language->has_named_classes()) {
 		has_named_classes = true;
 		has_named_classes = true;
 	} else {
 	} else {
 		has_named_classes = false;
 		has_named_classes = false;
@@ -187,7 +206,7 @@ void ScriptCreateDialog::_lang_changed(int l) {
 		can_inherit_from_file = false;
 		can_inherit_from_file = false;
 	}
 	}
 
 
-	String selected_ext = "." + ScriptServer::get_language(l)->get_extension();
+	String selected_ext = "." + language->get_extension();
 	String path = file_path->get_text();
 	String path = file_path->get_text();
 	String extension = "";
 	String extension = "";
 	if (path != "") {
 	if (path != "") {
@@ -204,7 +223,7 @@ void ScriptCreateDialog::_lang_changed(int l) {
 			List<String> extensions;
 			List<String> extensions;
 			// get all possible extensions for script
 			// get all possible extensions for script
 			for (int l = 0; l < language_menu->get_item_count(); l++) {
 			for (int l = 0; l < language_menu->get_item_count(); l++) {
-				ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
+				language->get_recognized_extensions(&extensions);
 			}
 			}
 
 
 			for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
 			for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
@@ -218,6 +237,18 @@ void ScriptCreateDialog::_lang_changed(int l) {
 		file_path->set_text(path);
 		file_path->set_text(path);
 	}
 	}
 
 
+	bool use_templates = language->is_using_templates();
+	template_menu->set_disabled(!use_templates);
+	if (use_templates) {
+		Vector<String> template_list = EditorSettings::get_singleton()->get_script_templates(language->get_extension());
+
+		template_menu->clear();
+		template_menu->add_item(TTR("Default"));
+		for (int i = 0; i < template_list.size(); i++) {
+			template_menu->add_item(template_list[i]);
+		}
+	}
+
 	_update_dialog();
 	_update_dialog();
 }
 }
 
 
@@ -471,6 +502,7 @@ void ScriptCreateDialog::_bind_methods() {
 	ClassDB::bind_method("_browse_path", &ScriptCreateDialog::_browse_path);
 	ClassDB::bind_method("_browse_path", &ScriptCreateDialog::_browse_path);
 	ClassDB::bind_method("_file_selected", &ScriptCreateDialog::_file_selected);
 	ClassDB::bind_method("_file_selected", &ScriptCreateDialog::_file_selected);
 	ClassDB::bind_method("_path_changed", &ScriptCreateDialog::_path_changed);
 	ClassDB::bind_method("_path_changed", &ScriptCreateDialog::_path_changed);
+	ClassDB::bind_method("_template_changed", &ScriptCreateDialog::_template_changed);
 	ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
 	ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
 }
 }
 
 
@@ -629,6 +661,16 @@ ScriptCreateDialog::ScriptCreateDialog() {
 	gc->add_child(l);
 	gc->add_child(l);
 	gc->add_child(class_name);
 	gc->add_child(class_name);
 
 
+	/* Templates */
+
+	template_menu = memnew(OptionButton);
+	l = memnew(Label);
+	l->set_text(TTR("Template"));
+	l->set_align(Label::ALIGN_RIGHT);
+	gc->add_child(l);
+	gc->add_child(template_menu);
+	template_menu->connect("item_selected", this, "_template_changed");
+
 	/* Built-in Script */
 	/* Built-in Script */
 
 
 	internal = memnew(CheckButton);
 	internal = memnew(CheckButton);

+ 3 - 0
editor/script_create_dialog.h

@@ -48,6 +48,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
 	LineEdit *parent_name;
 	LineEdit *parent_name;
 	Button *parent_browse_button;
 	Button *parent_browse_button;
 	OptionButton *language_menu;
 	OptionButton *language_menu;
+	OptionButton *template_menu;
 	LineEdit *file_path;
 	LineEdit *file_path;
 	Button *path_button;
 	Button *path_button;
 	EditorFileDialog *file_browse;
 	EditorFileDialog *file_browse;
@@ -68,6 +69,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
 	bool is_built_in;
 	bool is_built_in;
 	int current_language;
 	int current_language;
 	bool re_check_path;
 	bool re_check_path;
+	String script_template;
 
 
 	void _path_changed(const String &p_path = String());
 	void _path_changed(const String &p_path = String());
 	void _lang_changed(int l = 0);
 	void _lang_changed(int l = 0);
@@ -75,6 +77,7 @@ class ScriptCreateDialog : public ConfirmationDialog {
 	bool _validate(const String &p_strin);
 	bool _validate(const String &p_strin);
 	void _class_name_changed(const String &p_name);
 	void _class_name_changed(const String &p_name);
 	void _parent_name_changed(const String &p_parent);
 	void _parent_name_changed(const String &p_parent);
+	void _template_changed(int p_template = 0);
 	void _browse_path(bool browse_parent);
 	void _browse_path(bool browse_parent);
 	void _file_selected(const String &p_file);
 	void _file_selected(const String &p_file);
 	virtual void ok_pressed();
 	virtual void ok_pressed();

+ 13 - 0
modules/gdscript/gd_editor.cpp

@@ -69,6 +69,19 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str
 	return script;
 	return script;
 }
 }
 
 
+bool GDScriptLanguage::is_using_templates() {
+
+	return true;
+}
+
+void GDScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
+
+	String src = p_script->get_source_code();
+	src = src.replace("%BASE%", p_base_class_name);
+	src = src.replace("%TS%", _get_indentation());
+	p_script->set_source_code(src);
+}
+
 bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
 bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
 
 
 	GDParser parser;
 	GDParser parser;

+ 5 - 0
modules/gdscript/gd_script.cpp

@@ -615,6 +615,11 @@ Error GDScript::reload(bool p_keep_state) {
 	if (basedir != "")
 	if (basedir != "")
 		basedir = basedir.get_base_dir();
 		basedir = basedir.get_base_dir();
 
 
+	if (basedir.find("res://") == -1 && basedir.find("user://") == -1) {
+		//loading a template, don't parse
+		return OK;
+	}
+
 	valid = false;
 	valid = false;
 	GDParser parser;
 	GDParser parser;
 	Error err = parser.parse(source, basedir, false, path);
 	Error err = parser.parse(source, basedir, false, path);

+ 2 - 0
modules/gdscript/gd_script.h

@@ -381,6 +381,8 @@ public:
 	virtual void get_comment_delimiters(List<String> *p_delimiters) const;
 	virtual void get_comment_delimiters(List<String> *p_delimiters) const;
 	virtual void get_string_delimiters(List<String> *p_delimiters) const;
 	virtual void get_string_delimiters(List<String> *p_delimiters) const;
 	virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
 	virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+	virtual bool is_using_templates();
+	virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
 	virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
 	virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
 	virtual Script *create_script() const;
 	virtual Script *create_script() const;
 	virtual bool has_named_classes() const;
 	virtual bool has_named_classes() const;

+ 11 - 0
modules/visual_script/visual_script.cpp

@@ -2369,6 +2369,17 @@ Ref<Script> VisualScriptLanguage::get_template(const String &p_class_name, const
 	script->set_instance_base_type(p_base_class_name);
 	script->set_instance_base_type(p_base_class_name);
 	return script;
 	return script;
 }
 }
+
+bool VisualScriptLanguage::is_using_templates() {
+
+	return true;
+}
+
+void VisualScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
+	Ref<VisualScript> script = p_script;
+	script->set_instance_base_type(p_base_class_name);
+}
+
 bool VisualScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
 bool VisualScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
 
 
 	return false;
 	return false;

+ 2 - 0
modules/visual_script/visual_script.h

@@ -564,6 +564,8 @@ public:
 	virtual void get_comment_delimiters(List<String> *p_delimiters) const;
 	virtual void get_comment_delimiters(List<String> *p_delimiters) const;
 	virtual void get_string_delimiters(List<String> *p_delimiters) const;
 	virtual void get_string_delimiters(List<String> *p_delimiters) const;
 	virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
 	virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+	virtual bool is_using_templates();
+	virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
 	virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
 	virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
 	virtual Script *create_script() const;
 	virtual Script *create_script() const;
 	virtual bool has_named_classes() const;
 	virtual bool has_named_classes() const;