-ability to change scripts in external editor and still have properties reloaded in godot UI, fixes #3003

This commit is contained in:
Juan Linietsky 2015-12-09 09:08:41 -03:00
parent 708ff381d6
commit 6bc6b8fcf2
7 changed files with 119 additions and 21 deletions

View file

@ -853,6 +853,8 @@ String ResourceInteractiveLoaderBinary::get_unicode_string() {
if (len>str_buf.size()) {
str_buf.resize(len);
}
if (len==0)
return String();
f->get_buffer((uint8_t*)&str_buf[0],len);
String s;
s.parse_utf8(&str_buf[0]);

View file

@ -338,6 +338,14 @@ void EditorData::set_editor_states(const Dictionary& p_states) {
}
void EditorData::notify_edited_scene_changed() {
for(int i=0;i<editor_plugins.size();i++) {
editor_plugins[i]->edited_scene_changed();
}
}
void EditorData::clear_editor_states() {
for(int i=0;i<editor_plugins.size();i++) {

View file

@ -200,6 +200,7 @@ public:
void save_edited_scene_state(EditorSelection *p_selection,EditorHistory *p_history,const Dictionary& p_custom);
Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history);
void notify_edited_scene_changed();
EditorData();

View file

@ -3399,6 +3399,8 @@ void EditorNode::_set_main_scene_state(Dictionary p_state) {
//changing_scene=true; //avoid script change from opening editor
ScriptEditor::get_singleton()->get_debugger()->update_live_edit_root();
ScriptEditor::get_singleton()->set_scene_root_script( editor_data.get_scene_root_script(editor_data.get_edited_scene()) );
editor_data.notify_edited_scene_changed();
//changing_scene=false;
}

View file

@ -92,6 +92,7 @@ public:
virtual bool get_remove_list(List<Node*> *p_list);
virtual void set_window_layout(Ref<ConfigFile> p_layout);
virtual void get_window_layout(Ref<ConfigFile> p_layout);
virtual void edited_scene_changed(){}; // if changes are pending in editor, apply them
virtual void restore_global_state();
virtual void save_global_state();

View file

@ -379,6 +379,8 @@ void ScriptTextEditor::reload_text() {
te->set_h_scroll(h);
te->set_v_scroll(v);
te->tag_saved_version();
_line_col_changed();
}
@ -391,6 +393,12 @@ void ScriptTextEditor::_notification(int p_what) {
}
}
bool ScriptTextEditor::is_unsaved() {
return get_text_edit()->get_version()!=get_text_edit()->get_saved_version();
}
String ScriptTextEditor::get_name() {
String name;
@ -492,6 +500,59 @@ static Node* _find_node_for_script(Node* p_base, Node*p_current, const Ref<Scrip
return NULL;
}
static void _find_changed_scripts_for_external_editor(Node* p_base, Node*p_current, Set<Ref<Script> > &r_scripts) {
if (p_current->get_owner()!=p_base && p_base!=p_current)
return;
Ref<Script> c = p_current->get_script();
if (c.is_valid())
r_scripts.insert(c);
for(int i=0;i<p_current->get_child_count();i++) {
_find_changed_scripts_for_external_editor(p_base,p_current->get_child(i),r_scripts);
}
}
void ScriptEditor::_update_modified_scripts_for_external_editor() {
if (!bool(EditorSettings::get_singleton()->get("external_editor/use_external_editor")))
return;
Set<Ref<Script> > scripts;
Node *base = get_tree()->get_edited_scene_root();
if (base) {
_find_changed_scripts_for_external_editor(base,base,scripts);
}
for (Set<Ref<Script> >::Element *E=scripts.front();E;E=E->next()) {
Ref<Script> script = E->get();
if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1) {
continue; //internal script, who cares, though weird
}
uint64_t last_date = script->get_last_modified_time();
uint64_t date = FileAccess::get_modified_time(script->get_path());
if (last_date!=date) {
Ref<Script> rel_script = ResourceLoader::load(script->get_path(),script->get_type(),true);
ERR_CONTINUE(!rel_script.is_valid());
script->set_source_code( rel_script->get_source_code() );
script->set_last_modified_time( rel_script->get_last_modified_time() );
script->update_exports();
}
}
}
void ScriptTextEditor::_code_complete_script(const String& p_code, List<String>* r_options) {
Node *base = get_tree()->get_edited_scene_root();
@ -749,6 +810,7 @@ void ScriptEditor::_reload_scripts(){
}
disk_changed->hide();
_update_script_names();
}
@ -791,46 +853,53 @@ bool ScriptEditor::_test_script_times_on_disk() {
TreeItem *r = disk_changed_list->create_item();
disk_changed_list->set_hide_root(true);
bool all_ok=true;
bool need_ask=false;
bool need_reload=false;
bool use_autoreload=bool(EDITOR_DEF("text_editor/auto_reload_scripts_on_external_change",false));
for(int i=0;i<tab_container->get_child_count();i++) {
ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>();
if (!ste)
continue;
if (ste) {
Ref<Script> script = ste->get_edited_script();
if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1)
continue; //internal script, who cares
Ref<Script> script = ste->get_edited_script();
uint64_t last_date = script->get_last_modified_time();
uint64_t date = FileAccess::get_modified_time(script->get_path());
if (script->get_path()=="" || script->get_path().find("local://")!=-1 || script->get_path().find("::")!=-1)
continue; //internal script, who cares
//printf("last date: %lli vs date: %lli\n",last_date,date);
if (last_date!=date) {
TreeItem *ti = disk_changed_list->create_item(r);
ti->set_text(0,script->get_path().get_file());
uint64_t last_date = script->get_last_modified_time();
uint64_t date = FileAccess::get_modified_time(script->get_path());
//printf("last date: %lli vs date: %lli\n",last_date,date);
if (last_date!=date) {
TreeItem *ti = disk_changed_list->create_item(r);
ti->set_text(0,script->get_path().get_file());
all_ok=false;
//r->set_metadata(0,);
if (!use_autoreload || ste->is_unsaved()) {
need_ask=true;
}
need_reload=true;
//r->set_metadata(0,);
}
}
}
if (!all_ok) {
if (bool(EDITOR_DEF("text_editor/auto_reload_changed_scripts",false))) {
if (need_reload) {
if (!need_ask) {
script_editor->_reload_scripts();
need_reload=false;
} else {
disk_changed->call_deferred("popup_centered_ratio",0.5);
}
}
return all_ok;
return need_reload;
}
void ScriptEditor::swap_lines(TextEdit *tx, int line1, int line2)
@ -1403,6 +1472,7 @@ void ScriptEditor::_notification(int p_what) {
if (p_what==MainLoop::NOTIFICATION_WM_FOCUS_IN) {
_test_script_times_on_disk();
_update_modified_scripts_for_external_editor();
}
if (p_what==NOTIFICATION_PROCESS) {
@ -1411,6 +1481,11 @@ void ScriptEditor::_notification(int p_what) {
}
void ScriptEditor::edited_scene_changed() {
_update_modified_scripts_for_external_editor();
}
static const Node * _find_node_with_script(const Node* p_node, const RefPtr & p_script) {
@ -2560,6 +2635,11 @@ void ScriptEditorPlugin::get_breakpoints(List<String> *p_breakpoints) {
return script_editor->get_breakpoints(p_breakpoints);
}
void ScriptEditorPlugin::edited_scene_changed() {
script_editor->edited_scene_changed();
}
ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
editor=p_node;
@ -2569,7 +2649,7 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
script_editor->hide();
EDITOR_DEF("text_editor/auto_reload_changed_scripts",false);
EDITOR_DEF("text_editor/auto_reload_scripts_on_external_change",true);
EDITOR_DEF("text_editor/open_dominant_script_on_scene_change",true);
EDITOR_DEF("external_editor/use_external_editor",false);
EDITOR_DEF("external_editor/exec_path","");

View file

@ -103,7 +103,7 @@ public:
void reload_text();
String get_name() ;
Ref<Texture> get_icon() ;
bool is_unsaved();
ScriptTextEditor();
};
@ -271,6 +271,7 @@ class ScriptEditor : public VBoxContainer {
void _go_to_tab(int p_idx);
void _update_history_pos(int p_new_pos);
void _update_script_colors();
void _update_modified_scripts_for_external_editor();
static ScriptEditor *script_editor;
@ -302,6 +303,8 @@ public:
void set_scene_root_script( Ref<Script> p_script );
virtual void edited_scene_changed();
ScriptEditorDebugger *get_debugger() { return debugger; }
ScriptEditor(EditorNode *p_editor);
@ -338,6 +341,7 @@ public:
virtual void get_breakpoints(List<String> *p_breakpoints);
virtual void edited_scene_changed();
ScriptEditorPlugin(EditorNode *p_node);
~ScriptEditorPlugin();