summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/array.cpp20
-rw-r--r--core/array.h4
-rw-r--r--core/dvector.h28
-rw-r--r--core/func_ref.cpp6
-rw-r--r--core/image.cpp1
-rw-r--r--core/input_map.cpp58
-rw-r--r--core/input_map.h1
-rw-r--r--core/io/file_access_pack.cpp2
-rw-r--r--core/math/a_star.cpp412
-rw-r--r--core/math/a_star.h92
-rw-r--r--core/math/math_2d.cpp22
-rw-r--r--core/math/math_2d.h15
-rw-r--r--core/math/triangulate.cpp5
-rw-r--r--core/math/vector3.cpp10
-rw-r--r--core/method_bind.h19
-rw-r--r--core/object.cpp25
-rw-r--r--core/object_type_db.cpp181
-rw-r--r--core/object_type_db.h19
-rw-r--r--core/os/input.cpp6
-rw-r--r--core/os/input.h5
-rw-r--r--core/os/input_event.cpp2
-rw-r--r--core/register_core_types.cpp2
-rw-r--r--core/script_debugger_remote.cpp6
-rw-r--r--core/script_language.h20
-rw-r--r--core/undo_redo.cpp16
-rw-r--r--core/ustring.cpp2
-rw-r--r--core/ustring.h2
-rw-r--r--core/variant_call.cpp8
28 files changed, 829 insertions, 160 deletions
diff --git a/core/array.cpp b/core/array.cpp
index 23792f90fc..683a43e3d0 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -276,16 +276,26 @@ void Array::push_front(const Variant& p_value) {
_p->array.insert(0,p_value);
}
-void Array::pop_back(){
+Variant Array::pop_back(){
- if (!_p->array.empty())
- _p->array.resize( _p->array.size() -1 );
+ if (!_p->array.empty()) {
+ int n = _p->array.size() - 1;
+ Variant ret = _p->array.get(n);
+ _p->array.resize(n);
+ return ret;
+ }
+ return Variant();
}
-void Array::pop_front(){
- if (!_p->array.empty())
+Variant Array::pop_front(){
+
+ if (!_p->array.empty()) {
+ Variant ret = _p->array.get(0);
_p->array.remove(0);
+ return ret;
+ }
+ return Variant();
}
diff --git a/core/array.h b/core/array.h
index dfc902525c..eb79b0cf33 100644
--- a/core/array.h
+++ b/core/array.h
@@ -80,8 +80,8 @@ public:
void erase(const Variant& p_value);
void push_front(const Variant& p_value);
- void pop_back();
- void pop_front();
+ Variant pop_back();
+ Variant pop_front();
Array(const Array& p_from);
Array(bool p_shared=false);
diff --git a/core/dvector.h b/core/dvector.h
index a5519ed604..9a54641617 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 644d8b5b63..ca890111be 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 d6ac3f28ea..90051d7d0d 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/input_map.cpp b/core/input_map.cpp
index 3a0f9596f5..09cb7ce426 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -232,64 +232,6 @@ bool InputMap::event_is_action(const InputEvent& p_event, const StringName& p_ac
return _find_event(E->get().inputs,p_event)!=NULL;
}
-bool InputMap::event_is_joy_motion_action_pressed(const InputEvent& p_event) const {
-
- ERR_FAIL_COND_V(p_event.type!=InputEvent::JOYSTICK_MOTION,false);
- bool pressed=false;
-
- //this could be optimized by having a separate list of joymotions?
-
- for (Map<StringName, Action>::Element *A=input_map.front();A;A=A->next()) {
-
- for (List<InputEvent>::Element *E=A->get().inputs.front();E;E=E->next()) {
-
- const InputEvent& e=E->get();
- if(e.type!=p_event.type)
- continue;
- if (e.type!=InputEvent::KEY && e.device!=p_event.device)
- continue;
-
- switch(p_event.type) {
-
- case InputEvent::KEY: {
-
- if (e.key.scancode==p_event.key.scancode && e.key.mod == p_event.key.mod)
- return e.key.pressed;
-
- } break;
- case InputEvent::JOYSTICK_BUTTON: {
-
- if (e.joy_button.button_index==p_event.joy_button.button_index) {
- return e.joy_button.pressed;
- }
-
- } break;
- case InputEvent::MOUSE_BUTTON: {
-
- if (e.mouse_button.button_index==p_event.mouse_button.button_index) {
- return e.mouse_button.pressed;
- }
-
- } break;
- case InputEvent::JOYSTICK_MOTION: {
-
- if (e.joy_motion.axis==p_event.joy_motion.axis) {
- if (
- (e.joy_motion.axis_value * p_event.joy_motion.axis_value >0) && //same axis
- ABS(e.joy_motion.axis_value)>0.5 && ABS(p_event.joy_motion.axis_value)>0.5 )
- pressed=true;
- }
-
- } break;
- }
-
- }
- }
-
- return pressed;
-
-}
-
const Map<StringName, InputMap::Action>& InputMap::get_action_map() const {
return input_map;
}
diff --git a/core/input_map.h b/core/input_map.h
index a224765d8c..21c479588d 100644
--- a/core/input_map.h
+++ b/core/input_map.h
@@ -72,7 +72,6 @@ public:
const List<InputEvent> *get_action_list(const StringName& p_action);
bool event_is_action(const InputEvent& p_event, const StringName& p_action) const;
- bool event_is_joy_motion_action_pressed(const InputEvent& p_event) const;
const Map<StringName, Action>& get_action_map() const;
void load_from_globals();
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index 5c8c741f28..1632b841c6 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 0000000000..5bbbbdaa5a
--- /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 0000000000..a0517b5941
--- /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/math_2d.cpp b/core/math/math_2d.cpp
index 0e2060008c..2cc11aa738 100644
--- a/core/math/math_2d.cpp
+++ b/core/math/math_2d.cpp
@@ -475,18 +475,18 @@ Matrix32::Matrix32(real_t p_rot, const Vector2& p_pos) {
elements[2]=p_pos;
}
-Vector2 Matrix32::get_scale() const {
+Size2 Matrix32::get_scale() const {
- return Vector2( elements[0].length(), elements[1].length() );
+ return Size2( elements[0].length(), elements[1].length() );
}
-void Matrix32::scale(const Vector2& p_scale) {
+void Matrix32::scale(const Size2& p_scale) {
elements[0]*=p_scale;
elements[1]*=p_scale;
elements[2]*=p_scale;
}
-void Matrix32::scale_basis(const Vector2& p_scale) {
+void Matrix32::scale_basis(const Size2& p_scale) {
elements[0]*=p_scale;
elements[1]*=p_scale;
@@ -501,7 +501,6 @@ void Matrix32::translate( const Vector2& p_translation ) {
elements[2]+=basis_xform(p_translation);
}
-
void Matrix32::orthonormalize() {
// Gram-Schmidt Process
@@ -550,11 +549,6 @@ void Matrix32::operator*=(const Matrix32& p_transform) {
elements[2] = xform(p_transform.elements[2]);
float x0,x1,y0,y1;
-/*
- x0 = p_transform.tdotx(elements[0]);
- x1 = p_transform.tdoty(elements[0]);
- y0 = p_transform.tdotx(elements[1]);
- y1 = p_transform.tdoty(elements[1]);*/
x0 = tdotx(p_transform.elements[0]);
x1 = tdoty(p_transform.elements[0]);
@@ -576,7 +570,7 @@ Matrix32 Matrix32::operator*(const Matrix32& p_transform) const {
}
-Matrix32 Matrix32::scaled(const Vector2& p_scale) const {
+Matrix32 Matrix32::scaled(const Size2& p_scale) const {
Matrix32 copy=*this;
copy.scale(p_scale);
@@ -584,7 +578,7 @@ Matrix32 Matrix32::scaled(const Vector2& p_scale) const {
}
-Matrix32 Matrix32::basis_scaled(const Vector2& p_scale) const {
+Matrix32 Matrix32::basis_scaled(const Size2& p_scale) const {
Matrix32 copy=*this;
copy.scale_basis(p_scale);
@@ -629,8 +623,8 @@ Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) cons
real_t r1 = get_rotation();
real_t r2 = p_transform.get_rotation();
- Vector2 s1 = get_scale();
- Vector2 s2 = p_transform.get_scale();
+ Size2 s1 = get_scale();
+ Size2 s2 = p_transform.get_scale();
//slerp rotation
Vector2 v1(Math::cos(r1), Math::sin(r1));
diff --git a/core/math/math_2d.h b/core/math/math_2d.h
index 90aae9fe50..38c1ac9656 100644
--- a/core/math/math_2d.h
+++ b/core/math/math_2d.h
@@ -553,10 +553,8 @@ struct Rect2i {
struct Matrix32 {
-
Vector2 elements[3];
-
_FORCE_INLINE_ float tdotx(const Vector2& v) const { return elements[0][0] * v.x + elements[1][0] * v.y; }
_FORCE_INLINE_ float tdoty(const Vector2& v) const { return elements[0][1] * v.x + elements[1][1] * v.y; }
@@ -577,26 +575,25 @@ struct Matrix32 {
_FORCE_INLINE_ void set_rotation_and_scale(real_t p_phi,const Size2& p_scale);
void rotate(real_t p_phi);
- void scale(const Vector2& p_scale);
- void scale_basis(const Vector2& p_scale);
+ void scale(const Size2& p_scale);
+ void scale_basis(const Size2& p_scale);
void translate( real_t p_tx, real_t p_ty);
void translate( const Vector2& p_translation );
float basis_determinant() const;
- Vector2 get_scale() const;
+ Size2 get_scale() const;
_FORCE_INLINE_ const Vector2& get_origin() const { return elements[2]; }
_FORCE_INLINE_ void set_origin(const Vector2& p_origin) { elements[2]=p_origin; }
- Matrix32 scaled(const Vector2& p_scale) const;
- Matrix32 basis_scaled(const Vector2& p_scale) const;
+ Matrix32 scaled(const Size2& p_scale) const;
+ Matrix32 basis_scaled(const Size2& p_scale) const;
Matrix32 translated(const Vector2& p_offset) const;
Matrix32 rotated(float p_phi) const;
Matrix32 untranslated() const;
-
void orthonormalize();
Matrix32 orthonormalized() const;
@@ -615,7 +612,6 @@ struct Matrix32 {
_FORCE_INLINE_ Rect2 xform(const Rect2& p_vec) const;
_FORCE_INLINE_ Rect2 xform_inv(const Rect2& p_vec) const;
-
operator String() const;
Matrix32(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) {
@@ -630,7 +626,6 @@ struct Matrix32 {
Matrix32(real_t p_rot, const Vector2& p_pos);
Matrix32() { elements[0][0]=1.0; elements[1][1]=1.0; }
-
};
bool Rect2::intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const {
diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp
index 27b7c86675..1f5d5ed6b3 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 8afd73f482..b4a13d8f6d 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 072953743c..04ff5c22c6 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 b036efa501..8cd4e07097 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 b6a69e3bd4..e121dc9e98 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 3fcd38aa31..9e9029ff2f 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/os/input.cpp b/core/os/input.cpp
index 401ab7ffe2..4ab57a84ea 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -64,6 +64,10 @@ void Input::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_connected_joysticks"),&Input::get_connected_joysticks);
ObjectTypeDB::bind_method(_MD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength);
ObjectTypeDB::bind_method(_MD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration);
+ ObjectTypeDB::bind_method(_MD("get_joy_button_string", "button_index"), &Input::get_joy_button_string);
+ ObjectTypeDB::bind_method(_MD("get_joy_button_index_from_string", "button"), &Input::get_joy_button_index_from_string);
+ ObjectTypeDB::bind_method(_MD("get_joy_axis_string", "axis_index"), &Input::get_joy_axis_string);
+ ObjectTypeDB::bind_method(_MD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string);
ObjectTypeDB::bind_method(_MD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0));
ObjectTypeDB::bind_method(_MD("stop_joy_vibration", "device"), &Input::stop_joy_vibration);
ObjectTypeDB::bind_method(_MD("get_accelerometer"),&Input::get_accelerometer);
@@ -90,7 +94,7 @@ void Input::get_argument_options(const StringName& p_function,int p_idx,List<Str
#ifdef TOOLS_ENABLED
String pf=p_function;
- if (p_idx==0 && (pf=="is_action_pressed" || pf=="action_press" || pf=="action_release")) {
+ if (p_idx==0 && (pf=="is_action_pressed" || pf=="action_press" || pf=="action_release" || pf=="is_action_just_pressed" || pf=="is_action_just_released")) {
List<PropertyInfo> pinfo;
Globals::get_singleton()->get_property_list(&pinfo);
diff --git a/core/os/input.h b/core/os/input.h
index 665fb4ad99..d8f3be09df 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -96,6 +96,11 @@ public:
virtual void set_custom_mouse_cursor(const RES& p_cursor,const Vector2& p_hotspot=Vector2())=0;
virtual void set_mouse_in_window(bool p_in_window)=0;
+ virtual String get_joy_button_string(int p_button)=0;
+ virtual String get_joy_axis_string(int p_axis)=0;
+ virtual int get_joy_button_index_from_string(String p_button)=0;
+ virtual int get_joy_axis_index_from_string(String p_axis)=0;
+
Input();
};
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 9d920724e1..9982767be1 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -204,7 +204,7 @@ bool InputEvent::is_pressed() const {
case MOUSE_BUTTON: return mouse_button.pressed;
case JOYSTICK_BUTTON: return joy_button.pressed;
case SCREEN_TOUCH: return screen_touch.pressed;
- case JOYSTICK_MOTION: return InputMap::get_singleton()->event_is_joy_motion_action_pressed(*this);
+ case JOYSTICK_MOTION: return ABS(joy_motion.axis_value) > 0.5;
case ACTION: return action.pressed;
default: {}
}
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 3de26573f4..7e4ba039c5 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 d3cd824620..6d685d3c43 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -221,7 +221,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());
@@ -244,7 +245,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 1b037e908c..53af4c74d1 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 99740b365c..e8a71d4991 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/ustring.cpp b/core/ustring.cpp
index 0d887210c3..f7dcba6b14 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -3173,7 +3173,7 @@ bool String::is_valid_identifier() const {
//kind of poor should be rewritten properly
-String String::world_wrap(int p_chars_per_line) const {
+String String::word_wrap(int p_chars_per_line) const {
int from=0;
int last_space=0;
diff --git a/core/ustring.h b/core/ustring.h
index bb57b11d88..09d13a9e64 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -218,7 +218,7 @@ public:
String c_escape() const;
String c_unescape() const;
String json_escape() const;
- String world_wrap(int p_chars_per_line) const;
+ String word_wrap(int p_chars_per_line) const;
String percent_encode() const;
String percent_decode() const;
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index e7e71e8251..a84eed4d88 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -346,6 +346,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_LOCALMEM0R(Vector2,angle);
// VCALL_LOCALMEM1R(Vector2,cross);
VCALL_LOCALMEM0R(Vector2,abs);
+ VCALL_LOCALMEM1R(Vector2,clamped);
VCALL_LOCALMEM0R(Rect2,get_area);
VCALL_LOCALMEM1R(Rect2,intersects);
@@ -464,8 +465,8 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
VCALL_LOCALMEM0R(Array,hash);
VCALL_LOCALMEM1(Array,push_back);
VCALL_LOCALMEM1(Array,push_front);
- VCALL_LOCALMEM0(Array,pop_back);
- VCALL_LOCALMEM0(Array,pop_front);
+ VCALL_LOCALMEM0R(Array,pop_back);
+ VCALL_LOCALMEM0R(Array,pop_front);
VCALL_LOCALMEM1(Array,append);
VCALL_LOCALMEM1(Array,resize);
VCALL_LOCALMEM2(Array,insert);
@@ -518,6 +519,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);
@@ -1456,6 +1458,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
ADDFUNC1(VECTOR2,VECTOR2,Vector2,reflect,VECTOR2,"vec",varray());
//ADDFUNC1(VECTOR2,REAL,Vector2,cross,VECTOR2,"with",varray());
ADDFUNC0(VECTOR2,VECTOR2,Vector2,abs,varray());
+ ADDFUNC1(VECTOR2,VECTOR2,Vector2,clamped,REAL,"length",varray());
ADDFUNC0(RECT2,REAL,Rect2,get_area,varray());
ADDFUNC1(RECT2,BOOL,Rect2,intersects,RECT2,"b",varray());
@@ -1592,6 +1595,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());