diff --git a/SConstruct b/SConstruct index f5aa0cd1bd6..b9f2b7e2c4a 100644 --- a/SConstruct +++ b/SConstruct @@ -170,26 +170,6 @@ if selected_platform in platform_list: else: env = env_base.Clone() - # Workaround for MinGW. See: - # http://www.scons.org/wiki/LongCmdLinesOnWin32 - if (os.name=="nt"): - import subprocess - def mySpawn(sh, escape, cmd, args, env): - newargs = ' '.join(args[1:]) - cmdline = cmd + " " + newargs - startupinfo = subprocess.STARTUPINFO() - startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW - proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env) - data, err = proc.communicate() - rv = proc.wait() - if rv: - print "=====" - print err - print "=====" - return rv - env['SPAWN'] = mySpawn - env.extra_suffix="" CCFLAGS = env.get('CCFLAGS', '') diff --git a/core/os/input.cpp b/core/os/input.cpp index 4151c1b5a8c..a827e75896c 100644 --- a/core/os/input.cpp +++ b/core/os/input.cpp @@ -29,6 +29,7 @@ #include "input.h" #include "input_map.h" #include "os/os.h" +#include "globals.h" Input *Input::singleton=NULL; Input *Input::get_singleton() { @@ -69,6 +70,30 @@ void Input::_bind_methods() { ADD_SIGNAL( MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "connected")) ); } +void Input::get_argument_options(const StringName& p_function,int p_idx,List*r_options) const { +#ifdef TOOLS_ENABLED + + String pf=p_function; + if (p_idx==0 && (pf=="is_action_pressed" || pf=="action_press" || pf=="action_release")) { + + List pinfo; + Globals::get_singleton()->get_property_list(&pinfo); + + for(List::Element *E=pinfo.front();E;E=E->next()) { + const PropertyInfo &pi=E->get(); + + if (!pi.name.begins_with("input/")) + continue; + + String name = pi.name.substr(pi.name.find("/")+1,pi.name.length()); + r_options->push_back("\""+name+"\""); + + } + } +#endif + +} + Input::Input() { singleton=this; diff --git a/core/os/input.h b/core/os/input.h index 1cb0f35d963..387a43a35a4 100644 --- a/core/os/input.h +++ b/core/os/input.h @@ -76,6 +76,8 @@ public: virtual void action_press(const StringName& p_action)=0; virtual void action_release(const StringName& p_action)=0; + void get_argument_options(const StringName& p_function,int p_idx,List*r_options) const; + Input(); }; diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index b4791fc6d8c..161e3048272 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -145,7 +145,7 @@ static _FORCE_INLINE_ uint16_t make_half_float(float f) { hf = (((uint16_t)sign) << 15) | (uint16_t)(mantissa); */ - hf=0; //denormals do not work for 3D + hf=0; //denormals do not work for 3D, convert to zero } else { diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp index eb1d0a4db32..12dc1bb1391 100644 --- a/modules/gdscript/gd_editor.cpp +++ b/modules/gdscript/gd_editor.cpp @@ -28,7 +28,7 @@ /*************************************************************************/ #include "gd_script.h" #include "gd_compiler.h" - +#include "globals.h" void GDScriptLanguage::get_comment_delimiters(List *p_delimiters) const { @@ -1276,7 +1276,23 @@ static void _make_function_hint(const GDParser::FunctionNode* p_func,int p_argid static void _find_type_arguments(const GDParser::Node*p_node,int p_line,const StringName& p_method,const GDCompletionIdentifier& id, int p_argidx, Set& result, String& arghint) { - if (id.type==Variant::OBJECT && id.obj_type!=StringName()) { + if (id.type==Variant::INPUT_EVENT && String(p_method)=="is_action" && p_argidx==0) { + + List pinfo; + Globals::get_singleton()->get_property_list(&pinfo); + + for(List::Element *E=pinfo.front();E;E=E->next()) { + const PropertyInfo &pi=E->get(); + + if (!pi.name.begins_with("input/")) + continue; + + String name = pi.name.substr(pi.name.find("/")+1,pi.name.length()); + result.insert("\""+name+"\""); + } + + + } else if (id.type==Variant::OBJECT && id.obj_type!=StringName()) { MethodBind *m = ObjectTypeDB::get_method(id.obj_type,p_method); @@ -1299,7 +1315,7 @@ static void _find_type_arguments(const GDParser::Node*p_node,int p_line,const St const GDParser::OperatorNode *op=static_cast(p_node); if (op->arguments.size()>) - }*/ + }*/ } else { Object *obj=id.value; @@ -1826,6 +1842,37 @@ Error GDScriptLanguage::complete_code(const String& p_code, const String& p_base _find_call_arguments(context,p.get_completion_node(),p.get_completion_line(),p.get_completion_argument_index(),options,r_call_hint); } break; + case GDParser::COMPLETION_VIRTUAL_FUNC: { + + GDCompletionIdentifier cid = _get_native_class(context); + + if (cid.obj_type!=StringName()) { + List vm; + ObjectTypeDB::get_virtual_methods(cid.obj_type,&vm); + for(List::Element *E=vm.front();E;E=E->next()) { + + MethodInfo &mi=E->get(); + String m = mi.name; + if (m.find(":")!=-1) + m=m.substr(0,m.find(":")); + m+="("; + + if (mi.arguments.size()) { + for(int i=0;i0) + m+=", "; + String n =mi.arguments[i].name; + if (n.find(":")!=-1) + n=n.substr(0,n.find(":")); + m+=n; + } + } + m+="):"; + + options.insert(m); + } + } + } break; } diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index f79f3ee44a5..aa2878f9e14 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2027,14 +2027,20 @@ void GDParser::_parse_class(ClassNode *p_class) { } - if (tokenizer->get_token(1)!=GDTokenizer::TK_IDENTIFIER) { + tokenizer->advance(); + StringName name; + + if (_get_completable_identifier(COMPLETION_VIRTUAL_FUNC,name)) { + + } + + + if (name==StringName()) { _set_error("Expected identifier after 'func' (syntax: 'func ([arguments]):' )."); return; } - StringName name = tokenizer->get_token_identifier(1); - for(int i=0;ifunctions.size();i++) { if (p_class->functions[i]->name==name) { _set_error("Function '"+String(name)+"' already exists in this class (at line: "+itos(p_class->functions[i]->line)+")."); @@ -2045,7 +2051,7 @@ void GDParser::_parse_class(ClassNode *p_class) { _set_error("Function '"+String(name)+"' already exists in this class (at line: "+itos(p_class->static_functions[i]->line)+")."); } } - tokenizer->advance(2); + if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_OPEN) { diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h index 26955d2b7a2..44e7b55323a 100644 --- a/modules/gdscript/gd_parser.h +++ b/modules/gdscript/gd_parser.h @@ -363,6 +363,7 @@ public: COMPLETION_METHOD, COMPLETION_CALL_ARGUMENTS, COMPLETION_INDEX, + COMPLETION_VIRTUAL_FUNC }; diff --git a/platform/windows/detect.py b/platform/windows/detect.py index be92ee8f6da..245d6f1bd3d 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -135,6 +135,27 @@ def configure(env): env.Append(LIBPATH=[DIRECTX_PATH+"/Lib/x86"]) env['ENV'] = os.environ; else: + + # Workaround for MinGW. See: + # http://www.scons.org/wiki/LongCmdLinesOnWin32 + if (os.name=="nt"): + import subprocess + def mySpawn(sh, escape, cmd, args, env): + newargs = ' '.join(args[1:]) + cmdline = cmd + " " + newargs + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + proc = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, startupinfo=startupinfo, shell = False, env = env) + data, err = proc.communicate() + rv = proc.wait() + if rv: + print "=====" + print err + print "=====" + return rv + env['SPAWN'] = mySpawn + #build using mingw if (os.name=="nt"): env['ENV']['TMP'] = os.environ['TMP'] #way to go scons, you can be so stupid sometimes diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 933895a2076..8afcbf32836 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -3274,19 +3274,41 @@ void TextEdit::_update_completion_candidates() { String s; - - while(cofs>0 && l[cofs-1]>32 && _is_completable(l[cofs-1])) { - s=String::chr(l[cofs-1])+s; - if (l[cofs-1]=='\'' || l[cofs-1]=='"') - break; - - cofs--; + + //look for keywords first + + bool pre_keyword=false; + + if (cofs>0 && l[cofs-1]==' ') { + int kofs=cofs-1; + String kw; + while (kofs>=0 && l[kofs]==' ') + kofs--; + + while(kofs>=0 && l[kofs]>32 && _is_completable(l[kofs])) { + kw=String::chr(l[kofs])+kw; + kofs--; + } + + pre_keyword=keywords.has(kw); + print_line("KW "+kw+"? "+itos(pre_keyword)); + + } else { + + + while(cofs>0 && l[cofs-1]>32 && _is_completable(l[cofs-1])) { + s=String::chr(l[cofs-1])+s; + if (l[cofs-1]=='\'' || l[cofs-1]=='"') + break; + + cofs--; + } } - + update(); - if (s=="" && (cofs==0 || !completion_prefixes.has(String::chr(l[cofs-1])))) { + if (!pre_keyword && s=="" && (cofs==0 || !completion_prefixes.has(String::chr(l[cofs-1])))) { //none to complete, cancel _cancel_completion(); return;