diff options
Diffstat (limited to 'core')
| -rw-r--r-- | core/dvector.h | 28 | ||||
| -rw-r--r-- | core/func_ref.cpp | 6 | ||||
| -rw-r--r-- | core/image.cpp | 1 | ||||
| -rw-r--r-- | core/io/file_access_pack.cpp | 2 | ||||
| -rw-r--r-- | core/math/a_star.cpp | 412 | ||||
| -rw-r--r-- | core/math/a_star.h | 92 | ||||
| -rw-r--r-- | core/math/triangulate.cpp | 5 | ||||
| -rw-r--r-- | core/math/vector3.cpp | 10 | ||||
| -rw-r--r-- | core/method_bind.h | 19 | ||||
| -rw-r--r-- | core/object.cpp | 25 | ||||
| -rw-r--r-- | core/object_type_db.cpp | 181 | ||||
| -rw-r--r-- | core/object_type_db.h | 19 | ||||
| -rw-r--r-- | core/register_core_types.cpp | 2 | ||||
| -rw-r--r-- | core/script_debugger_remote.cpp | 6 | ||||
| -rw-r--r-- | core/script_language.h | 20 | ||||
| -rw-r--r-- | core/undo_redo.cpp | 16 | ||||
| -rw-r--r-- | core/variant_call.cpp | 2 |
17 files changed, 782 insertions, 64 deletions
diff --git a/core/dvector.h b/core/dvector.h index a5519ed60..9a5464161 100644 --- a/core/dvector.h +++ b/core/dvector.h @@ -262,6 +262,34 @@ public: w[bs+i]=r[i]; } + DVector<T> subarray(int p_from, int p_to) { + + if (p_from<0) { + p_from=size()+p_from; + } + if (p_to<0) { + p_to=size()+p_to; + } + if (p_from<0 || p_from>=size()) { + DVector<T>& aux=*((DVector<T>*)0); // nullreturn + ERR_FAIL_COND_V(p_from<0 || p_from>=size(),aux) + } + if (p_to<0 || p_to>=size()) { + DVector<T>& aux=*((DVector<T>*)0); // nullreturn + ERR_FAIL_COND_V(p_to<0 || p_to>=size(),aux) + } + + DVector<T> slice; + int span=1 + p_to - p_from; + slice.resize(span); + Read r = read(); + Write w = slice.write(); + for (int i=0; i<span; ++i) { + w[i] = r[p_from+i]; + } + + return slice; + } Error insert(int p_pos,const T& p_val) { diff --git a/core/func_ref.cpp b/core/func_ref.cpp index 644d8b5b6..ca890111b 100644 --- a/core/func_ref.cpp +++ b/core/func_ref.cpp @@ -61,11 +61,7 @@ void FuncRef::_bind_methods() { MethodInfo mi; mi.name="call_func"; Vector<Variant> defargs; - for(int i=0;i<10;i++) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_func:Variant",&FuncRef::call_func,mi,defargs); + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call_func:Variant",&FuncRef::call_func,mi,defargs); } diff --git a/core/image.cpp b/core/image.cpp index d6ac3f28e..90051d7d0 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -2052,6 +2052,7 @@ Error Image::_decompress_bc() { ht/=2; } break; + default: {} } } diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 5c8c741f2..1632b841c 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -409,6 +409,8 @@ Error DirAccessPack::change_dir(String p_dir) { nd=nd.simplify_path(); + if (nd == "") nd = "."; + if (nd.begins_with("/")) { nd=nd.replace_first("/","") ; absolute=true; diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp new file mode 100644 index 000000000..5bbbbdaa5 --- /dev/null +++ b/core/math/a_star.cpp @@ -0,0 +1,412 @@ +#include "a_star.h" +#include "geometry.h" + + +int AStar::get_available_point_id() const { + + if (points.empty()) { + return 1; + } + + return points.back()->key()+1; +} + +void AStar::add_point(int p_id, const Vector3 &p_pos, float p_weight_scale) { + ERR_FAIL_COND(p_id<0); + if (!points.has(p_id)) { + Point *pt = memnew( Point ); + pt->id=p_id; + pt->pos=p_pos; + pt->weight_scale=p_weight_scale; + pt->prev_point=NULL; + pt->last_pass=0; + points[p_id]=pt; + } else { + points[p_id]->pos=p_pos; + points[p_id]->weight_scale=p_weight_scale; + } +} + +Vector3 AStar::get_point_pos(int p_id) const{ + + ERR_FAIL_COND_V(!points.has(p_id),Vector3()); + + return points[p_id]->pos; + +} +float AStar::get_point_weight_scale(int p_id) const{ + + ERR_FAIL_COND_V(!points.has(p_id),0); + + return points[p_id]->weight_scale; + +} +void AStar::remove_point(int p_id){ + + ERR_FAIL_COND(!points.has(p_id)); + + Point* p = points[p_id]; + + for(int i=0;i<p->neighbours.size();i++) { + + Segment s(p_id,p->neighbours[i]->id); + segments.erase(s); + p->neighbours[i]->neighbours.erase(p); + } + + memdelete(p); + points.erase(p_id); +} + +void AStar::connect_points(int p_id,int p_with_id){ + + ERR_FAIL_COND(!points.has(p_id)); + ERR_FAIL_COND(!points.has(p_with_id)); + ERR_FAIL_COND(p_id==p_with_id); + + + Point* a = points[p_id]; + Point* b = points[p_with_id]; + a->neighbours.push_back(b); + b->neighbours.push_back(a); + + Segment s(p_id,p_with_id); + if (s.from==p_id) { + s.from_point=a; + s.to_point=b; + } else { + s.from_point=b; + s.to_point=a; + } + + segments.insert(s); + + +} +void AStar::disconnect_points(int p_id,int p_with_id){ + + Segment s(p_id,p_with_id); + ERR_FAIL_COND(!segments.has(s)); + + + segments.erase(s); + + Point *a = points[p_id]; + Point *b = points[p_with_id]; + a->neighbours.erase(b); + b->neighbours.erase(a); + +} +bool AStar::are_points_connected(int p_id,int p_with_id) const{ + + Segment s(p_id,p_with_id); + return segments.has(s); +} + +void AStar::clear(){ + + for (const Map<int,Point*>::Element *E=points.front();E;E=E->next()) { + + memdelete(E->get()); + } + segments.clear(); + points.clear(); +} + + +int AStar::get_closest_point(const Vector3& p_point) const{ + + int closest_id=-1; + float closest_dist=1e20; + + for (const Map<int,Point*>::Element *E=points.front();E;E=E->next()) { + + float d = p_point.distance_squared_to(E->get()->pos); + if (closest_id<0 || d<closest_dist) { + closest_dist=d; + closest_id=E->key(); + } + } + + return closest_id; + + +} +Vector3 AStar::get_closest_pos_in_segment(const Vector3& p_point) const { + + float closest_dist = 1e20; + bool found=false; + Vector3 closest_point; + + + for (const Set<Segment>::Element *E=segments.front();E;E=E->next()) { + + Vector3 segment[2]={ + E->get().from_point->pos, + E->get().to_point->pos, + }; + + Vector3 p = Geometry::get_closest_point_to_segment(p_point,segment); + float d = p_point.distance_squared_to(p); + if (!found || d<closest_dist) { + + closest_point=p; + closest_dist=d; + found=true; + } + } + + return closest_point; +} + +bool AStar::_solve(Point* begin_point, Point* end_point) { + + pass++; + + SelfList<Point>::List open_list; + + bool found_route=false; + + + for(int i=0;i<begin_point->neighbours.size();i++) { + + Point *n = begin_point->neighbours[i]; + n->prev_point=begin_point; + n->distance=n->pos.distance_to(begin_point->pos); + n->distance*=n->weight_scale; + n->last_pass=pass; + open_list.add(&n->list); + + if (end_point==n) { + found_route=true; + break; + } + } + + while(!found_route) { + + if (open_list.first()==NULL) { + //could not find path sadly + break; + } + //check open list + + SelfList<Point> *least_cost_point=NULL; + float least_cost=1e30; + + //this could be faster (cache previous results) + for (SelfList<Point> *E=open_list.first();E;E=E->next()) { + + Point *p=E->self(); + + float cost=p->distance; + cost+=p->pos.distance_to(end_point->pos); + cost*=p->weight_scale; + + if (cost<least_cost) { + + least_cost_point=E; + least_cost=cost; + } + } + + + Point *p=least_cost_point->self(); + //open the neighbours for search + int es = p->neighbours.size(); + + for(int i=0;i<es;i++) { + + + Point* e=p->neighbours[i]; + + + float distance = p->pos.distance_to(e->pos) + p->distance; + distance*=e->weight_scale; + + + + if (e->last_pass==pass) { + //oh this was visited already, can we win the cost? + + if (e->distance>distance) { + + e->prev_point=p; + e->distance=distance; + } + } else { + //add to open neighbours + + e->prev_point=p; + e->distance=distance; + e->last_pass=pass; //mark as used + open_list.add(&e->list); + + if (e==end_point) { + //oh my reached end! stop algorithm + found_route=true; + break; + + } + + } + } + + if (found_route) + break; + + open_list.remove(least_cost_point); + } + + //clear the openf list + while(open_list.first()) { + open_list.remove( open_list.first() ); + } + + return found_route; + +} + +DVector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) { + + ERR_FAIL_COND_V(!points.has(p_from_id),DVector<Vector3>()); + ERR_FAIL_COND_V(!points.has(p_to_id),DVector<Vector3>()); + + + pass++; + + Point* a = points[p_from_id]; + Point* b = points[p_to_id]; + + if (a==b) { + DVector<Vector3> ret; + ret.push_back(a->pos); + return ret; + } + + + Point *begin_point=a; + Point *end_point=b; + + bool found_route=_solve(begin_point,end_point); + + if (!found_route) + return DVector<Vector3>(); + + //midpoints + Point *p=end_point; + int pc=1; //begin point + while(p!=begin_point) { + pc++; + p=p->prev_point; + } + + DVector<Vector3> path; + path.resize(pc); + + { + DVector<Vector3>::Write w = path.write(); + + Point *p=end_point; + int idx=pc-1; + while(p!=begin_point) { + w[idx--]=p->pos; + p=p->prev_point; + } + + w[0]=p->pos; //assign first + + } + + return path; + +} + + +DVector<int> AStar::get_id_path(int p_from_id, int p_to_id) { + + ERR_FAIL_COND_V(!points.has(p_from_id),DVector<int>()); + ERR_FAIL_COND_V(!points.has(p_to_id),DVector<int>()); + + + pass++; + + Point* a = points[p_from_id]; + Point* b = points[p_to_id]; + + if (a==b) { + DVector<int> ret; + ret.push_back(a->id); + return ret; + } + + + Point *begin_point=a; + Point *end_point=b; + + bool found_route=_solve(begin_point,end_point); + + if (!found_route) + return DVector<int>(); + + //midpoints + Point *p=end_point; + int pc=1; //begin point + while(p!=begin_point) { + pc++; + p=p->prev_point; + } + + DVector<int> path; + path.resize(pc); + + { + DVector<int>::Write w = path.write(); + + p=end_point; + int idx=pc-1; + while(p!=begin_point) { + w[idx--]=p->id; + p=p->prev_point; + } + + w[0]=p->id; //assign first + + } + + return path; +} + +void AStar::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("get_available_point_id"),&AStar::get_available_point_id); + ObjectTypeDB::bind_method(_MD("add_point","id","pos","weight_scale"),&AStar::add_point,DEFVAL(1.0)); + ObjectTypeDB::bind_method(_MD("get_point_pos","id"),&AStar::get_point_pos); + ObjectTypeDB::bind_method(_MD("get_point_weight_scale","id"),&AStar::get_point_weight_scale); + ObjectTypeDB::bind_method(_MD("remove_point","id"),&AStar::remove_point); + + ObjectTypeDB::bind_method(_MD("connect_points","id","to_id"),&AStar::connect_points); + ObjectTypeDB::bind_method(_MD("disconnect_points","id","to_id"),&AStar::disconnect_points); + ObjectTypeDB::bind_method(_MD("are_points_connected","id","to_id"),&AStar::are_points_connected); + + ObjectTypeDB::bind_method(_MD("clear"),&AStar::clear); + + ObjectTypeDB::bind_method(_MD("get_closest_point","to_pos"),&AStar::get_closest_point); + ObjectTypeDB::bind_method(_MD("get_closest_pos_in_segment","to_pos"),&AStar::get_closest_pos_in_segment); + + ObjectTypeDB::bind_method(_MD("get_point_path","from_id","to_id"),&AStar::get_point_path); + ObjectTypeDB::bind_method(_MD("get_id_path","from_id","to_id"),&AStar::get_id_path); + +} + + +AStar::AStar() { + + pass=1; +} + + +AStar::~AStar() { + + pass=1; +} diff --git a/core/math/a_star.h b/core/math/a_star.h new file mode 100644 index 000000000..a0517b594 --- /dev/null +++ b/core/math/a_star.h @@ -0,0 +1,92 @@ +#ifndef ASTAR_H +#define ASTAR_H + +#include "reference.h" +#include "self_list.h" + +class AStar: public Reference { + + OBJ_TYPE(AStar,Reference) + + + uint64_t pass; + + struct Point { + + SelfList<Point> list; + + int id; + Vector3 pos; + float weight_scale; + uint64_t last_pass; + + Vector<Point*> neighbours; + + //used for pathfinding + Point *prev_point; + float distance; + + Point() : list(this) {} + }; + + Map<int,Point*> points; + + struct Segment { + union { + struct { + int32_t from; + int32_t to; + }; + uint64_t key; + }; + + Point *from_point; + Point *to_point; + + bool operator<(const Segment& p_s) const { return key<p_s.key; } + Segment() { key=0; } + Segment(int p_from,int p_to) { + if (p_from > p_to) { + SWAP(p_from,p_to); + } + + from=p_from; + to=p_to; + } + }; + + + Set<Segment> segments; + + bool _solve(Point *begin_point, Point *end_point); + +protected: + + static void _bind_methods(); +public: + + int get_available_point_id() const; + + void add_point(int p_id,const Vector3& p_pos,float p_weight_scale=1); + Vector3 get_point_pos(int p_id) const; + float get_point_weight_scale(int p_id) const; + void remove_point(int p_id); + + void connect_points(int p_id,int p_with_id); + void disconnect_points(int p_id,int p_with_id); + bool are_points_connected(int p_id,int p_with_id) const; + + void clear(); + + + int get_closest_point(const Vector3& p_point) const; + Vector3 get_closest_pos_in_segment(const Vector3& p_point) const; + + DVector<Vector3> get_point_path(int p_from_id, int p_to_id); + DVector<int> get_id_path(int p_from_id, int p_to_id); + + AStar(); + ~AStar(); +}; + +#endif // ASTAR_H diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp index 27b7c8667..1f5d5ed6b 100644 --- a/core/math/triangulate.cpp +++ b/core/math/triangulate.cpp @@ -157,7 +157,10 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour,Vector<int> &result m++; /* remove v from remaining polygon */ - for(s=v,t=v+1;t<nv;s++,t++) V[s] = V[t]; nv--; + for(s=v,t=v+1;t<nv;s++,t++) + V[s] = V[t]; + + nv--; /* resest error detection counter */ count = 2*nv; diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index 8afd73f48..b4a13d8f6 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -65,13 +65,9 @@ int Vector3::max_axis() const { void Vector3::snap(float p_val) { - x+=p_val/2.0; - x-=Math::fmod(x,p_val); - y+=p_val/2.0; - y-=Math::fmod(y,p_val); - z+=p_val/2.0; - z-=Math::fmod(z,p_val); - + x=Math::stepify(x,p_val); + y=Math::stepify(y,p_val); + z=Math::stepify(z,p_val); } Vector3 Vector3::snapped(float p_val) const { diff --git a/core/method_bind.h b/core/method_bind.h index 072953743..04ff5c22c 100644 --- a/core/method_bind.h +++ b/core/method_bind.h @@ -52,6 +52,7 @@ enum MethodFlags { METHOD_FLAG_REVERSE=16, // used for events METHOD_FLAG_VIRTUAL=32, METHOD_FLAG_FROM_SCRIPT=64, + METHOD_FLAG_VARARG=128, METHOD_FLAGS_DEFAULT=METHOD_FLAG_NORMAL, }; @@ -229,7 +230,7 @@ public: Vector<StringName> get_argument_names() const; #endif void set_hint_flags(uint32_t p_hint) { hint_flags=p_hint; } - uint32_t get_hint_flags() const { return hint_flags|(is_const()?METHOD_FLAG_CONST:0); } + uint32_t get_hint_flags() const { return hint_flags|(is_const()?METHOD_FLAG_CONST:0)|(is_vararg()?METHOD_FLAG_VARARG:0); } virtual String get_instance_type() const=0; _FORCE_INLINE_ int get_argument_count() const { return argument_count; }; @@ -267,7 +268,7 @@ public: _FORCE_INLINE_ int get_method_id() const { return method_id; } _FORCE_INLINE_ bool is_const() const { return _const; } _FORCE_INLINE_ bool has_return() const { return _returns; } - + virtual bool is_vararg() const { return false; } void set_default_arguments(const Vector<Variant>& p_defargs); @@ -277,7 +278,7 @@ public: template<class T> -class MethodBindNative : public MethodBind { +class MethodBindVarArg : public MethodBind { public: typedef Variant (T::*NativeCall)(const Variant**,int ,Variant::CallError &); protected: @@ -319,7 +320,9 @@ public: } #ifdef PTRCALL_ENABLED - virtual void ptrcall(Object* p_object,const void** p_args,void* r_ret) {} //todo + virtual void ptrcall(Object* p_object,const void** p_args,void* r_ret) { + ERR_FAIL(); //can't call + } //todo #endif @@ -327,14 +330,16 @@ public: virtual bool is_const() const { return false; } virtual String get_instance_type() const { return T::get_type_static(); } - MethodBindNative() { call_method=NULL; _set_returns(true);} + virtual bool is_vararg() const { return true; } + + MethodBindVarArg() { call_method=NULL; _set_returns(true);} }; template<class T > -MethodBind* create_native_method_bind( Variant (T::*p_method)(const Variant**,int ,Variant::CallError &), const MethodInfo& p_info ) { +MethodBind* create_vararg_method_bind( Variant (T::*p_method)(const Variant**,int ,Variant::CallError &), const MethodInfo& p_info ) { - MethodBindNative<T > * a = memnew( (MethodBindNative<T >) ); + MethodBindVarArg<T > * a = memnew( (MethodBindVarArg<T >) ); a->set_method(p_method); a->set_method_info(p_info); return a; diff --git a/core/object.cpp b/core/object.cpp index b036efa50..8cd4e0709 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -1644,6 +1644,7 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) { _clear_internal_resource_paths(d[E->get()]); } } break; + default: {} } } @@ -1693,42 +1694,26 @@ void Object::_bind_methods() { MethodInfo mi; mi.name="emit_signal"; mi.arguments.push_back( PropertyInfo( Variant::STRING, "signal")); - Vector<Variant> defargs; - for(int i=0;i<VARIANT_ARG_MAX;i++) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"emit_signal",&Object::_emit_signal,mi,defargs); + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"emit_signal",&Object::_emit_signal,mi); } { MethodInfo mi; mi.name="call"; mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); - Vector<Variant> defargs; - for(int i=0;i<10;i++) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call:Variant",&Object::_call_bind,mi,defargs); + + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call:Variant",&Object::_call_bind,mi); } { MethodInfo mi; mi.name="call_deferred"; mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); - Vector<Variant> defargs; - for(int i=0;i<VARIANT_ARG_MAX;i++) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"call_deferred",&Object::_call_deferred_bind,mi,defargs); + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"call_deferred",&Object::_call_deferred_bind,mi); } ObjectTypeDB::bind_method(_MD("callv:Variant","method","arg_array"),&Object::callv); diff --git a/core/object_type_db.cpp b/core/object_type_db.cpp index b6a69e3bd..e121dc9e9 100644 --- a/core/object_type_db.cpp +++ b/core/object_type_db.cpp @@ -189,6 +189,14 @@ MethodDefinition _MD(const char* p_name,const char *p_arg1,const char *p_arg2,co #endif + +ObjectTypeDB::APIType ObjectTypeDB::current_api=API_CORE; + +void ObjectTypeDB::set_current_api(APIType p_api) { + + current_api=p_api; +} + HashMap<StringName,ObjectTypeDB::TypeInfo,StringNameHasher> ObjectTypeDB::types; HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::resource_base_extensions; HashMap<StringName,StringName,StringNameHasher> ObjectTypeDB::compat_types; @@ -258,6 +266,171 @@ StringName ObjectTypeDB::type_inherits_from(const StringName& p_type) { return ti->inherits; } +ObjectTypeDB::APIType ObjectTypeDB::get_api_type(const StringName &p_type) { + + OBJTYPE_LOCK; + + TypeInfo *ti = types.getptr(p_type); + ERR_FAIL_COND_V(!ti,API_NONE); + return ti->api; +} + +uint64_t ObjectTypeDB::get_api_hash(APIType p_api) { + +#ifdef DEBUG_METHODS_ENABLED + + uint64_t hash = hash_djb2_one_64(HashMapHahserDefault::hash(VERSION_FULL_NAME)); + + List<StringName> names; + + const StringName *k=NULL; + + while((k=types.next(k))) { + + names.push_back(*k); + } + //must be alphabetically sorted for hash to compute + names.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *E=names.front();E;E=E->next()) { + + TypeInfo *t = types.getptr(E->get()); + ERR_FAIL_COND_V(!t,0); + if (t->api!=p_api) + continue; + hash = hash_djb2_one_64(t->name.hash(),hash); + hash = hash_djb2_one_64(t->inherits.hash(),hash); + + { //methods + + List<StringName> snames; + + k=NULL; + + while((k=t->method_map.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *F=snames.front();F;F=F->next()) { + + MethodBind *mb = t->method_map[F->get()]; + hash = hash_djb2_one_64( mb->get_name().hash(), hash); + hash = hash_djb2_one_64( mb->get_argument_count(), hash); + hash = hash_djb2_one_64( mb->get_argument_type(-1), hash); //return + + for(int i=0;i<mb->get_argument_count();i++) { + hash = hash_djb2_one_64( mb->get_argument_info(i).type, hash ); + hash = hash_djb2_one_64( mb->get_argument_info(i).name.hash(), hash ); + hash = hash_djb2_one_64( mb->get_argument_info(i).hint, hash ); + hash = hash_djb2_one_64( mb->get_argument_info(i).hint_string.hash(), hash ); + } + + hash = hash_djb2_one_64( mb->get_default_argument_count(), hash); + + for(int i=0;i<mb->get_default_argument_count();i++) { + //hash should not change, i hope for tis + Variant da = mb->get_default_argument(i); + hash = hash_djb2_one_64( da.hash(), hash ); + } + + hash = hash_djb2_one_64( mb->get_hint_flags(), hash); + + } + } + + + { //constants + + List<StringName> snames; + + k=NULL; + + while((k=t->constant_map.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *F=snames.front();F;F=F->next()) { + + hash = hash_djb2_one_64(F->get().hash(), hash); + hash = hash_djb2_one_64( t->constant_map[F->get()], hash); + } + } + + + { //signals + + List<StringName> snames; + + k=NULL; + + while((k=t->signal_map.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *F=snames.front();F;F=F->next()) { + + MethodInfo &mi = t->signal_map[F->get()]; + hash = hash_djb2_one_64( F->get().hash(), hash); + for(int i=0;i<mi.arguments.size();i++) { + hash = hash_djb2_one_64( mi.arguments[i].type, hash); + } + } + } + + { //properties + + List<StringName> snames; + + k=NULL; + + while((k=t->property_setget.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *F=snames.front();F;F=F->next()) { + + PropertySetGet *psg=t->property_setget.getptr(F->get()); + + hash = hash_djb2_one_64( F->get().hash(), hash); + hash = hash_djb2_one_64( psg->setter.hash(), hash); + hash = hash_djb2_one_64( psg->getter.hash(), hash); + + } + } + + //property list + for (List<PropertyInfo>::Element *F=t->property_list.front();F;F=F->next()) { + + hash = hash_djb2_one_64( F->get().name.hash(), hash); + hash = hash_djb2_one_64( F->get().type, hash); + hash = hash_djb2_one_64( F->get().hint, hash); + hash = hash_djb2_one_64( F->get().hint_string.hash(), hash); + hash = hash_djb2_one_64( F->get().usage, hash); + } + + + } + + + return hash; +#else + return 0; +#endif + +} + bool ObjectTypeDB::type_exists(const StringName &p_type) { OBJTYPE_LOCK; @@ -309,6 +482,7 @@ void ObjectTypeDB::_add_type2(const StringName& p_type, const StringName& p_inhe TypeInfo &ti=types[name]; ti.name=name; ti.inherits=p_inherits; + ti.api=current_api; if (ti.inherits) { @@ -866,21 +1040,14 @@ MethodBind* ObjectTypeDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , c Vector<Variant> defvals; -#define PARSE_DEFVAL(m_defval)\ -if (d##m_defval.used) defvals.insert(0,d##m_defval.val);\ -else goto set_defvals; - defvals.resize(p_defcount); for(int i=0;i<p_defcount;i++) { defvals[i]=*p_defs[p_defcount-i-1]; } - set_defvals: - p_bind->set_default_arguments(defvals); p_bind->set_hint_flags(p_flags); -#undef PARSE_DEFVAL return p_bind; } diff --git a/core/object_type_db.h b/core/object_type_db.h index 3fcd38aa3..9e9029ff2 100644 --- a/core/object_type_db.h +++ b/core/object_type_db.h @@ -109,7 +109,13 @@ static _FORCE_INLINE_ const char* _MD(const char* m_name, ...) { return m_name; #endif class ObjectTypeDB { - +public: + enum APIType { + API_CORE, + API_EDITOR, + API_NONE + }; +public: struct PropertySetGet { int index; @@ -122,6 +128,7 @@ class ObjectTypeDB { struct TypeInfo { + APIType api; TypeInfo *inherits_ptr; HashMap<StringName,MethodBind*,StringNameHasher> method_map; HashMap<StringName,int,StringNameHasher> constant_map; @@ -161,6 +168,7 @@ class ObjectTypeDB { #endif + static APIType current_api; static void _add_type2(const StringName& p_type, const StringName& p_inherits); public: @@ -236,6 +244,9 @@ public: static bool is_type(const StringName &p_type,const StringName& p_inherits); static bool can_instance(const StringName &p_type); static Object *instance(const StringName &p_type); + static APIType get_api_type(const StringName &p_type); + + static uint64_t get_api_hash(APIType p_api); #if 0 template<class N, class M> @@ -415,13 +426,13 @@ public: #endif template<class M> - static MethodBind* bind_native_method(uint32_t p_flags, StringName p_name, M p_method,const MethodInfo& p_info=MethodInfo(),const Vector<Variant>& p_default_args=Vector<Variant>()) { + static MethodBind* bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method,const MethodInfo& p_info=MethodInfo(),const Vector<Variant>& p_default_args=Vector<Variant>()) { GLOBAL_LOCK_FUNCTION; - MethodBind *bind = create_native_method_bind(p_method,p_info); + MethodBind *bind = create_vararg_method_bind(p_method,p_info); ERR_FAIL_COND_V(!bind,NULL); String rettype; @@ -499,6 +510,8 @@ public: static void add_compatibility_type(const StringName& p_type,const StringName& p_fallback); static void init(); + + static void set_current_api(APIType p_api); static void cleanup(); }; diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 3de26573f..7e4ba039c 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -33,6 +33,7 @@ #include "io/config_file.h" #include "os/main_loop.h" #include "io/packet_peer.h" +#include "math/a_star.h" #include "globals.h" #include "object_type_db.h" #include "geometry.h" @@ -147,6 +148,7 @@ void register_core_types() { ObjectTypeDB::register_type<PackedDataContainer>(); ObjectTypeDB::register_virtual_type<PackedDataContainerRef>(); + ObjectTypeDB::register_type<AStar>(); ip = IP::create(); diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 99d1e22c0..1ac090796 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -219,7 +219,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) { if (F->get().get_type()==Variant::OBJECT) { packet_peer_stream->put_var("*"+E->get()); - packet_peer_stream->put_var(safe_get_instance_id(F->get())); + String pretty_print = F->get().operator String(); + packet_peer_stream->put_var(pretty_print.ascii().get_data()); } else { packet_peer_stream->put_var(E->get()); packet_peer_stream->put_var(F->get()); @@ -242,7 +243,8 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script,bool p_can_continue) { if (F->get().get_type()==Variant::OBJECT) { packet_peer_stream->put_var("*"+E->get()); - packet_peer_stream->put_var(safe_get_instance_id(F->get())); + String pretty_print = F->get().operator String(); + packet_peer_stream->put_var(pretty_print.ascii().get_data()); } else { packet_peer_stream->put_var(E->get()); packet_peer_stream->put_var(F->get()); diff --git a/core/script_language.h b/core/script_language.h index 1b037e908..53af4c74d 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -122,6 +122,7 @@ public: virtual void get_script_method_list(List<MethodInfo> *p_list) const=0; virtual void get_script_property_list(List<PropertyInfo> *p_list) const=0; + virtual int get_member_line(const StringName& p_member) const { return 0; } Script() {} }; @@ -207,7 +208,26 @@ public: virtual bool has_named_classes() const=0; virtual int find_function(const String& p_function,const String& p_code) const=0; virtual String make_function(const String& p_class,const String& p_name,const StringArray& p_args) const=0; + virtual Error complete_code(const String& p_code, const String& p_base_path, Object*p_owner,List<String>* r_options,String& r_call_hint) { return ERR_UNAVAILABLE; } + + struct LookupResult { + enum Type { + RESULT_SCRIPT_LOCATION, + RESULT_CLASS, + RESULT_CLASS_CONSTANT, + RESULT_CLASS_PROPERTY, + RESULT_CLASS_METHOD + }; + Type type; + Ref<Script> script; + String class_name; + String class_member; + int location; + }; + + virtual Error lookup_code(const String& p_code, const String& p_symbol,const String& p_base_path, Object*p_owner,LookupResult& r_result) { return ERR_UNAVAILABLE; } + virtual void auto_indent_code(String& p_code,int p_from_line,int p_to_line) const=0; virtual void add_global_constant(const StringName& p_variable,const Variant& p_value)=0; diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp index 99740b365..e8a71d499 100644 --- a/core/undo_redo.cpp +++ b/core/undo_redo.cpp @@ -490,13 +490,9 @@ void UndoRedo::_bind_methods() { mi.name="add_do_method"; mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object")); mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); - Vector<Variant> defargs; - for(int i=0;i<VARIANT_ARG_MAX;++i) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_do_method",&UndoRedo::_add_do_method,mi,defargs); + + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"add_do_method",&UndoRedo::_add_do_method,mi); } { @@ -504,13 +500,9 @@ void UndoRedo::_bind_methods() { mi.name="add_undo_method"; mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object")); mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); - Vector<Variant> defargs; - for(int i=0;i<VARIANT_ARG_MAX;++i) { - mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); - defargs.push_back(Variant()); - } - ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_undo_method",&UndoRedo::_add_undo_method,mi,defargs); + + ObjectTypeDB::bind_vararg_method(METHOD_FLAGS_DEFAULT,"add_undo_method",&UndoRedo::_add_undo_method,mi); } ObjectTypeDB::bind_method(_MD("add_do_property","object", "property", "value:Variant"),&UndoRedo::add_do_property); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index e7e71e825..8473fdcd1 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -518,6 +518,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM1(ByteArray,append); VCALL_LOCALMEM1(ByteArray,append_array); VCALL_LOCALMEM0(ByteArray,invert); + VCALL_LOCALMEM2R(ByteArray,subarray); VCALL_LOCALMEM0R(IntArray,size); VCALL_LOCALMEM2(IntArray,set); @@ -1592,6 +1593,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC2(RAW_ARRAY,INT,ByteArray,insert,INT,"idx",INT,"byte",varray()); ADDFUNC1(RAW_ARRAY,NIL,ByteArray,resize,INT,"idx",varray()); ADDFUNC0(RAW_ARRAY,NIL,ByteArray,invert,varray()); + ADDFUNC2(RAW_ARRAY,RAW_ARRAY,ByteArray,subarray,INT,"from",INT,"to",varray()); ADDFUNC0(RAW_ARRAY,STRING,ByteArray,get_string_from_ascii,varray()); ADDFUNC0(RAW_ARRAY,STRING,ByteArray,get_string_from_utf8,varray()); |
