Batch of Bugfixes
-=-=-=-=-=-=-=-=- -Fixed Export UV XForm (should work now). #923 -Fixed enforcement of limits in property editor. #919 -Fixed long-standing bug of export editings in script inheritance. #914, #859, #756 -Fixed horrible error reporting in shader language. #912 -Added kinematic collision with plane (please test well). #911 -Fixed double animation track insert when using 2D rigs. #904 -VKey updates offset parameter in sprite edition. #901 -Do not allow anymore a script to preload itself. (does not fix #899, but narrows it down) -Avoid connection editor from overriding selected text. #897 -Fixed timer autostart. #876 -Fixed collision layers in 3D physics. #872 -Improved operators in shader #857 -Fixed ambient lighting bug #834 -Avoid editor from processing gamepad input #813 -Added not keyword #752 Please test!
This commit is contained in:
@ -66,7 +66,7 @@ bool GDScriptLanguage::validate(const String& p_script, int &r_line_error,int &r
|
||||
|
||||
GDParser parser;
|
||||
|
||||
Error err = parser.parse(p_script,p_path.get_base_dir(),true);
|
||||
Error err = parser.parse(p_script,p_path.get_base_dir(),true,p_path);
|
||||
if (err) {
|
||||
r_line_error=parser.get_error_line();
|
||||
r_col_error=parser.get_error_column();
|
||||
|
||||
@ -225,7 +225,14 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
String path = tokenizer->get_token_constant();
|
||||
if (!path.is_abs_path() && base_path!="")
|
||||
path=base_path+"/"+path;
|
||||
path = path.replace("///","//");
|
||||
path = path.replace("///","//").simplify_path();
|
||||
if (path==self_path) {
|
||||
|
||||
_set_error("Can't preload itself (use 'get_script()').");
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Ref<Resource> res;
|
||||
if (!validating) {
|
||||
@ -2616,8 +2623,9 @@ Error GDParser::_parse(const String& p_base_path) {
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path) {
|
||||
Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path, const String &p_self_path) {
|
||||
|
||||
self_path=p_self_path;
|
||||
GDTokenizerBuffer *tb = memnew( GDTokenizerBuffer );
|
||||
tb->set_code_buffer(p_bytecode);
|
||||
tokenizer=tb;
|
||||
@ -2628,9 +2636,9 @@ Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p
|
||||
}
|
||||
|
||||
|
||||
Error GDParser::parse(const String& p_code,const String& p_base_path,bool p_just_validate) {
|
||||
|
||||
Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_just_validate, const String &p_self_path) {
|
||||
|
||||
self_path=p_self_path;
|
||||
GDTokenizerText *tt = memnew( GDTokenizerText );
|
||||
tt->set_code(p_code);
|
||||
|
||||
|
||||
@ -373,6 +373,7 @@ private:
|
||||
List<int> tab_level;
|
||||
|
||||
String base_path;
|
||||
String self_path;
|
||||
|
||||
PropertyInfo current_export;
|
||||
|
||||
@ -398,8 +399,8 @@ public:
|
||||
String get_error() const;
|
||||
int get_error_line() const;
|
||||
int get_error_column() const;
|
||||
Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false);
|
||||
Error parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path="");
|
||||
Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="");
|
||||
Error parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path="",const String& p_self_path="");
|
||||
|
||||
const Node *get_parse_tree() const;
|
||||
|
||||
|
||||
@ -1523,6 +1523,7 @@ void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
|
||||
placeholders.erase(p_placeholder);
|
||||
}
|
||||
|
||||
/*
|
||||
void GDScript::_update_placeholder(PlaceHolderScriptInstance *p_placeholder) {
|
||||
|
||||
|
||||
@ -1563,7 +1564,7 @@ void GDScript::_update_placeholder(PlaceHolderScriptInstance *p_placeholder) {
|
||||
|
||||
p_placeholder->update(plist,default_values);
|
||||
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
ScriptInstance* GDScript::instance_create(Object *p_this) {
|
||||
|
||||
@ -1582,7 +1583,8 @@ ScriptInstance* GDScript::instance_create(Object *p_this) {
|
||||
}*/
|
||||
PlaceHolderScriptInstance *si = memnew( PlaceHolderScriptInstance(GDScriptLanguage::get_singleton(),Ref<Script>(this),p_this) );
|
||||
placeholders.insert(si);
|
||||
_update_placeholder(si);
|
||||
//_update_placeholder(si);
|
||||
_update_exports();
|
||||
return si;
|
||||
#else
|
||||
return NULL;
|
||||
@ -1623,61 +1625,136 @@ String GDScript::get_source_code() const {
|
||||
}
|
||||
void GDScript::set_source_code(const String& p_code) {
|
||||
|
||||
if (source==p_code)
|
||||
return;
|
||||
source=p_code;
|
||||
#ifdef TOOLS_ENABLED
|
||||
source_changed_cache=true;
|
||||
//print_line("SC CHANGED "+get_path());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void GDScript::_update_exports_values(Map<StringName,Variant>& values, List<PropertyInfo> &propnames) {
|
||||
|
||||
void GDScript::_update_exports(Set<PlaceHolderScriptInstance*> *p_instances) {
|
||||
if (base_cache.is_valid()) {
|
||||
base_cache->_update_exports_values(values,propnames);
|
||||
}
|
||||
|
||||
for(Map<StringName,Variant>::Element *E=member_default_values_cache.front();E;E=E->next()) {
|
||||
values[E->key()]=E->get();
|
||||
}
|
||||
|
||||
for (List<PropertyInfo>::Element *E=members_cache.front();E;E=E->next()) {
|
||||
propnames.push_back(E->get());
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
bool GDScript::_update_exports() {
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
String basedir=path;
|
||||
bool changed=false;
|
||||
|
||||
if (basedir=="")
|
||||
basedir=get_path();
|
||||
if (source_changed_cache) {
|
||||
//print_line("updating source for "+get_path());
|
||||
source_changed_cache=false;
|
||||
changed=true;
|
||||
|
||||
if (basedir!="")
|
||||
basedir=basedir.get_base_dir();
|
||||
String basedir=path;
|
||||
|
||||
GDParser parser;
|
||||
Error err = parser.parse(source,basedir,true);
|
||||
if (err)
|
||||
return; //do none
|
||||
if (basedir=="")
|
||||
basedir=get_path();
|
||||
|
||||
const GDParser::Node* root = parser.get_parse_tree();
|
||||
ERR_FAIL_COND(root->type!=GDParser::Node::TYPE_CLASS);
|
||||
if (basedir!="")
|
||||
basedir=basedir.get_base_dir();
|
||||
|
||||
GDParser parser;
|
||||
Error err = parser.parse(source,basedir,true,path);
|
||||
|
||||
if (err==OK) {
|
||||
|
||||
const GDParser::Node* root = parser.get_parse_tree();
|
||||
ERR_FAIL_COND_V(root->type!=GDParser::Node::TYPE_CLASS,false);
|
||||
|
||||
const GDParser::ClassNode *c = static_cast<const GDParser::ClassNode*>(root);
|
||||
|
||||
if (base_cache.is_valid()) {
|
||||
base_cache->inheriters_cache.erase(get_instance_ID());
|
||||
base_cache=Ref<GDScript>();
|
||||
}
|
||||
|
||||
|
||||
if (c->extends_used && String(c->extends_file)!="") {
|
||||
|
||||
const GDParser::ClassNode *c = static_cast<const GDParser::ClassNode*>(root);
|
||||
String path = c->extends_file;
|
||||
if (path.is_rel_path()) {
|
||||
|
||||
if (c->extends_used && String(c->extends_file)!="") {
|
||||
String base = get_path();
|
||||
if (base=="" || base.is_rel_path()) {
|
||||
|
||||
Ref<GDScript> bf = ResourceLoader::load(c->extends_file);
|
||||
if (bf.is_valid()) {
|
||||
ERR_PRINT(("Could not resolve relative path for parent class: "+path).utf8().get_data());
|
||||
} else {
|
||||
path=base.get_base_dir().plus_file(path);
|
||||
}
|
||||
}
|
||||
|
||||
bf->_update_exports(p_instances);
|
||||
Ref<GDScript> bf = ResourceLoader::load(path);
|
||||
|
||||
if (bf.is_valid()) {
|
||||
|
||||
//print_line("parent is: "+bf->get_path());
|
||||
base_cache=bf;
|
||||
bf->inheriters_cache.insert(get_instance_ID());
|
||||
|
||||
//bf->_update_exports(p_instances,true,false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
members_cache.clear();;
|
||||
member_default_values_cache.clear();
|
||||
|
||||
for(int i=0;i<c->variables.size();i++) {
|
||||
if (c->variables[i]._export.type==Variant::NIL)
|
||||
continue;
|
||||
|
||||
members_cache.push_back(c->variables[i]._export);
|
||||
//print_line("found "+c->variables[i]._export.name);
|
||||
member_default_values_cache[c->variables[i].identifier]=c->variables[i].default_value;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//print_line("unchaged is "+get_path());
|
||||
|
||||
}
|
||||
|
||||
if (base_cache.is_valid()) {
|
||||
if (base_cache->_update_exports()) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
List<PropertyInfo> plist;
|
||||
if (/*changed &&*/ placeholders.size()) { //hm :(
|
||||
|
||||
Map<StringName,Variant> default_values;
|
||||
//print_line("updating placeholders for "+get_path());
|
||||
|
||||
for(int i=0;i<c->variables.size();i++) {
|
||||
if (c->variables[i]._export.type==Variant::NIL)
|
||||
continue;
|
||||
//update placeholders if any
|
||||
Map<StringName,Variant> values;
|
||||
List<PropertyInfo> propnames;
|
||||
_update_exports_values(values,propnames);
|
||||
|
||||
plist.push_back(c->variables[i]._export);
|
||||
default_values[c->variables[i].identifier]=c->variables[i].default_value;
|
||||
for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) {
|
||||
|
||||
E->get()->update(propnames,values);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
|
||||
for (Set<PlaceHolderScriptInstance*>::Element *E=p_instances->front();E;E=E->next()) {
|
||||
|
||||
E->get()->update(plist,default_values);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1685,8 +1762,20 @@ void GDScript::update_exports() {
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
_update_exports(&placeholders);
|
||||
_update_exports();
|
||||
|
||||
Set<ObjectID> copy=inheriters_cache; //might get modified
|
||||
|
||||
//print_line("update exports for "+get_path()+" ic: "+itos(copy.size()));
|
||||
for(Set<ObjectID>::Element *E=copy.front();E;E=E->next()) {
|
||||
Object *id=ObjectDB::get_instance(E->get());
|
||||
if (!id)
|
||||
continue;
|
||||
GDScript *s=id->cast_to<GDScript>();
|
||||
if (!s)
|
||||
continue;
|
||||
s->update_exports();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@ -1718,7 +1807,7 @@ Error GDScript::reload() {
|
||||
|
||||
valid=false;
|
||||
GDParser parser;
|
||||
Error err = parser.parse(source,basedir);
|
||||
Error err = parser.parse(source,basedir,false,path);
|
||||
if (err) {
|
||||
if (ScriptDebugger::get_singleton()) {
|
||||
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(),parser.get_error_line(),"Parser Error: "+parser.get_error());
|
||||
@ -1746,10 +1835,10 @@ Error GDScript::reload() {
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) {
|
||||
/*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) {
|
||||
|
||||
_update_placeholder(E->get());
|
||||
}
|
||||
}*/
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
@ -1892,7 +1981,7 @@ Error GDScript::load_byte_code(const String& p_path) {
|
||||
|
||||
valid=false;
|
||||
GDParser parser;
|
||||
Error err = parser.parse_bytecode(bytecode,basedir);
|
||||
Error err = parser.parse_bytecode(bytecode,basedir,get_path());
|
||||
if (err) {
|
||||
_err_print_error("GDScript::load_byte_code",path.empty()?"built-in":(const char*)path.utf8().get_data(),parser.get_error_line(),("Parse Error: "+parser.get_error()).utf8().get_data());
|
||||
ERR_FAIL_V(ERR_PARSE_ERROR);
|
||||
@ -1945,6 +2034,8 @@ Error GDScript::load_source_code(const String& p_path) {
|
||||
}
|
||||
|
||||
source=s;
|
||||
source_changed_cache=true;
|
||||
//print_line("LSC :"+get_path());
|
||||
path=p_path;
|
||||
return OK;
|
||||
|
||||
@ -1986,6 +2077,9 @@ GDScript::GDScript() {
|
||||
_base=NULL;
|
||||
_owner=NULL;
|
||||
tool=false;
|
||||
#ifdef TOOLS_ENABLED
|
||||
source_changed_cache=false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -245,7 +245,16 @@ friend class GDScriptLanguage;
|
||||
Map<StringName,Ref<GDScript> > subclasses;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
Map<StringName,Variant> member_default_values;
|
||||
|
||||
List<PropertyInfo> members_cache;
|
||||
Map<StringName,Variant> member_default_values_cache;
|
||||
Ref<GDScript> base_cache;
|
||||
Set<ObjectID> inheriters_cache;
|
||||
bool source_changed_cache;
|
||||
void _update_exports_values(Map<StringName,Variant>& values, List<PropertyInfo> &propnames);
|
||||
|
||||
#endif
|
||||
Map<StringName,PropertyInfo> member_info;
|
||||
|
||||
@ -265,13 +274,13 @@ friend class GDScriptLanguage;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
Set<PlaceHolderScriptInstance*> placeholders;
|
||||
void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
|
||||
//void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
|
||||
virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void _update_exports(Set<PlaceHolderScriptInstance *> *p_instances);
|
||||
bool _update_exports();
|
||||
|
||||
protected:
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
|
||||
Reference in New Issue
Block a user