3D Physics Rework, Other Stuff
-=-=-=-=-=-=-=-=-=-=-=-=-=-
3D Physics:
-Fixed "Bounce" parameter in 3D
-Fixed bug affecting Area (sometims it would not detect properly)
-Vehicle Body has seen heavy work
-Added Query API for doing space queries in 3D. Needs some docs though.
-Added JOINTS! Adapted Bullet Joints: and created easy gizmos for setting them up:
-PinJoint
-HingeJoint (with motor)
-SliderJoint
-ConeTwistJoint
-Generic6DOFJoint
-Added OBJECT PICKING! based on the new query API. Any physics object now (Area or Body) has the following signals and virtual functions:
-input_event (mouse or multitouch input over the body)
-mouse_enter (mouse entered the body area)
-mouse_exit (mouse exited body area)
For Area it needs to be activated manually, as it isn't by default (ray goes thru).
Other:
-Begun working on Windows 8 (RT) port. Compiles but does not work yet.
-Added TheoraPlayer library for improved to-texture and portable video support.
-Fixed a few bugs in the renderer, collada importer, collada exporter, etc.
This commit is contained in:
parent
1a2cb755e2
commit
8cab401d08
217 changed files with 81476 additions and 8145 deletions
|
|
@ -60,7 +60,8 @@ bool GDCompiler::_create_unary_operator(CodeGen& codegen,const GDParser::Operato
|
|||
codegen.opcodes.push_back(GDFunction::OPCODE_OPERATOR); // perform operator
|
||||
codegen.opcodes.push_back(op); //which operator
|
||||
codegen.opcodes.push_back(src_address_a); // argument 1
|
||||
codegen.opcodes.push_back(GDFunction::ADDR_TYPE_NIL); // argument 2 (unary only takes one parameter)
|
||||
codegen.opcodes.push_back(src_address_a); // argument 2 (repeated)
|
||||
//codegen.opcodes.push_back(GDFunction::ADDR_TYPE_NIL); // argument 2 (unary only takes one parameter)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -507,6 +508,34 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
|
|||
codegen.opcodes.push_back(arguments[i]);
|
||||
}
|
||||
} break;
|
||||
case GDParser::OperatorNode::OP_YIELD: {
|
||||
|
||||
|
||||
ERR_FAIL_COND_V(on->arguments.size() && on->arguments.size()!=2,-1);
|
||||
|
||||
Vector<int> arguments;
|
||||
int slevel = p_stack_level;
|
||||
for(int i=0;i<on->arguments.size();i++) {
|
||||
|
||||
int ret = _parse_expression(codegen,on->arguments[i],slevel);
|
||||
if (ret<0)
|
||||
return ret;
|
||||
if (ret&GDFunction::ADDR_TYPE_STACK<<GDFunction::ADDR_BITS) {
|
||||
slevel++;
|
||||
codegen.alloc_stack(slevel);
|
||||
}
|
||||
arguments.push_back(ret);
|
||||
}
|
||||
|
||||
//push call bytecode
|
||||
codegen.opcodes.push_back(arguments.size()==0?GDFunction::OPCODE_YIELD:GDFunction::OPCODE_YIELD_SIGNAL); // basic type constructor
|
||||
for(int i=0;i<arguments.size();i++)
|
||||
codegen.opcodes.push_back(arguments[i]); //arguments
|
||||
codegen.opcodes.push_back(GDFunction::OPCODE_YIELD_RESUME);
|
||||
//next will be where to place the result :)
|
||||
|
||||
} break;
|
||||
|
||||
//indexing operator
|
||||
case GDParser::OperatorNode::OP_INDEX:
|
||||
case GDParser::OperatorNode::OP_INDEX_NAMED: {
|
||||
|
|
@ -644,8 +673,8 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
|
|||
case GDParser::OperatorNode::OP_BIT_OR: { if (!_create_binary_operator(codegen,on,Variant::OP_BIT_OR,p_stack_level)) return -1;} break;
|
||||
case GDParser::OperatorNode::OP_BIT_XOR: { if (!_create_binary_operator(codegen,on,Variant::OP_BIT_XOR,p_stack_level)) return -1;} break;
|
||||
//shift
|
||||
case GDParser::OperatorNode::OP_SHIFT_LEFT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_LEFT,p_stack_level)) return -1;} break;
|
||||
case GDParser::OperatorNode::OP_SHIFT_RIGHT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_RIGHT,p_stack_level)) return -1;} break;
|
||||
case GDParser::OperatorNode::OP_SHIFT_LEFT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_LEFT,p_stack_level)) return -1;} break;
|
||||
case GDParser::OperatorNode::OP_SHIFT_RIGHT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_RIGHT,p_stack_level)) return -1;} break;
|
||||
//assignment operators
|
||||
case GDParser::OperatorNode::OP_ASSIGN_ADD:
|
||||
case GDParser::OperatorNode::OP_ASSIGN_SUB:
|
||||
|
|
|
|||
|
|
@ -256,6 +256,55 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
|||
tokenizer->advance();
|
||||
|
||||
expr=constant;
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_PR_YIELD) {
|
||||
|
||||
//constant defined by tokenizer
|
||||
|
||||
tokenizer->advance();
|
||||
if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_OPEN) {
|
||||
_set_error("Expected '(' after 'yield'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tokenizer->advance();
|
||||
|
||||
OperatorNode *yield = alloc_node<OperatorNode>();
|
||||
yield->op=OperatorNode::OP_YIELD;
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) {
|
||||
expr=yield;
|
||||
tokenizer->advance();
|
||||
} else {
|
||||
|
||||
Node *object = _parse_and_reduce_expression(p_parent,p_static);
|
||||
if (!object)
|
||||
return NULL;
|
||||
yield->arguments.push_back(object);
|
||||
|
||||
if (tokenizer->get_token()!=GDTokenizer::TK_COMMA) {
|
||||
|
||||
_set_error("Expected ',' after first argument of 'yield'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tokenizer->advance();
|
||||
|
||||
Node *signal = _parse_and_reduce_expression(p_parent,p_static);
|
||||
if (!signal)
|
||||
return NULL;
|
||||
yield->arguments.push_back(signal);
|
||||
|
||||
if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
|
||||
|
||||
_set_error("Expected ')' after second argument of 'yield'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tokenizer->advance();
|
||||
|
||||
expr=yield;
|
||||
}
|
||||
|
||||
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_SELF) {
|
||||
|
||||
|
|
@ -1067,6 +1116,10 @@ GDParser::Node* GDParser::_reduce_expression(Node *p_node,bool p_to_const) {
|
|||
}
|
||||
|
||||
return op; //don't reduce yet
|
||||
|
||||
} else if (op->op==OperatorNode::OP_YIELD) {
|
||||
return op;
|
||||
|
||||
} else if (op->op==OperatorNode::OP_INDEX) {
|
||||
//can reduce indices into constant arrays or dictionaries
|
||||
|
||||
|
|
|
|||
|
|
@ -183,6 +183,7 @@ public:
|
|||
//call/constructor operator
|
||||
OP_CALL,
|
||||
OP_PARENT_CALL,
|
||||
OP_YIELD,
|
||||
OP_EXTENDS,
|
||||
//indexing operator
|
||||
OP_INDEX,
|
||||
|
|
@ -225,7 +226,7 @@ public:
|
|||
OP_ASSIGN_BIT_XOR,
|
||||
OP_BIT_AND,
|
||||
OP_BIT_OR,
|
||||
OP_BIT_XOR
|
||||
OP_BIT_XOR,
|
||||
};
|
||||
|
||||
Operator op;
|
||||
|
|
@ -258,6 +259,7 @@ public:
|
|||
Node* condition;
|
||||
AssertNode() { type=TYPE_ASSERT; }
|
||||
};
|
||||
|
||||
struct NewLineNode : public Node {
|
||||
int line;
|
||||
NewLineNode() { type=TYPE_NEWLINE; }
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ static String _get_var_type(const Variant* p_type) {
|
|||
|
||||
}
|
||||
|
||||
Variant GDFunction::call(GDInstance *p_instance,const Variant **p_args, int p_argcount,Variant::CallError& r_err) {
|
||||
Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError& r_err, CallState *p_state) {
|
||||
|
||||
|
||||
if (!_code_ptr) {
|
||||
|
|
@ -205,77 +205,91 @@ Variant GDFunction::call(GDInstance *p_instance,const Variant **p_args, int p_ar
|
|||
|
||||
#endif
|
||||
|
||||
if (p_argcount!=_argument_count) {
|
||||
uint32_t alloca_size=0;
|
||||
GDScript *_class;
|
||||
int ip=0;
|
||||
int line=_initial_line;
|
||||
|
||||
if (p_argcount>_argument_count) {
|
||||
if (p_state) {
|
||||
//use existing (supplied) state (yielded)
|
||||
stack=(Variant*)p_state->stack.ptr();
|
||||
call_args=(Variant**)&p_state->stack[sizeof(Variant)*p_state->stack_size];
|
||||
line=p_state->line;
|
||||
ip=p_state->ip;
|
||||
alloca_size=p_state->stack.size();
|
||||
_class=p_state->_class;
|
||||
p_instance=p_state->instance;
|
||||
defarg=p_state->defarg;
|
||||
self=p_state->self;
|
||||
//stack[p_state->result_pos]=p_state->result; //assign stack with result
|
||||
|
||||
r_err.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_err.argument=_argument_count;
|
||||
} else {
|
||||
|
||||
return Variant();
|
||||
} else if (p_argcount < _argument_count - _default_arg_count) {
|
||||
if (p_argcount!=_argument_count) {
|
||||
|
||||
r_err.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_err.argument=_argument_count - _default_arg_count;
|
||||
return Variant();
|
||||
} else {
|
||||
if (p_argcount>_argument_count) {
|
||||
|
||||
defarg=_argument_count-p_argcount;
|
||||
r_err.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
|
||||
r_err.argument=_argument_count;
|
||||
|
||||
return Variant();
|
||||
} else if (p_argcount < _argument_count - _default_arg_count) {
|
||||
|
||||
r_err.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_err.argument=_argument_count - _default_arg_count;
|
||||
return Variant();
|
||||
} else {
|
||||
|
||||
defarg=_argument_count-p_argcount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t alloca_size = sizeof(Variant*)*_call_size + sizeof(Variant)*_stack_size;
|
||||
alloca_size = sizeof(Variant*)*_call_size + sizeof(Variant)*_stack_size;
|
||||
|
||||
if (alloca_size) {
|
||||
if (alloca_size) {
|
||||
|
||||
uint8_t *aptr = (uint8_t*)alloca(alloca_size);
|
||||
uint8_t *aptr = (uint8_t*)alloca(alloca_size);
|
||||
|
||||
if (_stack_size) {
|
||||
|
||||
stack=(Variant*)aptr;
|
||||
for(int i=0;i<p_argcount;i++)
|
||||
memnew_placement(&stack[i],Variant(*p_args[i]));
|
||||
for(int i=p_argcount;i<_stack_size;i++)
|
||||
memnew_placement(&stack[i],Variant);
|
||||
} else {
|
||||
stack=NULL;
|
||||
}
|
||||
|
||||
if (_call_size) {
|
||||
|
||||
call_args = (Variant**)&aptr[sizeof(Variant)*_stack_size];
|
||||
} else {
|
||||
|
||||
call_args=NULL;
|
||||
}
|
||||
|
||||
if (_stack_size) {
|
||||
|
||||
stack=(Variant*)aptr;
|
||||
for(int i=0;i<p_argcount;i++)
|
||||
memnew_placement(&stack[i],Variant(*p_args[i]));
|
||||
for(int i=p_argcount;i<_stack_size;i++)
|
||||
memnew_placement(&stack[i],Variant);
|
||||
} else {
|
||||
stack=NULL;
|
||||
}
|
||||
|
||||
if (_call_size) {
|
||||
|
||||
call_args = (Variant**)&aptr[sizeof(Variant)*_stack_size];
|
||||
} else {
|
||||
|
||||
call_args=NULL;
|
||||
}
|
||||
|
||||
if (p_instance) {
|
||||
if (p_instance->base_ref && static_cast<Reference*>(p_instance->owner)->is_referenced()) {
|
||||
|
||||
} else {
|
||||
stack=NULL;
|
||||
call_args=NULL;
|
||||
}
|
||||
|
||||
|
||||
GDScript *_class;
|
||||
|
||||
if (p_instance) {
|
||||
if (p_instance->base_ref && static_cast<Reference*>(p_instance->owner)->is_referenced()) {
|
||||
|
||||
self=REF(static_cast<Reference*>(p_instance->owner));
|
||||
self=REF(static_cast<Reference*>(p_instance->owner));
|
||||
} else {
|
||||
self=p_instance->owner;
|
||||
}
|
||||
_class=p_instance->script.ptr();
|
||||
} else {
|
||||
self=p_instance->owner;
|
||||
_class=_script;
|
||||
}
|
||||
_class=p_instance->script.ptr();
|
||||
} else {
|
||||
_class=_script;
|
||||
}
|
||||
|
||||
int ip=0;
|
||||
int line=_initial_line;
|
||||
String err_text;
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
if (ScriptDebugger::get_singleton())
|
||||
|
|
@ -783,6 +797,97 @@ Variant GDFunction::call(GDInstance *p_instance,const Variant **p_args, int p_ar
|
|||
|
||||
ip+=4+argc;
|
||||
|
||||
} continue;
|
||||
case OPCODE_YIELD:
|
||||
case OPCODE_YIELD_SIGNAL: {
|
||||
|
||||
int ipofs=1;
|
||||
if (_code_ptr[ip]==OPCODE_YIELD_SIGNAL) {
|
||||
CHECK_SPACE(4);
|
||||
ipofs+=2;
|
||||
} else {
|
||||
CHECK_SPACE(2);
|
||||
|
||||
}
|
||||
|
||||
Ref<GDFunctionState> gdfs = memnew( GDFunctionState );
|
||||
gdfs->function=this;
|
||||
|
||||
gdfs->state.stack.resize(alloca_size);
|
||||
//copy variant stack
|
||||
for(int i=0;i<_stack_size;i++) {
|
||||
memnew_placement(&stack[sizeof(Variant)*i],Variant(stack[i]));
|
||||
}
|
||||
gdfs->state.stack_size=_stack_size;
|
||||
gdfs->state.self=self;
|
||||
gdfs->state.alloca_size=alloca_size;
|
||||
gdfs->state._class=_class;
|
||||
gdfs->state.ip=ip+ipofs;
|
||||
gdfs->state.line=line;
|
||||
//gdfs->state.result_pos=ip+ipofs-1;
|
||||
gdfs->state.defarg=defarg;
|
||||
gdfs->state.instance=p_instance;
|
||||
gdfs->function=this;
|
||||
|
||||
retvalue=gdfs;
|
||||
|
||||
if (_code_ptr[ip]==OPCODE_YIELD_SIGNAL) {
|
||||
GET_VARIANT_PTR(argobj,1);
|
||||
GET_VARIANT_PTR(argname,2);
|
||||
//do the oneshot connect
|
||||
|
||||
if (argobj->get_type()!=Variant::OBJECT) {
|
||||
err_text="First argument of yield() not of type object.";
|
||||
break;
|
||||
}
|
||||
if (argname->get_type()!=Variant::STRING) {
|
||||
err_text="Second argument of yield() not a string (for signal name).";
|
||||
break;
|
||||
}
|
||||
Object *obj=argobj->operator Object *();
|
||||
String signal = argname->operator String();
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
if (!obj) {
|
||||
err_text="First argument of yield() is null.";
|
||||
break;
|
||||
}
|
||||
if (ScriptDebugger::get_singleton()) {
|
||||
if (!ObjectDB::instance_validate(obj)) {
|
||||
err_text="First argument of yield() is a previously freed instance.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (signal.length()==0) {
|
||||
|
||||
err_text="Second argument of yield() is an empty string (for signal name).";
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
Error err = obj->connect(signal,gdfs.ptr(),"_signal_callback",varray(gdfs),Object::CONNECT_ONESHOT);
|
||||
if (err!=OK) {
|
||||
err_text="Error connecting to signal: "+signal+" during yield().";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
exit_ok=true;
|
||||
|
||||
} break;
|
||||
case OPCODE_YIELD_RESUME: {
|
||||
|
||||
CHECK_SPACE(2);
|
||||
if (!p_state) {
|
||||
err_text=("Invalid Resume (bug?)");
|
||||
break;
|
||||
}
|
||||
GET_VARIANT_PTR(result,1);
|
||||
*result=p_state->result;
|
||||
ip+=2;
|
||||
|
||||
} continue;
|
||||
case OPCODE_JUMP: {
|
||||
|
||||
|
|
@ -1168,6 +1273,93 @@ GDFunction::GDFunction() {
|
|||
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
|
||||
|
||||
Variant GDFunctionState::_signal_callback(const Variant** p_args, int p_argcount, Variant::CallError& r_error) {
|
||||
|
||||
Variant arg;
|
||||
r_error.error=Variant::CallError::CALL_OK;
|
||||
|
||||
ERR_FAIL_COND_V(!function,Variant());
|
||||
|
||||
if (p_argcount==0) {
|
||||
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument=1;
|
||||
return Variant();
|
||||
} else if (p_argcount==1) {
|
||||
//noooneee
|
||||
} else if (p_argcount==2) {
|
||||
arg=*p_args[0];
|
||||
} else {
|
||||
Array extra_args;
|
||||
for(int i=0;i<p_argcount-1;i++) {
|
||||
extra_args.push_back(*p_args[i]);
|
||||
}
|
||||
arg=extra_args;
|
||||
}
|
||||
|
||||
Ref<GDFunctionState> self = *p_args[p_argcount-1];
|
||||
|
||||
if (self.is_null()) {
|
||||
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||
r_error.argument=p_argcount-1;
|
||||
r_error.expected=Variant::OBJECT;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
state.result=arg;
|
||||
Variant ret = function->call(NULL,NULL,0,r_error,&state);
|
||||
function=NULL; //cleaned up;
|
||||
state.result=Variant();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
bool GDFunctionState::is_valid() const {
|
||||
|
||||
return function!=NULL;
|
||||
}
|
||||
|
||||
Variant GDFunctionState::resume(const Variant& p_arg) {
|
||||
|
||||
ERR_FAIL_COND_V(!function,Variant());
|
||||
|
||||
state.result=p_arg;
|
||||
Variant::CallError err;
|
||||
Variant ret = function->call(NULL,NULL,0,err,&state);
|
||||
function=NULL; //cleaned up;
|
||||
state.result=Variant();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void GDFunctionState::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("resume:var","arg"),&GDFunctionState::resume,DEFVAL(Variant()));
|
||||
ObjectTypeDB::bind_method(_MD("is_valid"),&GDFunctionState::is_valid);
|
||||
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"_signal_callback",&GDFunctionState::_signal_callback,MethodInfo("_signal_callback"));
|
||||
|
||||
}
|
||||
|
||||
GDFunctionState::GDFunctionState() {
|
||||
|
||||
function=NULL;
|
||||
}
|
||||
|
||||
GDFunctionState::~GDFunctionState() {
|
||||
|
||||
if (function!=NULL) {
|
||||
//never called, deinitialize stack
|
||||
for(int i=0;i<state.stack_size;i++) {
|
||||
Variant *v=(Variant*)&state.stack[sizeof(Variant)*i];
|
||||
v->~Variant();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
|
||||
GDNativeClass::GDNativeClass(const StringName& p_name) {
|
||||
|
||||
name=p_name;
|
||||
|
|
@ -2183,6 +2375,8 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
|
|||
"or",
|
||||
"export",
|
||||
"assert",
|
||||
"yield",
|
||||
"static",
|
||||
0};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
class GDInstance;
|
||||
class GDScript;
|
||||
|
||||
|
||||
|
||||
class GDFunction {
|
||||
public:
|
||||
|
||||
|
|
@ -58,6 +60,9 @@ public:
|
|||
OPCODE_CALL_BUILT_IN,
|
||||
OPCODE_CALL_SELF,
|
||||
OPCODE_CALL_SELF_BASE,
|
||||
OPCODE_YIELD,
|
||||
OPCODE_YIELD_SIGNAL,
|
||||
OPCODE_YIELD_RESUME,
|
||||
OPCODE_JUMP,
|
||||
OPCODE_JUMP_IF,
|
||||
OPCODE_JUMP_IF_NOT,
|
||||
|
|
@ -132,6 +137,20 @@ friend class GDCompiler;
|
|||
|
||||
public:
|
||||
|
||||
struct CallState {
|
||||
|
||||
GDInstance *instance;
|
||||
Vector<uint8_t> stack;
|
||||
int stack_size;
|
||||
Variant self;
|
||||
uint32_t alloca_size;
|
||||
GDScript *_class;
|
||||
int ip;
|
||||
int line;
|
||||
int defarg;
|
||||
Variant result;
|
||||
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ bool is_static() const { return _static; }
|
||||
|
||||
|
|
@ -150,12 +169,30 @@ public:
|
|||
_FORCE_INLINE_ bool is_empty() const { return _code_size==0; }
|
||||
|
||||
int get_argument_count() const { return _argument_count; }
|
||||
Variant call(GDInstance *p_instance,const Variant **p_args, int p_argcount,Variant::CallError& r_err);
|
||||
Variant call(GDInstance *p_instance,const Variant **p_args, int p_argcount,Variant::CallError& r_err,CallState *p_state=NULL);
|
||||
|
||||
GDFunction();
|
||||
};
|
||||
|
||||
|
||||
class GDFunctionState : public Reference {
|
||||
|
||||
OBJ_TYPE(GDFunctionState,Reference);
|
||||
friend class GDFunction;
|
||||
GDFunction *function;
|
||||
GDFunction::CallState state;
|
||||
Variant _signal_callback(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
bool is_valid() const;
|
||||
Variant resume(const Variant& p_arg=Variant());
|
||||
GDFunctionState();
|
||||
~GDFunctionState();
|
||||
};
|
||||
|
||||
|
||||
class GDNativeClass : public Reference {
|
||||
|
||||
OBJ_TYPE(GDNativeClass,Reference);
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ const char* GDTokenizer::token_names[TK_MAX]={
|
|||
"var",
|
||||
"preload",
|
||||
"assert",
|
||||
"yield",
|
||||
"'['",
|
||||
"']'",
|
||||
"'{'",
|
||||
|
|
@ -826,6 +827,7 @@ void GDTokenizerText::_advance() {
|
|||
{TK_PR_VAR,"var"},
|
||||
{TK_PR_PRELOAD,"preload"},
|
||||
{TK_PR_ASSERT,"assert"},
|
||||
{TK_PR_YIELD,"yield"},
|
||||
{TK_PR_CONST,"const"},
|
||||
//controlflow
|
||||
{TK_CF_IF,"if"},
|
||||
|
|
@ -1006,7 +1008,7 @@ void GDTokenizerText::advance(int p_amount) {
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define BYTECODE_VERSION 1
|
||||
#define BYTECODE_VERSION 2
|
||||
|
||||
Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) {
|
||||
|
||||
|
|
@ -1016,8 +1018,8 @@ Error GDTokenizerBuffer::set_code_buffer(const Vector<uint8_t> & p_buffer) {
|
|||
ERR_FAIL_COND_V( p_buffer.size()<24 || p_buffer[0]!='G' || p_buffer[1]!='D' || p_buffer[2]!='S' || p_buffer[3]!='C',ERR_INVALID_DATA);
|
||||
|
||||
int version = decode_uint32(&buf[4]);
|
||||
if (version>1) {
|
||||
ERR_EXPLAIN("Bytecode is too New!");
|
||||
if (version>BYTECODE_VERSION) {
|
||||
ERR_EXPLAIN("Bytecode is too New! Please use a newer engine version.");
|
||||
ERR_FAIL_COND_V(version>BYTECODE_VERSION,ERR_INVALID_DATA);
|
||||
}
|
||||
int identifier_count = decode_uint32(&buf[8]);
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ public:
|
|||
TK_PR_VAR,
|
||||
TK_PR_PRELOAD,
|
||||
TK_PR_ASSERT,
|
||||
TK_PR_YIELD,
|
||||
TK_BRACKET_OPEN,
|
||||
TK_BRACKET_CLOSE,
|
||||
TK_CURLY_BRACKET_OPEN,
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ void register_gdscript_types() {
|
|||
ResourceLoader::add_resource_format_loader(resource_loader_gd);
|
||||
resource_saver_gd=memnew( ResourceFormatSaverGDScript );
|
||||
ResourceSaver::add_resource_format_saver(resource_saver_gd);
|
||||
ObjectTypeDB::register_virtual_type<GDFunctionState>();
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue