summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/dictionary.cpp10
-rw-r--r--core/dictionary.h2
-rw-r--r--core/variant_call.cpp2
-rw-r--r--core/vector.h5
-rw-r--r--drivers/nrex/README.md18
-rw-r--r--drivers/nrex/nrex.cpp131
-rw-r--r--drivers/nrex/nrex.hpp7
-rw-r--r--modules/gdscript/gd_compiler.cpp17
-rw-r--r--scene/animation/animation_tree_player.cpp135
-rw-r--r--scene/animation/animation_tree_player.h3
-rw-r--r--scene/gui/text_edit.cpp5
-rw-r--r--scene/gui/text_edit.h1
-rw-r--r--tools/editor/code_editor.cpp3
-rw-r--r--tools/editor/editor_settings.cpp1
-rw-r--r--tools/editor/plugins/script_editor_plugin.cpp1
15 files changed, 220 insertions, 121 deletions
diff --git a/core/dictionary.cpp b/core/dictionary.cpp
index a013c21b29..75c8531251 100644
--- a/core/dictionary.cpp
+++ b/core/dictionary.cpp
@@ -110,6 +110,16 @@ bool Dictionary::has(const Variant& p_key) const {
return _p->variant_map.has(p_key);
}
+
+bool Dictionary::has_all(const Array& p_keys) const {
+ for (int i=0;i<p_keys.size();i++) {
+ if( !has(p_keys[i]) ) {
+ return false;
+ }
+ }
+ return true;
+}
+
void Dictionary::erase(const Variant& p_key) {
_copy_on_write();
_p->variant_map.erase(p_key);
diff --git a/core/dictionary.h b/core/dictionary.h
index 145e7e5c84..c854e95ee6 100644
--- a/core/dictionary.h
+++ b/core/dictionary.h
@@ -69,6 +69,8 @@ public:
bool is_shared() const;
bool has(const Variant& p_key) const;
+ bool has_all(const Array& p_keys) const;
+
void erase(const Variant& p_key);
bool operator==(const Dictionary& p_dictionary) const;
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 78814c83e2..a4963f0d1f 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -440,6 +440,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_LOCALMEM0R(Dictionary,empty);
VCALL_LOCALMEM0(Dictionary,clear);
VCALL_LOCALMEM1R(Dictionary,has);
+ VCALL_LOCALMEM1R(Dictionary,has_all);
VCALL_LOCALMEM1(Dictionary,erase);
VCALL_LOCALMEM0R(Dictionary,hash);
VCALL_LOCALMEM0R(Dictionary,keys);
@@ -1423,6 +1424,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC0(DICTIONARY,BOOL,Dictionary,empty,varray());
ADDFUNC0(DICTIONARY,NIL,Dictionary,clear,varray());
ADDFUNC1(DICTIONARY,BOOL,Dictionary,has,NIL,"value",varray());
+ ADDFUNC1(DICTIONARY,BOOL,Dictionary,has_all,ARRAY,"values",varray());
ADDFUNC1(DICTIONARY,NIL,Dictionary,erase,NIL,"value",varray());
ADDFUNC0(DICTIONARY,INT,Dictionary,hash,varray());
ADDFUNC0(DICTIONARY,ARRAY,Dictionary,keys,varray());
diff --git a/core/vector.h b/core/vector.h
index 16a09c1ddd..87248ccf68 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -70,7 +70,8 @@ class Vector {
}
_FORCE_INLINE_ size_t _get_alloc_size(size_t p_elements) const {
- return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
+ //return nearest_power_of_2_templated(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
+ return nearest_power_of_2(p_elements*sizeof(T)+sizeof(SafeRefCount)+sizeof(int));
}
_FORCE_INLINE_ bool _get_alloc_size_checked(size_t p_elements, size_t *out) const {
@@ -79,7 +80,7 @@ class Vector {
size_t p;
if (_mul_overflow(p_elements, sizeof(T), &o)) return false;
if (_add_overflow(o, sizeof(SafeRefCount)+sizeof(int), &p)) return false;
- *out = nearest_power_of_2_templated(p);
+ *out = nearest_power_of_2(p);
return true;
#else
// Speed is more important than correctness here, do the operations unchecked
diff --git a/drivers/nrex/README.md b/drivers/nrex/README.md
index 9ff67992dc..7a942b2452 100644
--- a/drivers/nrex/README.md
+++ b/drivers/nrex/README.md
@@ -1,6 +1,8 @@
# NREX: Node RegEx
-Version 0.1
+[![Build Status](https://travis-ci.org/leezh/nrex.svg?branch=master)](https://travis-ci.org/leezh/nrex)
+
+** Version 0.2 **
Small node-based regular expression library. It only does text pattern
matchhing, not replacement. To use add the files `nrex.hpp`, `nrex.cpp`
@@ -38,7 +40,7 @@ Currently supported features:
## License
-Copyright (c) 2015, Zher Huei Lee
+Copyright (c) 2015-2016, Zher Huei Lee
All rights reserved.
This software is provided 'as-is', without any express or implied
@@ -59,3 +61,15 @@ freely, subject to the following restrictions:
3. This notice may not be removed or altered from any source
distribution.
+
+
+# Changes
+
+## Version 0.2 (2016-08-04)
+ * Fixed capturing groups matching to invalid results
+ * Fixed parents of recursive quantifiers not expanding properly
+ * Fixed LookAhead sometimes adding to result
+ * More verbose unit testing
+
+## Version 0.1 (2015-12-04)
+ * Initial release
diff --git a/drivers/nrex/nrex.cpp b/drivers/nrex/nrex.cpp
index 1eb9ec38c8..ac19c71408 100644
--- a/drivers/nrex/nrex.cpp
+++ b/drivers/nrex/nrex.cpp
@@ -1,7 +1,7 @@
// NREX: Node RegEx
-// Version 0.1
+// Version 0.2
//
-// Copyright (c) 2015, Zher Huei Lee
+// Copyright (c) 2015-2016, Zher Huei Lee
// All rights reserved.
//
// This software is provided 'as-is', without any express or implied
@@ -68,6 +68,13 @@ class nrex_array
{
}
+ nrex_array(unsigned int size)
+ : _data(NREX_NEW_ARRAY(T, size))
+ , _reserved(size)
+ , _size(0)
+ {
+ }
+
~nrex_array()
{
NREX_DELETE_ARRAY(_data);
@@ -100,7 +107,7 @@ class nrex_array
_size++;
}
- T& top()
+ const T& top() const
{
return _data[_size - 1];
}
@@ -189,17 +196,19 @@ struct nrex_search
nrex_result* captures;
int end;
bool complete;
+ nrex_array<int> lookahead_pos;
nrex_char at(int pos)
{
return str[pos];
}
- nrex_search(const nrex_char* str, nrex_result* captures)
+ nrex_search(const nrex_char* str, nrex_result* captures, int lookahead)
: str(str)
, captures(captures)
, end(0)
{
+ lookahead_pos.reserve(lookahead);
}
};
@@ -239,13 +248,17 @@ struct nrex_node
{
pos = next->test(s, pos);
}
+ if (pos >= 0)
+ {
+ s->complete = true;
+ }
if (parent && pos >= 0)
{
pos = parent->test_parent(s, pos);
}
- if (pos >= 0)
+ if (pos < 0)
{
- s->complete = true;
+ s->complete = false;
}
return pos;
}
@@ -274,25 +287,31 @@ struct nrex_node
}
};
-struct nrex_node_group : public nrex_node
+enum nrex_group_type
{
- static const int NonCapture = -1;
- static const int Bracket = -2;
- static const int LookAhead = -3;
- static const int LookBehind = -4;
+ nrex_group_capture,
+ nrex_group_non_capture,
+ nrex_group_bracket,
+ nrex_group_look_ahead,
+ nrex_group_look_behind,
+};
- int mode;
+struct nrex_node_group : public nrex_node
+{
+ nrex_group_type type;
+ int id;
bool negate;
nrex_array<nrex_node*> childset;
nrex_node* back;
- nrex_node_group(int mode)
+ nrex_node_group(nrex_group_type type, int id = 0)
: nrex_node(true)
- , mode(mode)
+ , type(type)
+ , id(id)
, negate(false)
, back(NULL)
{
- if (mode != Bracket)
+ if (type != nrex_group_bracket)
{
length = 0;
}
@@ -300,7 +319,7 @@ struct nrex_node_group : public nrex_node
{
length = 1;
}
- if (mode == LookAhead || mode == LookBehind)
+ if (type == nrex_group_look_ahead || type == nrex_group_look_behind)
{
quantifiable = false;
}
@@ -317,15 +336,17 @@ struct nrex_node_group : public nrex_node
int test(nrex_search* s, int pos) const
{
- if (mode >= 0)
+ int old_start;
+ if (type == nrex_group_capture)
{
- s->captures[mode].start = pos;
+ old_start = s->captures[id].start;
+ s->captures[id].start = pos;
}
for (unsigned int i = 0; i < childset.size(); ++i)
{
s->complete = false;
int offset = 0;
- if (mode == LookBehind)
+ if (type == nrex_group_look_behind)
{
if (pos < length)
{
@@ -333,7 +354,15 @@ struct nrex_node_group : public nrex_node
}
offset = length;
}
+ if (type == nrex_group_look_ahead)
+ {
+ s->lookahead_pos.push(pos);
+ }
int res = childset[i]->test(s, pos - offset);
+ if (type == nrex_group_look_ahead)
+ {
+ s->lookahead_pos.pop();
+ }
if (s->complete)
{
return res;
@@ -355,32 +384,40 @@ struct nrex_node_group : public nrex_node
}
if (res >= 0)
{
- if (mode >= 0)
+ if (type == nrex_group_capture)
{
- s->captures[mode].length = res - pos;
+ s->captures[id].length = res - pos;
}
- else if (mode == LookAhead || mode == LookBehind)
+ else if (type == nrex_group_look_ahead || type == nrex_group_look_behind)
{
res = pos;
}
return next ? next->test(s, res) : res;
}
}
+ if (type == nrex_group_capture)
+ {
+ s->captures[id].start = old_start;
+ }
return -1;
}
virtual int test_parent(nrex_search* s, int pos) const
{
- if (mode >= 0)
+ if (type == nrex_group_capture)
+ {
+ s->captures[id].length = pos - s->captures[id].start;
+ }
+ if (type == nrex_group_look_ahead)
{
- s->captures[mode].length = pos - s->captures[mode].start;
+ pos = s->lookahead_pos[id];
}
return nrex_node::test_parent(s, pos);
}
void add_childset()
{
- if (childset.size() > 0 && mode != Bracket)
+ if (childset.size() > 0 && type != nrex_group_bracket)
{
length = -1;
}
@@ -391,7 +428,7 @@ struct nrex_node_group : public nrex_node
{
node->parent = this;
node->previous = back;
- if (back && mode != Bracket)
+ if (back && type != nrex_group_bracket)
{
back->next = node;
}
@@ -399,7 +436,7 @@ struct nrex_node_group : public nrex_node
{
childset.push(node);
}
- if (mode != Bracket)
+ if (type != nrex_group_bracket)
{
increment_length(node->length);
}
@@ -418,7 +455,7 @@ struct nrex_node_group : public nrex_node
{
childset.pop();
}
- if (mode != Bracket)
+ if (type != nrex_group_bracket)
{
increment_length(old->length, true);
}
@@ -436,7 +473,7 @@ struct nrex_node_group : public nrex_node
{
childset.pop();
}
- if (mode != Bracket)
+ if (type != nrex_group_bracket)
{
increment_length(old->length, true);
}
@@ -887,6 +924,12 @@ struct nrex_node_quantifier : public nrex_node
}
return -1;
}
+
+ virtual int test_parent(nrex_search* s, int pos) const
+ {
+ s->complete = false;
+ return pos;
+ }
};
struct nrex_node_anchor : public nrex_node
@@ -986,7 +1029,7 @@ bool nrex_has_lookbehind(nrex_array<nrex_node_group*>& stack)
{
for (unsigned int i = 0; i < stack.size(); i++)
{
- if (stack[i]->mode == nrex_node_group::LookBehind)
+ if (stack[i]->type == nrex_group_look_behind)
{
return true;
}
@@ -996,12 +1039,14 @@ bool nrex_has_lookbehind(nrex_array<nrex_node_group*>& stack)
nrex::nrex()
: _capturing(0)
+ , _lookahead_depth(0)
, _root(NULL)
{
}
nrex::nrex(const nrex_char* pattern, int captures)
: _capturing(0)
+ , _lookahead_depth(0)
, _root(NULL)
{
compile(pattern, captures);
@@ -1023,6 +1068,7 @@ bool nrex::valid() const
void nrex::reset()
{
_capturing = 0;
+ _lookahead_depth = 0;
if (_root)
{
NREX_DELETE(_root);
@@ -1042,9 +1088,10 @@ int nrex::capture_size() const
bool nrex::compile(const nrex_char* pattern, int captures)
{
reset();
- nrex_node_group* root = NREX_NEW(nrex_node_group(_capturing));
+ nrex_node_group* root = NREX_NEW(nrex_node_group(nrex_group_capture, _capturing));
nrex_array<nrex_node_group*> stack;
stack.push(root);
+ unsigned int lookahead_level = 0;
_root = root;
for (const nrex_char* c = pattern; c[0] != '\0'; ++c)
@@ -1056,22 +1103,26 @@ bool nrex::compile(const nrex_char* pattern, int captures)
if (c[2] == ':')
{
c = &c[2];
- nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::NonCapture));
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_group_non_capture));
stack.top()->add_child(group);
stack.push(group);
}
else if (c[2] == '!' || c[2] == '=')
{
c = &c[2];
- nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::LookAhead));
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_group_look_ahead, lookahead_level++));
group->negate = (c[0] == '!');
stack.top()->add_child(group);
stack.push(group);
+ if (lookahead_level > _lookahead_depth)
+ {
+ _lookahead_depth = lookahead_level;
+ }
}
else if (c[2] == '<' && (c[3] == '!' || c[3] == '='))
{
c = &c[3];
- nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::LookBehind));
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_group_look_behind));
group->negate = (c[0] == '!');
stack.top()->add_child(group);
stack.push(group);
@@ -1083,13 +1134,13 @@ bool nrex::compile(const nrex_char* pattern, int captures)
}
else if (captures >= 0 && _capturing < captures)
{
- nrex_node_group* group = NREX_NEW(nrex_node_group(++_capturing));
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_group_capture, ++_capturing));
stack.top()->add_child(group);
stack.push(group);
}
else
{
- nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::NonCapture));
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_group_non_capture));
stack.top()->add_child(group);
stack.push(group);
}
@@ -1098,6 +1149,10 @@ bool nrex::compile(const nrex_char* pattern, int captures)
{
if (stack.size() > 1)
{
+ if (stack.top()->type == nrex_group_look_ahead)
+ {
+ --lookahead_level;
+ }
stack.pop();
}
else
@@ -1107,7 +1162,7 @@ bool nrex::compile(const nrex_char* pattern, int captures)
}
else if (c[0] == '[')
{
- nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_node_group::Bracket));
+ nrex_node_group* group = NREX_NEW(nrex_node_group(nrex_group_bracket));
stack.top()->add_child(group);
if (c[1] == '^')
{
@@ -1410,7 +1465,7 @@ bool nrex::match(const nrex_char* str, nrex_result* captures, int offset, int en
{
return false;
}
- nrex_search s(str, captures);
+ nrex_search s(str, captures, _lookahead_depth);
if (end >= offset)
{
s.end = end;
diff --git a/drivers/nrex/nrex.hpp b/drivers/nrex/nrex.hpp
index 44e950c517..d30b7d0102 100644
--- a/drivers/nrex/nrex.hpp
+++ b/drivers/nrex/nrex.hpp
@@ -1,7 +1,7 @@
// NREX: Node RegEx
-// Version 0.1
+// Version 0.2
//
-// Copyright (c) 2015, Zher Huei Lee
+// Copyright (c) 2015-2016, Zher Huei Lee
// All rights reserved.
//
// This software is provided 'as-is', without any express or implied
@@ -57,7 +57,8 @@ class nrex_node;
class nrex
{
private:
- int _capturing;
+ unsigned int _capturing;
+ unsigned int _lookahead_depth;
nrex_node* _root;
public:
diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp
index e8e8ce4e96..d38f5f3e35 100644
--- a/modules/gdscript/gd_compiler.cpp
+++ b/modules/gdscript/gd_compiler.cpp
@@ -1421,7 +1421,22 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars
if (path.is_rel_path()) {
- String base = p_script->get_path();
+ String base;
+
+ if (p_owner) {
+ GDScript *current_class = p_owner;
+ while (current_class != NULL) {
+ base=current_class->get_path();
+ if (base=="")
+ current_class = current_class->_owner;
+ else
+ break;
+ }
+ }
+ else {
+ base = p_script->get_path();
+ }
+
if (base=="" || base.is_rel_path()) {
_set_error("Could not resolve relative path for parent class: "+path,p_class);
return ERR_FILE_NOT_FOUND;
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
index 9dcad8a533..ce341e2b09 100644
--- a/scene/animation/animation_tree_player.cpp
+++ b/scene/animation/animation_tree_player.cpp
@@ -432,7 +432,7 @@ void AnimationTreePlayer::_notification(int p_what) {
}
-float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_weight, float p_time, bool switched, bool p_seek,const HashMap<NodePath,bool> *p_filter, float p_reverse_weight) {
+float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_weight, float p_time, bool p_seek,const HashMap<NodePath,bool> *p_filter, float p_reverse_weight) {
ERR_FAIL_COND_V(!node_map.has(p_node), 0);
NodeBase *nb=node_map[p_node];
@@ -445,7 +445,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
case NODE_OUTPUT: {
NodeOut *on = static_cast<NodeOut*>(nb);
- return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek);
+ return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek);
} break;
case NODE_ANIMATION: {
@@ -479,9 +479,6 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
an->time=anim_size;
}
- if (switched && an->time >= anim_size) {
- an->time = 0.0;
- }
an->skip=true;
for (List<AnimationNode::TrackRef>::Element *E=an->tref.front();E;E=E->next()) {
@@ -523,13 +520,17 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
if (!osn->active) {
//make it as if this node doesn't exist, pass input 0 by.
- return _process_node(osn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight);
+ return _process_node(osn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight);
}
+ float os_seek = p_seek;
+
if (p_seek)
osn->time=p_time;
- if (osn->start)
+ if (osn->start) {
osn->time=0;
+ os_seek = true;
+ }
float blend;
@@ -554,13 +555,13 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
if (!osn->filter.empty()) {
- main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,switched,p_seek,&osn->filter,p_weight);
- os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,osn->start,p_seek,&osn->filter,-1);
+ main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek,&osn->filter,p_weight);
+ os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,os_seek,&osn->filter,-1);
} else {
- main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,switched,p_seek);
- os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,osn->start,p_seek);
+ main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek);
+ os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,os_seek);
}
if (osn->start) {
@@ -570,8 +571,8 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
if (!p_seek) {
osn->time+=p_time;
- osn->remaining-=p_time;
- if (osn->remaining<0)
+ osn->remaining=os_rem;
+ if (osn->remaining<=0)
osn->active=false;
}
@@ -581,8 +582,8 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
MixNode *mn = static_cast<MixNode*>(nb);
- float rem = _process_node(mn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight);
- _process_node(mn->inputs[1].node,r_prev_anim,p_weight*mn->amount,p_time,switched,p_seek,p_filter,p_reverse_weight);
+ float rem = _process_node(mn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight);
+ _process_node(mn->inputs[1].node,r_prev_anim,p_weight*mn->amount,p_time,p_seek,p_filter,p_reverse_weight);
return rem;
} break;
@@ -593,12 +594,12 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
float rem;
if (!bn->filter.empty()) {
- rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,switched,p_seek,&bn->filter,p_weight);
- _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,&bn->filter,-1);
+ rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,p_seek,&bn->filter,p_weight);
+ _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,&bn->filter,-1);
} else {
- rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value));
- _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value);
+ rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value));
+ _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,p_filter,p_reverse_weight*bn->value);
}
return rem;
@@ -618,19 +619,19 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
upper_blend = bn->value;
}
- rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,switched,p_seek,p_filter,p_reverse_weight*blend);
- _process_node(bn->inputs[2].node,r_prev_anim,p_weight*upper_blend,p_time,switched,p_seek,p_filter,p_reverse_weight*upper_blend);
- _process_node(bn->inputs[0].node,r_prev_anim,p_weight*lower_blend,p_time,switched,p_seek,p_filter,p_reverse_weight*lower_blend);
+ rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,p_seek,p_filter,p_reverse_weight*blend);
+ _process_node(bn->inputs[2].node,r_prev_anim,p_weight*upper_blend,p_time,p_seek,p_filter,p_reverse_weight*upper_blend);
+ _process_node(bn->inputs[0].node,r_prev_anim,p_weight*lower_blend,p_time,p_seek,p_filter,p_reverse_weight*lower_blend);
return rem;
} break;
case NODE_BLEND4: {
Blend4Node *bn = static_cast<Blend4Node*>(nb);
- float rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value.x),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.x));
- _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value.x,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value.x);
- float rem2 = _process_node(bn->inputs[2].node,r_prev_anim,p_weight*(1.0-bn->value.y),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.y));
- _process_node(bn->inputs[3].node,r_prev_anim,p_weight*bn->value.y,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value.y);
+ float rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value.x),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.x));
+ _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value.x,p_time,p_seek,p_filter,p_reverse_weight*bn->value.x);
+ float rem2 = _process_node(bn->inputs[2].node,r_prev_anim,p_weight*(1.0-bn->value.y),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.y));
+ _process_node(bn->inputs[3].node,r_prev_anim,p_weight*bn->value.y,p_time,p_seek,p_filter,p_reverse_weight*bn->value.y);
return MAX(rem,rem2);
@@ -639,9 +640,9 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
TimeScaleNode *tsn = static_cast<TimeScaleNode*>(nb);
float rem;
if (p_seek)
- rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,true,p_filter,p_reverse_weight);
+ rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,true,p_filter,p_reverse_weight);
else
- rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,switched,false,p_filter,p_reverse_weight);
+ rem = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,false,p_filter,p_reverse_weight);
if (tsn->scale == 0)
return INFINITY;
else
@@ -651,68 +652,58 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
case NODE_TIMESEEK: {
TimeSeekNode *tsn = static_cast<TimeSeekNode*>(nb);
- if (tsn->seek_pos>=0) {
+ if (tsn->seek_pos>=0 && !p_seek) {
- float res = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,tsn->seek_pos,switched,true,p_filter,p_reverse_weight);
- tsn->seek_pos=-1;
- return res;
+ p_time = tsn->seek_pos;
+ p_seek = true;
+ }
+ tsn->seek_pos=-1;
- } else
- return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek);
+ return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek);
} break;
case NODE_TRANSITION: {
TransitionNode *tn = static_cast<TransitionNode*>(nb);
- if (tn->prev<0) {
+ if (tn->prev<0) { // process current animation, check for transition
- float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight);
+ float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight);
if (p_seek)
tn->time=p_time;
else
tn->time+=p_time;
- if (tn->input_data[tn->current].auto_advance && rem < tn->xfade) {
+ if (tn->input_data[tn->current].auto_advance && rem <= tn->xfade) {
- tn->prev=tn->current;
- tn->current++;
- if (tn->current>=tn->inputs.size())
- tn->current=0;
- tn->prev_xfading=tn->xfade;
- tn->prev_time=tn->time;
- tn->time=0;
- tn->switched=true;
+ tn->set_current((tn->current+1) % tn->inputs.size());
}
return rem;
- } else {
+ } else { // cross-fading from tn->prev to tn->current
float blend = tn->xfade? (tn->prev_xfading/tn->xfade) : 1;
float rem;
- if (!p_seek && tn->switched) { //just switched
+ if (!p_seek && tn->switched) { //just switched, seek to start of current
- rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),0,true,true,p_filter,p_reverse_weight*(1.0-blend));
+ rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),0,true,p_filter,p_reverse_weight*(1.0-blend));
} else {
- rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-blend));
+ rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),p_time,p_seek,p_filter,p_reverse_weight*(1.0-blend));
}
tn->switched=false;
- //if (!p_seek)
-
-
- if (p_seek) {
- _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,true,false,p_filter,p_reverse_weight*blend);
+ if (p_seek) { // don't seek prev animation
+ _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,false,p_filter,p_reverse_weight*blend);
tn->time=p_time;
} else {
- _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,switched,false,p_filter,p_reverse_weight*blend);
+ _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,false,p_filter,p_reverse_weight*blend);
tn->time+=p_time;
tn->prev_xfading-=p_time;
if (tn->prev_xfading<0) {
@@ -749,10 +740,10 @@ void AnimationTreePlayer::_process_animation(float p_delta) {
AnimationNode *prev=NULL;
if (reset_request) {
- _process_node(out_name,&prev, 1.0, 0, true, true );
+ _process_node(out_name,&prev, 1.0, 0, true);
reset_request=false;
} else
- _process_node(out_name,&prev, 1.0, p_delta, false, false );
+ _process_node(out_name,&prev, 1.0, p_delta);
if (dirty_caches) {
//some animation changed.. ignore this pass
@@ -1158,21 +1149,24 @@ void AnimationTreePlayer::transition_node_set_xfade_time(const StringName& p_nod
n->xfade=p_time;
}
+void AnimationTreePlayer::TransitionNode::set_current(int p_current) {
+ ERR_FAIL_INDEX(p_current,inputs.size());
-void AnimationTreePlayer::transition_node_set_current(const StringName& p_node, int p_current) {
-
- GET_NODE( NODE_TRANSITION, TransitionNode );
- ERR_FAIL_INDEX(p_current,n->inputs.size());
-
- if (n->current==p_current)
+ if (current==p_current)
return;
- n->prev=n->current;
- n->prev_xfading=n->xfade;
- n->prev_time=n->time;
- n->time=0;
- n->current=p_current;
+ prev=current;
+ prev_xfading=xfade;
+ prev_time=time;
+ time=0;
+ current=p_current;
+ switched=true;
+}
+
+void AnimationTreePlayer::transition_node_set_current(const StringName& p_node, int p_current) {
+ GET_NODE( NODE_TRANSITION, TransitionNode );
+ n->set_current(p_current);
}
@@ -1606,6 +1600,7 @@ void AnimationTreePlayer::set_active(bool p_active) {
active = p_active;
processing = active;
+ reset_request = p_active;
_set_process(processing, true);
}
@@ -1623,7 +1618,7 @@ AnimationTreePlayer::ConnectError AnimationTreePlayer::get_last_error() const {
void AnimationTreePlayer::reset() {
- reset_request=false;
+ reset_request=true;
}
@@ -1865,7 +1860,7 @@ AnimationTreePlayer::AnimationTreePlayer() {
processing = false;
active=false;
dirty_caches=true;
- reset_request=false;
+ reset_request=true;
last_error=CONNECT_INCOMPLETE;
base_path=String("..");
}
diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h
index 0fec9a9551..7cc96fc1e3 100644
--- a/scene/animation/animation_tree_player.h
+++ b/scene/animation/animation_tree_player.h
@@ -246,6 +246,7 @@ private:
float xfade;
TransitionNode() { type=NODE_TRANSITION; xfade=0; inputs.resize(1); input_data.resize(1); current=0; prev=-1; prev_time=0; prev_xfading=0; switched=false; }
+ void set_current(int p_current);
};
@@ -267,7 +268,7 @@ private:
Map<StringName,NodeBase*> node_map;
// return time left to finish animation
- float _process_node(const StringName& p_node,AnimationNode **r_prev_anim, float p_weight,float p_step, bool switched, bool p_seek=false,const HashMap<NodePath,bool> *p_filter=NULL, float p_reverse_weight=0);
+ float _process_node(const StringName& p_node,AnimationNode **r_prev_anim, float p_weight,float p_step, bool p_seek=false,const HashMap<NodePath,bool> *p_filter=NULL, float p_reverse_weight=0);
void _process_animation(float p_delta);
bool reset_request;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index a0887ffacd..f7461a736c 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -682,14 +682,12 @@ void TextEdit::_notification(int p_what) {
}
if (cache.line_number_w) {
- Color fcol = cache.font_color;
- fcol.a*=0.4;
String fc = String::num(line+1);
while (fc.length() < line_number_char_count) {
fc="0"+fc;
}
- cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,fcol);
+ cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,cache.line_number_color);
}
const Map<int,Text::ColorRegionInfo>& cri_map=text.get_color_region_info(line);
@@ -3083,6 +3081,7 @@ void TextEdit::_update_caches() {
cache.style_focus=get_stylebox("focus");
cache.font=get_font("font");
cache.caret_color=get_color("caret_color");
+ cache.line_number_color=get_color("line_number_color");
cache.font_color=get_color("font_color");
cache.font_selected_color=get_color("font_selected_color");
cache.keyword_color=get_color("keyword_color");
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 899ce533c4..09c2a4d729 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -74,6 +74,7 @@ class TextEdit : public Control {
Ref<StyleBox> style_focus;
Ref<Font> font;
Color caret_color;
+ Color line_number_color;
Color font_color;
Color font_selected_color;
Color keyword_color;
diff --git a/tools/editor/code_editor.cpp b/tools/editor/code_editor.cpp
index 968d02dfa5..cf8f40430b 100644
--- a/tools/editor/code_editor.cpp
+++ b/tools/editor/code_editor.cpp
@@ -148,6 +148,7 @@ void FindReplaceDialog::_replace_skip_callback() {
void FindReplaceDialog::_replace() {
+ text_edit->begin_complex_operation();
if (is_replace_all_mode()) {
//line as x so it gets priority in comparison, column as y
@@ -228,7 +229,7 @@ void FindReplaceDialog::_replace() {
_search();
}
-
+ text_edit->end_complex_operation();
}
diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp
index 255ad40bce..31da68cb8c 100644
--- a/tools/editor/editor_settings.cpp
+++ b/tools/editor/editor_settings.cpp
@@ -393,6 +393,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("global/show_script_in_scene_tabs",false);
set("text_editor/background_color",Color::html("3b000000"));
set("text_editor/caret_color",Color::html("aaaaaa"));
+ set("text_editor/line_number_color",Color::html("66aaaaaa"));
set("text_editor/text_color",Color::html("aaaaaa"));
set("text_editor/text_selected_color",Color::html("000000"));
set("text_editor/keyword_color",Color::html("ffffb3"));
diff --git a/tools/editor/plugins/script_editor_plugin.cpp b/tools/editor/plugins/script_editor_plugin.cpp
index 5f2efc8f03..6ed44901f1 100644
--- a/tools/editor/plugins/script_editor_plugin.cpp
+++ b/tools/editor/plugins/script_editor_plugin.cpp
@@ -288,6 +288,7 @@ void ScriptTextEditor::_load_theme_settings() {
get_text_edit()->set_custom_bg_color(EDITOR_DEF("text_editor/background_color",Color(0,0,0,0)));
get_text_edit()->add_color_override("font_color",EDITOR_DEF("text_editor/text_color",Color(0,0,0)));
+ get_text_edit()->add_color_override("line_number_color",EDITOR_DEF("text_editor/line_number_color",Color(0,0,0)));
get_text_edit()->add_color_override("caret_color",EDITOR_DEF("text_editor/caret_color",Color(0,0,0)));
get_text_edit()->add_color_override("font_selected_color",EDITOR_DEF("text_editor/text_selected_color",Color(1,1,1)));
get_text_edit()->add_color_override("selection_color",EDITOR_DEF("text_editor/selection_color",Color(0.2,0.2,1)));