mirror of
https://github.com/godotengine/godot.git
synced 2024-11-21 03:18:37 +08:00
-Fix bugs related to PoolVector crashes
-Added ability to request nodes using $Name in GDScript :)
This commit is contained in:
parent
2ab83e1abb
commit
8b912d1115
@ -127,15 +127,30 @@ class PoolVector {
|
||||
|
||||
MemoryPool::alloc_mutex->unlock();
|
||||
|
||||
|
||||
if (MemoryPool::memory_pool) {
|
||||
|
||||
|
||||
} else {
|
||||
alloc->mem = memalloc( alloc->size );
|
||||
copymem( alloc->mem, old_alloc->mem, alloc->size );
|
||||
}
|
||||
|
||||
if (old_alloc->refcount.unref()) {
|
||||
{
|
||||
Write w;
|
||||
w._ref(alloc);
|
||||
Read r;
|
||||
r._ref(old_alloc);
|
||||
|
||||
int cur_elements = alloc->size/sizeof(T);
|
||||
T*dst = (T*)w.ptr();
|
||||
const T*src = (const T*)r.ptr();
|
||||
for(int i=0;i<cur_elements;i++) {
|
||||
memnew_placement(&dst[i],T(src[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (old_alloc->refcount.unref()==true) {
|
||||
//this should never happen but..
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
@ -144,6 +159,17 @@ class PoolVector {
|
||||
MemoryPool::alloc_mutex->unlock();
|
||||
#endif
|
||||
|
||||
{
|
||||
Write w;
|
||||
w._ref(old_alloc);
|
||||
|
||||
int cur_elements = old_alloc->size/sizeof(T);
|
||||
T*elems = (T*)w.ptr();
|
||||
for(int i=0;i<cur_elements;i++) {
|
||||
elems[i].~T();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (MemoryPool::memory_pool) {
|
||||
//resize memory pool
|
||||
@ -151,6 +177,7 @@ class PoolVector {
|
||||
//if some resize
|
||||
} else {
|
||||
|
||||
|
||||
memfree( old_alloc->mem );
|
||||
old_alloc->mem=NULL;
|
||||
old_alloc->size=0;
|
||||
@ -190,7 +217,7 @@ class PoolVector {
|
||||
if (!alloc)
|
||||
return;
|
||||
|
||||
if (!alloc->refcount.unref()) {
|
||||
if (alloc->refcount.unref()==false) {
|
||||
alloc=NULL;
|
||||
return;
|
||||
}
|
||||
@ -199,7 +226,8 @@ class PoolVector {
|
||||
|
||||
{
|
||||
int cur_elements = alloc->size/sizeof(T);
|
||||
Write w;
|
||||
Write w = write();
|
||||
|
||||
for (int i=0;i<cur_elements;i++) {
|
||||
|
||||
w[i].~T();
|
||||
@ -585,7 +613,7 @@ Error PoolVector<T>::resize(int p_size) {
|
||||
} else {
|
||||
|
||||
{
|
||||
Write w;
|
||||
Write w = write();
|
||||
for (int i=p_size;i<cur_elements;i++) {
|
||||
|
||||
w[i].~T();
|
||||
|
@ -265,6 +265,92 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
|
||||
tokenizer->advance();
|
||||
expr=subexpr;
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_DOLLAR) {
|
||||
tokenizer->advance();
|
||||
|
||||
String path;
|
||||
|
||||
bool need_identifier=true;
|
||||
bool done=false;
|
||||
|
||||
while(!done) {
|
||||
|
||||
switch(tokenizer->get_token()) {
|
||||
case GDTokenizer::TK_CURSOR: {
|
||||
completion_cursor=StringName();
|
||||
completion_type=COMPLETION_GET_NODE;
|
||||
completion_class=current_class;
|
||||
completion_function=current_function;
|
||||
completion_line=tokenizer->get_token_line();
|
||||
completion_cursor=path;
|
||||
completion_argument=0;
|
||||
completion_block=current_block;
|
||||
completion_found=true;
|
||||
tokenizer->advance();
|
||||
} break;
|
||||
case GDTokenizer::TK_CONSTANT: {
|
||||
|
||||
if (!need_identifier)
|
||||
break;
|
||||
|
||||
if (tokenizer->get_token_constant().get_type()!=Variant::STRING) {
|
||||
_set_error("Expected string constant or identifier after '$' or '/'.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
path+=String(tokenizer->get_token_constant());
|
||||
tokenizer->advance();
|
||||
|
||||
} break;
|
||||
case GDTokenizer::TK_IDENTIFIER: {
|
||||
|
||||
if (!need_identifier)
|
||||
break;
|
||||
|
||||
path+=String(tokenizer->get_token_identifier());
|
||||
tokenizer->advance();
|
||||
need_identifier=false;
|
||||
|
||||
} break;
|
||||
case GDTokenizer::TK_OP_DIV: {
|
||||
|
||||
if (need_identifier)
|
||||
break;
|
||||
|
||||
path+="/";
|
||||
tokenizer->advance();
|
||||
need_identifier=true;
|
||||
|
||||
} break;
|
||||
default: {
|
||||
done=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path=="") {
|
||||
_set_error("Path expected after $.");
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
OperatorNode *op = alloc_node<OperatorNode>();
|
||||
op->op=OperatorNode::OP_CALL;
|
||||
|
||||
op->arguments.push_back(alloc_node<SelfNode>());
|
||||
|
||||
IdentifierNode *funcname = alloc_node<IdentifierNode>();
|
||||
funcname->name="get_node";
|
||||
|
||||
op->arguments.push_back(funcname);
|
||||
|
||||
ConstantNode *nodepath = alloc_node<ConstantNode>();
|
||||
nodepath->value = NodePath(StringName(path));
|
||||
op->arguments.push_back(nodepath);
|
||||
|
||||
expr=op;
|
||||
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_CURSOR) {
|
||||
tokenizer->advance();
|
||||
continue; //no point in cursor in the middle of expression
|
||||
|
@ -376,6 +376,7 @@ public:
|
||||
enum CompletionType {
|
||||
COMPLETION_NONE,
|
||||
COMPLETION_BUILT_IN_TYPE_CONSTANT,
|
||||
COMPLETION_GET_NODE,
|
||||
COMPLETION_FUNCTION,
|
||||
COMPLETION_IDENTIFIER,
|
||||
COMPLETION_PARENT_FUNCTION,
|
||||
|
@ -460,6 +460,9 @@ void GDTokenizerText::_advance() {
|
||||
case ':':
|
||||
_make_token(TK_COLON); //for methods maybe but now useless.
|
||||
break;
|
||||
case '$':
|
||||
_make_token(TK_DOLLAR); //for the get_node() shortener
|
||||
break;
|
||||
case '^': {
|
||||
if (GETCHAR(1)=='=') {
|
||||
_make_token(TK_OP_ASSIGN_BIT_XOR);
|
||||
|
@ -123,6 +123,7 @@ public:
|
||||
TK_PERIOD,
|
||||
TK_QUESTION_MARK,
|
||||
TK_COLON,
|
||||
TK_DOLLAR,
|
||||
TK_NEWLINE,
|
||||
TK_CONST_PI,
|
||||
TK_ERROR,
|
||||
|
Loading…
Reference in New Issue
Block a user