diff options
Diffstat (limited to 'core')
94 files changed, 1838 insertions, 1937 deletions
diff --git a/core/SCsub b/core/SCsub index e9b21bc71b..1545bc8aeb 100644 --- a/core/SCsub +++ b/core/SCsub @@ -105,6 +105,6 @@ SConscript('helper/SCsub') # Build it all as a library -lib = env.Library("core", env.core_sources) +lib = env.add_library("core", env.core_sources) env.Prepend(LIBS=[lib]) Export('env') diff --git a/core/array.cpp b/core/array.cpp index 171c11776c..1ccbbae147 100644 --- a/core/array.cpp +++ b/core/array.cpp @@ -261,10 +261,53 @@ Array &Array::sort_custom(Object *p_obj, const StringName &p_function) { SortArray<Variant, _ArrayVariantSortCustom> avs; avs.compare.obj = p_obj; avs.compare.func = p_function; - avs.sort(_p->array.ptr(), _p->array.size()); + avs.sort(_p->array.ptrw(), _p->array.size()); return *this; } +template <typename Less> +_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) { + + int lo = 0; + int hi = p_array.size(); + if (p_before) { + while (lo < hi) { + const int mid = (lo + hi) / 2; + if (p_less(p_array.get(mid), p_value)) { + lo = mid + 1; + } else { + hi = mid; + } + } + } else { + while (lo < hi) { + const int mid = (lo + hi) / 2; + if (p_less(p_value, p_array.get(mid))) { + hi = mid; + } else { + lo = mid + 1; + } + } + } + return lo; +} + +int Array::bsearch(const Variant &p_value, bool p_before) { + + return bisect(_p->array, p_value, p_before, _ArrayVariantSort()); +} + +int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) { + + ERR_FAIL_NULL_V(p_obj, 0); + + _ArrayVariantSortCustom less; + less.obj = p_obj; + less.func = p_function; + + return bisect(_p->array, p_value, p_before, less); +} + Array &Array::invert() { _p->array.invert(); diff --git a/core/array.h b/core/array.h index 2c29103108..3d70a31d2f 100644 --- a/core/array.h +++ b/core/array.h @@ -70,6 +70,8 @@ public: Array &sort(); Array &sort_custom(Object *p_obj, const StringName &p_function); + int bsearch(const Variant &p_value, bool p_before = true); + int bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before = true); Array &invert(); int find(const Variant &p_value, int p_from = 0) const; diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 4d6eb92b0d..f6011c3976 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -888,9 +888,9 @@ void _OS::dump_resources_to_file(const String &p_file) { OS::get_singleton()->dump_resources_to_file(p_file.utf8().get_data()); } -String _OS::get_data_dir() const { +String _OS::get_user_data_dir() const { - return OS::get_singleton()->get_data_dir(); + return OS::get_singleton()->get_user_data_dir(); }; Error _OS::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { @@ -1088,7 +1088,7 @@ void _OS::_bind_methods() { ClassDB::bind_method(D_METHOD("get_static_memory_peak_usage"), &_OS::get_static_memory_peak_usage); ClassDB::bind_method(D_METHOD("get_dynamic_memory_usage"), &_OS::get_dynamic_memory_usage); - ClassDB::bind_method(D_METHOD("get_data_dir"), &_OS::get_data_dir); + ClassDB::bind_method(D_METHOD("get_user_data_dir"), &_OS::get_user_data_dir); ClassDB::bind_method(D_METHOD("get_system_dir", "dir"), &_OS::get_system_dir); ClassDB::bind_method(D_METHOD("get_unique_id"), &_OS::get_unique_id); @@ -1316,6 +1316,16 @@ Vector<int> _Geometry::triangulate_polygon(const Vector<Vector2> &p_polygon) { return Geometry::triangulate_polygon(p_polygon); } +Vector<Point2> _Geometry::convex_hull_2d(const Vector<Point2> &p_points) { + + return Geometry::convex_hull_2d(p_points); +} + +Vector<Vector3> _Geometry::clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane) { + + return Geometry::clip_polygon(p_points, p_plane); +} + Dictionary _Geometry::make_atlas(const Vector<Size2> &p_rects) { Dictionary ret; @@ -1376,6 +1386,8 @@ void _Geometry::_bind_methods() { ClassDB::bind_method(D_METHOD("point_is_inside_triangle", "point", "a", "b", "c"), &_Geometry::point_is_inside_triangle); ClassDB::bind_method(D_METHOD("triangulate_polygon", "polygon"), &_Geometry::triangulate_polygon); + ClassDB::bind_method(D_METHOD("convex_hull_2d", "points"), &_Geometry::convex_hull_2d); + ClassDB::bind_method(D_METHOD("clip_polygon", "points", "plane"), &_Geometry::clip_polygon); ClassDB::bind_method(D_METHOD("make_atlas", "sizes"), &_Geometry::make_atlas); } @@ -2580,6 +2592,16 @@ bool _Engine::is_in_physics_frame() const { return Engine::get_singleton()->is_in_physics_frame(); } +bool _Engine::has_singleton(const String &p_name) const { + + return Engine::get_singleton()->has_singleton(p_name); +} + +Object *_Engine::get_singleton_object(const String &p_name) const { + + return Engine::get_singleton()->get_singleton_object(p_name); +} + void _Engine::set_editor_hint(bool p_enabled) { Engine::get_singleton()->set_editor_hint(p_enabled); @@ -2609,6 +2631,9 @@ void _Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("is_in_physics_frame"), &_Engine::is_in_physics_frame); + ClassDB::bind_method(D_METHOD("has_singleton", "name"), &_Engine::has_singleton); + ClassDB::bind_method(D_METHOD("get_singleton", "name"), &_Engine::get_singleton_object); + ClassDB::bind_method(D_METHOD("set_editor_hint", "enabled"), &_Engine::set_editor_hint); ClassDB::bind_method(D_METHOD("is_editor_hint"), &_Engine::is_editor_hint); } diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h index 72c20f6825..b642a907fb 100644 --- a/core/bind/core_bind.h +++ b/core/bind/core_bind.h @@ -297,7 +297,7 @@ public: String get_system_dir(SystemDir p_dir) const; - String get_data_dir() const; + String get_user_data_dir() const; void alert(const String &p_alert, const String &p_title = "ALERT!"); @@ -363,6 +363,8 @@ public: int get_uv84_normal_bit(const Vector3 &p_vector); Vector<int> triangulate_polygon(const Vector<Vector2> &p_polygon); + Vector<Point2> convex_hull_2d(const Vector<Point2> &p_points); + Vector<Vector3> clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane); Dictionary make_atlas(const Vector<Size2> &p_rects); @@ -668,6 +670,9 @@ public: bool is_in_physics_frame() const; + bool has_singleton(const String &p_name) const; + Object *get_singleton_object(const String &p_name) const; + void set_editor_hint(bool p_enabled); bool is_editor_hint() const; diff --git a/core/color.h b/core/color.h index 972b6a1b33..da2bfdcd98 100644 --- a/core/color.h +++ b/core/color.h @@ -101,6 +101,24 @@ struct Color { return res; } + _FORCE_INLINE_ Color darkened(float p_amount) const { + + Color res = *this; + res.r = CLAMP(res.r * (1.0f - p_amount), 0.0, 1.0); + res.g = CLAMP(res.g * (1.0f - p_amount), 0.0, 1.0); + res.b = CLAMP(res.b * (1.0f - p_amount), 0.0, 1.0); + return res; + } + + _FORCE_INLINE_ Color lightened(float p_amount) const { + + Color res = *this; + res.r = CLAMP(res.r + (1.0f - res.r) * p_amount, 0.0, 1.0); + res.g = CLAMP(res.g + (1.0f - res.g) * p_amount, 0.0, 1.0); + res.b = CLAMP(res.b + (1.0f - res.b) * p_amount, 0.0, 1.0); + return res; + } + _FORCE_INLINE_ uint32_t to_rgbe9995() const { const float pow2to9 = 512.0f; diff --git a/core/command_queue_mt.cpp b/core/command_queue_mt.cpp index 8e2aa24c22..2028a18a06 100644 --- a/core/command_queue_mt.cpp +++ b/core/command_queue_mt.cpp @@ -76,6 +76,30 @@ CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() { return &sync_sems[idx]; } +bool CommandQueueMT::dealloc_one() { +tryagain: + if (dealloc_ptr == write_ptr) { + // The queue is empty + return false; + } + + uint32_t size = *(uint32_t *)&command_mem[dealloc_ptr]; + + if (size == 0) { + // End of command buffer wrap down + dealloc_ptr = 0; + goto tryagain; + } + + if (size & 1) { + // Still used, nothing can be deallocated + return false; + } + + dealloc_ptr += (size >> 1) + sizeof(uint32_t); + return true; +} + CommandQueueMT::CommandQueueMT(bool p_sync) { read_ptr = 0; diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index e37d593f9f..af91ee0cd9 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -39,6 +39,230 @@ @author Juan Linietsky <reduzio@gmail.com> */ +#define COMMA(N) _COMMA_##N +#define _COMMA_0 +#define _COMMA_1 , +#define _COMMA_2 , +#define _COMMA_3 , +#define _COMMA_4 , +#define _COMMA_5 , +#define _COMMA_6 , +#define _COMMA_7 , +#define _COMMA_8 , +#define _COMMA_9 , +#define _COMMA_10 , +#define _COMMA_11 , +#define _COMMA_12 , + +// 1-based comma separed list of ITEMs +#define COMMA_SEP_LIST(ITEM, LENGTH) _COMMA_SEP_LIST_##LENGTH(ITEM) +#define _COMMA_SEP_LIST_12(ITEM) \ + _COMMA_SEP_LIST_11(ITEM) \ + , ITEM(12) +#define _COMMA_SEP_LIST_11(ITEM) \ + _COMMA_SEP_LIST_10(ITEM) \ + , ITEM(11) +#define _COMMA_SEP_LIST_10(ITEM) \ + _COMMA_SEP_LIST_9(ITEM) \ + , ITEM(10) +#define _COMMA_SEP_LIST_9(ITEM) \ + _COMMA_SEP_LIST_8(ITEM) \ + , ITEM(9) +#define _COMMA_SEP_LIST_8(ITEM) \ + _COMMA_SEP_LIST_7(ITEM) \ + , ITEM(8) +#define _COMMA_SEP_LIST_7(ITEM) \ + _COMMA_SEP_LIST_6(ITEM) \ + , ITEM(7) +#define _COMMA_SEP_LIST_6(ITEM) \ + _COMMA_SEP_LIST_5(ITEM) \ + , ITEM(6) +#define _COMMA_SEP_LIST_5(ITEM) \ + _COMMA_SEP_LIST_4(ITEM) \ + , ITEM(5) +#define _COMMA_SEP_LIST_4(ITEM) \ + _COMMA_SEP_LIST_3(ITEM) \ + , ITEM(4) +#define _COMMA_SEP_LIST_3(ITEM) \ + _COMMA_SEP_LIST_2(ITEM) \ + , ITEM(3) +#define _COMMA_SEP_LIST_2(ITEM) \ + _COMMA_SEP_LIST_1(ITEM) \ + , ITEM(2) +#define _COMMA_SEP_LIST_1(ITEM) \ + _COMMA_SEP_LIST_0(ITEM) \ + ITEM(1) +#define _COMMA_SEP_LIST_0(ITEM) + +// 1-based semicolon separed list of ITEMs +#define SEMIC_SEP_LIST(ITEM, LENGTH) _SEMIC_SEP_LIST_##LENGTH(ITEM) +#define _SEMIC_SEP_LIST_12(ITEM) \ + _SEMIC_SEP_LIST_11(ITEM); \ + ITEM(12) +#define _SEMIC_SEP_LIST_11(ITEM) \ + _SEMIC_SEP_LIST_10(ITEM); \ + ITEM(11) +#define _SEMIC_SEP_LIST_10(ITEM) \ + _SEMIC_SEP_LIST_9(ITEM); \ + ITEM(10) +#define _SEMIC_SEP_LIST_9(ITEM) \ + _SEMIC_SEP_LIST_8(ITEM); \ + ITEM(9) +#define _SEMIC_SEP_LIST_8(ITEM) \ + _SEMIC_SEP_LIST_7(ITEM); \ + ITEM(8) +#define _SEMIC_SEP_LIST_7(ITEM) \ + _SEMIC_SEP_LIST_6(ITEM); \ + ITEM(7) +#define _SEMIC_SEP_LIST_6(ITEM) \ + _SEMIC_SEP_LIST_5(ITEM); \ + ITEM(6) +#define _SEMIC_SEP_LIST_5(ITEM) \ + _SEMIC_SEP_LIST_4(ITEM); \ + ITEM(5) +#define _SEMIC_SEP_LIST_4(ITEM) \ + _SEMIC_SEP_LIST_3(ITEM); \ + ITEM(4) +#define _SEMIC_SEP_LIST_3(ITEM) \ + _SEMIC_SEP_LIST_2(ITEM); \ + ITEM(3) +#define _SEMIC_SEP_LIST_2(ITEM) \ + _SEMIC_SEP_LIST_1(ITEM); \ + ITEM(2) +#define _SEMIC_SEP_LIST_1(ITEM) \ + _SEMIC_SEP_LIST_0(ITEM) \ + ITEM(1) +#define _SEMIC_SEP_LIST_0(ITEM) + +// 1-based space separed list of ITEMs +#define SPACE_SEP_LIST(ITEM, LENGTH) _SPACE_SEP_LIST_##LENGTH(ITEM) +#define _SPACE_SEP_LIST_12(ITEM) \ + _SPACE_SEP_LIST_11(ITEM) \ + ITEM(12) +#define _SPACE_SEP_LIST_11(ITEM) \ + _SPACE_SEP_LIST_10(ITEM) \ + ITEM(11) +#define _SPACE_SEP_LIST_10(ITEM) \ + _SPACE_SEP_LIST_9(ITEM) \ + ITEM(10) +#define _SPACE_SEP_LIST_9(ITEM) \ + _SPACE_SEP_LIST_8(ITEM) \ + ITEM(9) +#define _SPACE_SEP_LIST_8(ITEM) \ + _SPACE_SEP_LIST_7(ITEM) \ + ITEM(8) +#define _SPACE_SEP_LIST_7(ITEM) \ + _SPACE_SEP_LIST_6(ITEM) \ + ITEM(7) +#define _SPACE_SEP_LIST_6(ITEM) \ + _SPACE_SEP_LIST_5(ITEM) \ + ITEM(6) +#define _SPACE_SEP_LIST_5(ITEM) \ + _SPACE_SEP_LIST_4(ITEM) \ + ITEM(5) +#define _SPACE_SEP_LIST_4(ITEM) \ + _SPACE_SEP_LIST_3(ITEM) \ + ITEM(4) +#define _SPACE_SEP_LIST_3(ITEM) \ + _SPACE_SEP_LIST_2(ITEM) \ + ITEM(3) +#define _SPACE_SEP_LIST_2(ITEM) \ + _SPACE_SEP_LIST_1(ITEM) \ + ITEM(2) +#define _SPACE_SEP_LIST_1(ITEM) \ + _SPACE_SEP_LIST_0(ITEM) \ + ITEM(1) +#define _SPACE_SEP_LIST_0(ITEM) + +#define ARG(N) p##N +#define PARAM(N) P##N p##N +#define TYPE_PARAM(N) class P##N +#define PARAM_DECL(N) typename GetSimpleTypeT<P##N>::type_t p##N + +#define DECL_CMD(N) \ + template <class T, class M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \ + struct Command##N : public CommandBase { \ + T *instance; \ + M method; \ + SEMIC_SEP_LIST(PARAM_DECL, N); \ + virtual void call() { \ + (instance->*method)(COMMA_SEP_LIST(ARG, N)); \ + } \ + }; + +#define DECL_CMD_RET(N) \ + template <class T, class M, COMMA_SEP_LIST(TYPE_PARAM, N) COMMA(N) class R> \ + struct CommandRet##N : public SyncCommand { \ + R *ret; \ + T *instance; \ + M method; \ + SEMIC_SEP_LIST(PARAM_DECL, N); \ + virtual void call() { \ + *ret = (instance->*method)(COMMA_SEP_LIST(ARG, N)); \ + } \ + }; + +#define DECL_CMD_SYNC(N) \ + template <class T, class M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \ + struct CommandSync##N : public SyncCommand { \ + T *instance; \ + M method; \ + SEMIC_SEP_LIST(PARAM_DECL, N); \ + virtual void call() { \ + (instance->*method)(COMMA_SEP_LIST(ARG, N)); \ + } \ + }; + +#define TYPE_ARG(N) P##N +#define CMD_TYPE(N) Command##N<T, M COMMA(N) COMMA_SEP_LIST(TYPE_ARG, N)> +#define CMD_ASSIGN_PARAM(N) cmd->p##N = p##N + +#define DECL_PUSH(N) \ + template <class T, class M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \ + void push(T *p_instance, M p_method COMMA(N) COMMA_SEP_LIST(PARAM, N)) { \ + CMD_TYPE(N) *cmd = allocate_and_lock<CMD_TYPE(N)>(); \ + cmd->instance = p_instance; \ + cmd->method = p_method; \ + SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \ + unlock(); \ + if (sync) sync->post(); \ + } + +#define CMD_RET_TYPE(N) CommandRet##N<T, M, COMMA_SEP_LIST(TYPE_ARG, N) COMMA(N) R> + +#define DECL_PUSH_AND_RET(N) \ + template <class T, class M, COMMA_SEP_LIST(TYPE_PARAM, N) COMMA(N) class R> \ + void push_and_ret(T *p_instance, M p_method, COMMA_SEP_LIST(PARAM, N) COMMA(N) R *r_ret) { \ + SyncSemaphore *ss = _alloc_sync_sem(); \ + CMD_RET_TYPE(N) *cmd = allocate_and_lock<CMD_RET_TYPE(N)>(); \ + cmd->instance = p_instance; \ + cmd->method = p_method; \ + SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \ + cmd->ret = r_ret; \ + cmd->sync_sem = ss; \ + unlock(); \ + if (sync) sync->post(); \ + ss->sem->wait(); \ + } + +#define CMD_SYNC_TYPE(N) CommandSync##N<T, M COMMA(N) COMMA_SEP_LIST(TYPE_ARG, N)> + +#define DECL_PUSH_AND_SYNC(N) \ + template <class T, class M COMMA(N) COMMA_SEP_LIST(TYPE_PARAM, N)> \ + void push_and_sync(T *p_instance, M p_method COMMA(N) COMMA_SEP_LIST(PARAM, N)) { \ + SyncSemaphore *ss = _alloc_sync_sem(); \ + CMD_SYNC_TYPE(N) *cmd = allocate_and_lock<CMD_SYNC_TYPE(N)>(); \ + cmd->instance = p_instance; \ + cmd->method = p_method; \ + SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \ + cmd->sync_sem = ss; \ + unlock(); \ + if (sync) sync->post(); \ + ss->sem->wait(); \ + } + +#define MAX_CMD_PARAMS 12 + class CommandQueueMT { struct SyncSemaphore { @@ -50,551 +274,30 @@ class CommandQueueMT { struct CommandBase { virtual void call() = 0; + virtual void post(){}; virtual ~CommandBase(){}; }; - template <class T, class M> - struct Command0 : public CommandBase { - - T *instance; - M method; - - virtual void call() { (instance->*method)(); } - }; - - template <class T, class M, class P1> - struct Command1 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - - virtual void call() { (instance->*method)(p1); } - }; - - template <class T, class M, class P1, class P2> - struct Command2 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - - virtual void call() { (instance->*method)(p1, p2); } - }; - - template <class T, class M, class P1, class P2, class P3> - struct Command3 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - - virtual void call() { (instance->*method)(p1, p2, p3); } - }; - - template <class T, class M, class P1, class P2, class P3, class P4> - struct Command4 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - - virtual void call() { (instance->*method)(p1, p2, p3, p4); } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5> - struct Command5 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - - virtual void call() { (instance->*method)(p1, p2, p3, p4, p5); } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6> - struct Command6 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - - virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6); } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7> - struct Command7 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - - virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7); } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> - struct Command8 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - typename GetSimpleTypeT<P8>::type_t p8; - - virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8); } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9> - struct Command9 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - typename GetSimpleTypeT<P8>::type_t p8; - typename GetSimpleTypeT<P9>::type_t p9; - - virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9); } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10> - struct Command10 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - typename GetSimpleTypeT<P8>::type_t p8; - typename GetSimpleTypeT<P9>::type_t p9; - typename GetSimpleTypeT<P10>::type_t p10; - - virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11> - struct Command11 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - typename GetSimpleTypeT<P8>::type_t p8; - typename GetSimpleTypeT<P9>::type_t p9; - typename GetSimpleTypeT<P10>::type_t p10; - typename GetSimpleTypeT<P11>::type_t p11; - - virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11, class P12> - struct Command12 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - typename GetSimpleTypeT<P8>::type_t p8; - typename GetSimpleTypeT<P9>::type_t p9; - typename GetSimpleTypeT<P10>::type_t p10; - typename GetSimpleTypeT<P11>::type_t p11; - typename GetSimpleTypeT<P12>::type_t p12; - - virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12); } - }; - - /* comands that return */ - - template <class T, class M, class R> - struct CommandRet0 : public CommandBase { - - T *instance; - M method; - R *ret; - SyncSemaphore *sync; - - virtual void call() { - *ret = (instance->*method)(); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class R> - struct CommandRet1 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - R *ret; - SyncSemaphore *sync; - - virtual void call() { - *ret = (instance->*method)(p1); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class R> - struct CommandRet2 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - R *ret; - SyncSemaphore *sync; - - virtual void call() { - *ret = (instance->*method)(p1, p2); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3, class R> - struct CommandRet3 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - R *ret; - SyncSemaphore *sync; - - virtual void call() { - *ret = (instance->*method)(p1, p2, p3); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class R> - struct CommandRet4 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - R *ret; - SyncSemaphore *sync; - - virtual void call() { - *ret = (instance->*method)(p1, p2, p3, p4); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class R> - struct CommandRet5 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - R *ret; - SyncSemaphore *sync; - - virtual void call() { - *ret = (instance->*method)(p1, p2, p3, p4, p5); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class R> - struct CommandRet6 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - R *ret; - SyncSemaphore *sync; - - virtual void call() { - *ret = (instance->*method)(p1, p2, p3, p4, p5, p6); - sync->sem->post(); - sync->in_use = false; - } - }; + struct SyncCommand : public CommandBase { - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class R> - struct CommandRet7 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - R *ret; - SyncSemaphore *sync; - - virtual void call() { - *ret = (instance->*method)(p1, p2, p3, p4, p5, p6, p7); - sync->sem->post(); - sync->in_use = false; - } - }; + SyncSemaphore *sync_sem; - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class R> - struct CommandRet8 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - typename GetSimpleTypeT<P8>::type_t p8; - R *ret; - SyncSemaphore *sync; - - virtual void call() { - *ret = (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8); - sync->sem->post(); - sync->in_use = false; + virtual void post() { + sync_sem->sem->post(); + sync_sem->in_use = false; } }; - /** commands that don't return but sync */ + DECL_CMD(0) + SPACE_SEP_LIST(DECL_CMD, 12) /* comands that return */ + DECL_CMD_RET(0) + SPACE_SEP_LIST(DECL_CMD_RET, 12) - template <class T, class M> - struct CommandSync0 : public CommandBase { - - T *instance; - M method; - - SyncSemaphore *sync; - - virtual void call() { - (instance->*method)(); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1> - struct CommandSync1 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - - SyncSemaphore *sync; - - virtual void call() { - (instance->*method)(p1); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2> - struct CommandSync2 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - - SyncSemaphore *sync; - - virtual void call() { - (instance->*method)(p1, p2); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3> - struct CommandSync3 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - - SyncSemaphore *sync; - - virtual void call() { - (instance->*method)(p1, p2, p3); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3, class P4> - struct CommandSync4 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - - SyncSemaphore *sync; - - virtual void call() { - (instance->*method)(p1, p2, p3, p4); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5> - struct CommandSync5 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - - SyncSemaphore *sync; - - virtual void call() { - (instance->*method)(p1, p2, p3, p4, p5); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6> - struct CommandSync6 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - - SyncSemaphore *sync; - - virtual void call() { - (instance->*method)(p1, p2, p3, p4, p5, p6); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7> - struct CommandSync7 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - - SyncSemaphore *sync; - - virtual void call() { - (instance->*method)(p1, p2, p3, p4, p5, p6, p7); - sync->sem->post(); - sync->in_use = false; - } - }; - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> - struct CommandSync8 : public CommandBase { - - T *instance; - M method; - typename GetSimpleTypeT<P1>::type_t p1; - typename GetSimpleTypeT<P2>::type_t p2; - typename GetSimpleTypeT<P3>::type_t p3; - typename GetSimpleTypeT<P4>::type_t p4; - typename GetSimpleTypeT<P5>::type_t p5; - typename GetSimpleTypeT<P6>::type_t p6; - typename GetSimpleTypeT<P7>::type_t p7; - typename GetSimpleTypeT<P8>::type_t p8; - - SyncSemaphore *sync; - - virtual void call() { - (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8); - sync->sem->post(); - sync->in_use = false; - } - }; + /* commands that don't return but sync */ + DECL_CMD_SYNC(0) + SPACE_SEP_LIST(DECL_CMD_SYNC, 12) /***** BASE *******/ @@ -607,6 +310,7 @@ class CommandQueueMT { uint8_t command_mem[COMMAND_MEM_SIZE]; uint32_t read_ptr; uint32_t write_ptr; + uint32_t dealloc_ptr; SyncSemaphore sync_sems[SYNC_SEMAPHORES]; Mutex *mutex; Semaphore *sync; @@ -619,18 +323,30 @@ class CommandQueueMT { tryagain: - if (write_ptr < read_ptr) { - // behind read_ptr, check that there is room - if ((read_ptr - write_ptr) <= alloc_size) + if (write_ptr < dealloc_ptr) { + // behind dealloc_ptr, check that there is room + if ((dealloc_ptr - write_ptr) <= alloc_size) { + + // There is no more room, try to deallocate something + if (dealloc_one()) { + goto tryagain; + } return NULL; - } else if (write_ptr >= read_ptr) { - // ahead of read_ptr, check that there is room + } + } else if (write_ptr >= dealloc_ptr) { + // ahead of dealloc_ptr, check that there is room - if ((COMMAND_MEM_SIZE - write_ptr) < alloc_size + 4) { + if ((COMMAND_MEM_SIZE - write_ptr) < alloc_size + sizeof(uint32_t)) { // no room at the end, wrap down; - if (read_ptr == 0) // don't want write_ptr to become read_ptr + if (dealloc_ptr == 0) { // don't want write_ptr to become dealloc_ptr + + // There is no more room, try to deallocate something + if (dealloc_one()) { + goto tryagain; + } return NULL; + } // if this happens, it's a bug ERR_FAIL_COND_V((COMMAND_MEM_SIZE - write_ptr) < sizeof(uint32_t), NULL); @@ -642,9 +358,11 @@ class CommandQueueMT { goto tryagain; } } - // allocate the size + // Allocate the size and the 'in use' bit. + // First bit used to mark if command is still in use (1) + // or if it has been destroyed and can be deallocated (0). uint32_t *p = (uint32_t *)&command_mem[write_ptr]; - *p = sizeof(T); + *p = (sizeof(T) << 1) | 1; write_ptr += sizeof(uint32_t); // allocate the command T *cmd = memnew_placement(&command_mem[write_ptr], T); @@ -669,15 +387,16 @@ class CommandQueueMT { return ret; } - bool flush_one() { - + bool flush_one(bool p_lock = true) { + if (p_lock) lock(); tryagain: // tried to read an empty queue if (read_ptr == write_ptr) return false; - uint32_t size = *(uint32_t *)(&command_mem[read_ptr]); + uint32_t size_ptr = read_ptr; + uint32_t size = *(uint32_t *)&command_mem[read_ptr] >> 1; if (size == 0) { //end of ringbuffer, wrap @@ -689,11 +408,17 @@ class CommandQueueMT { CommandBase *cmd = reinterpret_cast<CommandBase *>(&command_mem[read_ptr]); + read_ptr += size; + + if (p_lock) unlock(); cmd->call(); - cmd->~CommandBase(); + if (p_lock) lock(); - read_ptr += size; + cmd->post(); + cmd->~CommandBase(); + *(uint32_t *)&command_mem[size_ptr] &= ~1; + if (p_lock) unlock(); return true; } @@ -701,681 +426,33 @@ class CommandQueueMT { void unlock(); void wait_for_flush(); SyncSemaphore *_alloc_sync_sem(); + bool dealloc_one(); public: /* NORMAL PUSH COMMANDS */ + DECL_PUSH(0) + SPACE_SEP_LIST(DECL_PUSH, 12) - template <class T, class M> - void push(T *p_instance, M p_method) { - - Command0<T, M> *cmd = allocate_and_lock<Command0<T, M> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1> - void push(T *p_instance, M p_method, P1 p1) { - - Command1<T, M, P1> *cmd = allocate_and_lock<Command1<T, M, P1> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2> - void push(T *p_instance, M p_method, P1 p1, P2 p2) { - - Command2<T, M, P1, P2> *cmd = allocate_and_lock<Command2<T, M, P1, P2> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2, class P3> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3) { - - Command3<T, M, P1, P2, P3> *cmd = allocate_and_lock<Command3<T, M, P1, P2, P3> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2, class P3, class P4> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4) { - - Command4<T, M, P1, P2, P3, P4> *cmd = allocate_and_lock<Command4<T, M, P1, P2, P3, P4> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { - - Command5<T, M, P1, P2, P3, P4, P5> *cmd = allocate_and_lock<Command5<T, M, P1, P2, P3, P4, P5> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) { - - Command6<T, M, P1, P2, P3, P4, P5, P6> *cmd = allocate_and_lock<Command6<T, M, P1, P2, P3, P4, P5, P6> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) { - - Command7<T, M, P1, P2, P3, P4, P5, P6, P7> *cmd = allocate_and_lock<Command7<T, M, P1, P2, P3, P4, P5, P6, P7> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) { - - Command8<T, M, P1, P2, P3, P4, P5, P6, P7, P8> *cmd = allocate_and_lock<Command8<T, M, P1, P2, P3, P4, P5, P6, P7, P8> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - cmd->p8 = p8; - - unlock(); - - if (sync) sync->post(); - } + /* PUSH AND RET COMMANDS */ + DECL_PUSH_AND_RET(0) + SPACE_SEP_LIST(DECL_PUSH_AND_RET, 12) - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) { - - Command9<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9> *cmd = allocate_and_lock<Command9<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - cmd->p8 = p8; - cmd->p9 = p9; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) { - - Command10<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> *cmd = allocate_and_lock<Command10<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - cmd->p8 = p8; - cmd->p9 = p9; - cmd->p10 = p10; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) { - - Command11<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> *cmd = allocate_and_lock<Command11<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - cmd->p8 = p8; - cmd->p9 = p9; - cmd->p10 = p10; - cmd->p11 = p11; - - unlock(); - - if (sync) sync->post(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11, class P12> - void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11, P12 p12) { - - Command12<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12> *cmd = allocate_and_lock<Command12<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - cmd->p8 = p8; - cmd->p9 = p9; - cmd->p10 = p10; - cmd->p11 = p11; - cmd->p12 = p12; - - unlock(); - - if (sync) sync->post(); - } - - /*** PUSH AND RET COMMANDS ***/ - - template <class T, class M, class R> - void push_and_ret(T *p_instance, M p_method, R *r_ret) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandRet0<T, M, R> *cmd = allocate_and_lock<CommandRet0<T, M, R> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->ret = r_ret; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class R> - void push_and_ret(T *p_instance, M p_method, P1 p1, R *r_ret) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandRet1<T, M, P1, R> *cmd = allocate_and_lock<CommandRet1<T, M, P1, R> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->ret = r_ret; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class R> - void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, R *r_ret) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandRet2<T, M, P1, P2, R> *cmd = allocate_and_lock<CommandRet2<T, M, P1, P2, R> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->ret = r_ret; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class R> - void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, R *r_ret) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandRet3<T, M, P1, P2, P3, R> *cmd = allocate_and_lock<CommandRet3<T, M, P1, P2, P3, R> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->ret = r_ret; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class R> - void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, R *r_ret) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandRet4<T, M, P1, P2, P3, P4, R> *cmd = allocate_and_lock<CommandRet4<T, M, P1, P2, P3, P4, R> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->ret = r_ret; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class R> - void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, R *r_ret) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandRet5<T, M, P1, P2, P3, P4, P5, R> *cmd = allocate_and_lock<CommandRet5<T, M, P1, P2, P3, P4, P5, R> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->ret = r_ret; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class R> - void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, R *r_ret) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandRet6<T, M, P1, P2, P3, P4, P5, P6, R> *cmd = allocate_and_lock<CommandRet6<T, M, P1, P2, P3, P4, P5, P6, R> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->ret = r_ret; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class R> - void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, R *r_ret) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandRet7<T, M, P1, P2, P3, P4, P5, P6, P7, R> *cmd = allocate_and_lock<CommandRet7<T, M, P1, P2, P3, P4, P5, P6, P7, R> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - cmd->ret = r_ret; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class R> - void push_and_ret(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, R *r_ret) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandRet8<T, M, P1, P2, P3, P4, P5, P6, P7, P8, R> *cmd = allocate_and_lock<CommandRet8<T, M, P1, P2, P3, P4, P5, P6, P7, P8, R> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - cmd->p8 = p8; - cmd->ret = r_ret; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M> - void push_and_sync(T *p_instance, M p_method) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandSync0<T, M> *cmd = allocate_and_lock<CommandSync0<T, M> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1> - void push_and_sync(T *p_instance, M p_method, P1 p1) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandSync1<T, M, P1> *cmd = allocate_and_lock<CommandSync1<T, M, P1> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2> - void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandSync2<T, M, P1, P2> *cmd = allocate_and_lock<CommandSync2<T, M, P1, P2> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3> - void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandSync3<T, M, P1, P2, P3> *cmd = allocate_and_lock<CommandSync3<T, M, P1, P2, P3> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4> - void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandSync4<T, M, P1, P2, P3, P4> *cmd = allocate_and_lock<CommandSync4<T, M, P1, P2, P3, P4> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5> - void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandSync5<T, M, P1, P2, P3, P4, P5> *cmd = allocate_and_lock<CommandSync5<T, M, P1, P2, P3, P4, P5> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6> - void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandSync6<T, M, P1, P2, P3, P4, P5, P6> *cmd = allocate_and_lock<CommandSync6<T, M, P1, P2, P3, P4, P5, P6> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7> - void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandSync7<T, M, P1, P2, P3, P4, P5, P6, P7> *cmd = allocate_and_lock<CommandSync7<T, M, P1, P2, P3, P4, P5, P6, P7> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } - - template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8> - void push_and_sync(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) { - - SyncSemaphore *ss = _alloc_sync_sem(); - - CommandSync8<T, M, P1, P2, P3, P4, P5, P6, P7, P8> *cmd = allocate_and_lock<CommandSync8<T, M, P1, P2, P3, P4, P5, P6, P7, P8> >(); - - cmd->instance = p_instance; - cmd->method = p_method; - cmd->p1 = p1; - cmd->p2 = p2; - cmd->p3 = p3; - cmd->p4 = p4; - cmd->p5 = p5; - cmd->p6 = p6; - cmd->p7 = p7; - cmd->p8 = p8; - - cmd->sync = ss; - - unlock(); - - if (sync) sync->post(); - ss->sem->wait(); - } + /* PUSH AND RET SYNC COMMANDS*/ + DECL_PUSH_AND_SYNC(0) + SPACE_SEP_LIST(DECL_PUSH_AND_SYNC, 12) void wait_and_flush_one() { ERR_FAIL_COND(!sync); sync->wait(); - lock(); flush_one(); - unlock(); } void flush_all() { //ERR_FAIL_COND(sync); lock(); - while (true) { - bool exit = !flush_one(); - if (exit) - break; - } + while (flush_one(false)) + ; unlock(); } @@ -1383,4 +460,20 @@ public: ~CommandQueueMT(); }; +#undef ARG +#undef PARAM +#undef TYPE_PARAM +#undef PARAM_DECL +#undef DECL_CMD +#undef DECL_CMD_RET +#undef DECL_CMD_SYNC +#undef TYPE_ARG +#undef CMD_TYPE +#undef CMD_ASSIGN_PARAM +#undef DECL_PUSH +#undef CMD_RET_TYPE +#undef DECL_PUSH_AND_RET +#undef CMD_SYNC_TYPE +#undef DECL_CMD_SYNC + #endif diff --git a/core/compressed_translation.cpp b/core/compressed_translation.cpp index 74565d2e32..5c7b793590 100644 --- a/core/compressed_translation.cpp +++ b/core/compressed_translation.cpp @@ -288,7 +288,7 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const { CharString uncomp; uncomp.resize(bucket.elem[idx].uncomp_size + 1); - smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptr(), bucket.elem[idx].uncomp_size); + smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptrw(), bucket.elem[idx].uncomp_size); String rstr; rstr.parse_utf8(uncomp.get_data()); //print_line("Compressed, size: "+itos(bucket.elem[idx].comp_size)); diff --git a/core/dictionary.cpp b/core/dictionary.cpp index bb2e892951..48e65c734f 100644 --- a/core/dictionary.cpp +++ b/core/dictionary.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "dictionary.h" +#include "ordered_hash_map.h" #include "safe_refcount.h" #include "variant.h" @@ -39,22 +40,8 @@ struct _DictionaryVariantHash { struct DictionaryPrivate { - struct Data { - Variant variant; - int order; - }; - SafeRefCount refcount; - HashMap<Variant, Data, _DictionaryVariantHash> variant_map; - int counter; -}; - -struct DictionaryPrivateSort { - - bool operator()(const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair *A, const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair *B) const { - - return A->data.order < B->data.order; - } + OrderedHashMap<Variant, Variant, _DictionaryVariantHash> variant_map; }; void Dictionary::get_key_list(List<Variant> *p_keys) const { @@ -62,61 +49,45 @@ void Dictionary::get_key_list(List<Variant> *p_keys) const { if (_p->variant_map.empty()) return; - int count = _p->variant_map.size(); - const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair **pairs = (const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair **)alloca(count * sizeof(HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair *)); - _p->variant_map.get_key_value_ptr_array(pairs); - - SortArray<const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair *, DictionaryPrivateSort> sort; - sort.sort(pairs, count); - - for (int i = 0; i < count; i++) { - p_keys->push_back(pairs[i]->key); + for (OrderedHashMap<Variant, Variant, _DictionaryVariantHash>::Element E = _p->variant_map.front(); E; E = E.next()) { + p_keys->push_back(E.key()); } } Variant &Dictionary::operator[](const Variant &p_key) { - DictionaryPrivate::Data *v = _p->variant_map.getptr(p_key); - - if (!v) { - - DictionaryPrivate::Data d; - d.order = _p->counter++; - _p->variant_map[p_key] = d; - v = _p->variant_map.getptr(p_key); - } - return v->variant; + return _p->variant_map[p_key]; } const Variant &Dictionary::operator[](const Variant &p_key) const { - return _p->variant_map[p_key].variant; + return _p->variant_map[p_key]; } const Variant *Dictionary::getptr(const Variant &p_key) const { - const DictionaryPrivate::Data *v = _p->variant_map.getptr(p_key); - if (!v) + OrderedHashMap<Variant, Variant, _DictionaryVariantHash>::ConstElement E = ((const OrderedHashMap<Variant, Variant, _DictionaryVariantHash> *)&_p->variant_map)->find(p_key); + + if (!E) return NULL; - else - return &v->variant; + return &E.get(); } Variant *Dictionary::getptr(const Variant &p_key) { - DictionaryPrivate::Data *v = _p->variant_map.getptr(p_key); - if (!v) + OrderedHashMap<Variant, Variant, _DictionaryVariantHash>::Element E = _p->variant_map.find(p_key); + + if (!E) return NULL; - else - return &v->variant; + return &E.get(); } Variant Dictionary::get_valid(const Variant &p_key) const { - DictionaryPrivate::Data *v = _p->variant_map.getptr(p_key); - if (!v) + OrderedHashMap<Variant, Variant, _DictionaryVariantHash>::ConstElement E = ((const OrderedHashMap<Variant, Variant, _DictionaryVariantHash> *)&_p->variant_map)->find(p_key); + + if (!E) return Variant(); - else - return v->variant; + return E.get(); } int Dictionary::size() const { @@ -171,7 +142,6 @@ void Dictionary::_ref(const Dictionary &p_from) const { void Dictionary::clear() { _p->variant_map.clear(); - _p->counter = 0; } void Dictionary::_unref() const { @@ -205,15 +175,10 @@ Array Dictionary::keys() const { if (_p->variant_map.empty()) return varr; - int count = _p->variant_map.size(); - const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair **pairs = (const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair **)alloca(count * sizeof(HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair *)); - _p->variant_map.get_key_value_ptr_array(pairs); - - SortArray<const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair *, DictionaryPrivateSort> sort; - sort.sort(pairs, count); - - for (int i = 0; i < count; i++) { - varr[i] = pairs[i]->key; + int i = 0; + for (OrderedHashMap<Variant, Variant, _DictionaryVariantHash>::Element E = _p->variant_map.front(); E; E = E.next()) { + varr[i] = E.key(); + i++; } return varr; @@ -226,15 +191,10 @@ Array Dictionary::values() const { if (_p->variant_map.empty()) return varr; - int count = _p->variant_map.size(); - const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair **pairs = (const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair **)alloca(count * sizeof(HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair *)); - _p->variant_map.get_key_value_ptr_array(pairs); - - SortArray<const HashMap<Variant, DictionaryPrivate::Data, _DictionaryVariantHash>::Pair *, DictionaryPrivateSort> sort; - sort.sort(pairs, count); - - for (int i = 0; i < count; i++) { - varr[i] = pairs[i]->data.variant; + int i = 0; + for (OrderedHashMap<Variant, Variant, _DictionaryVariantHash>::Element E = _p->variant_map.front(); E; E = E.next()) { + varr[i] = E.get(); + i++; } return varr; @@ -242,7 +202,15 @@ Array Dictionary::values() const { const Variant *Dictionary::next(const Variant *p_key) const { - return _p->variant_map.next(p_key); + if (p_key == NULL) { + // caller wants to get the first element + return &_p->variant_map.front().key(); + } + OrderedHashMap<Variant, Variant, _DictionaryVariantHash>::Element E = _p->variant_map.find(*p_key); + + if (E && E.next()) + return &E.next().key(); + return NULL; } Dictionary Dictionary::copy() const { @@ -273,7 +241,6 @@ Dictionary::Dictionary() { _p = memnew(DictionaryPrivate); _p->refcount.init(); - _p->counter = 0; } Dictionary::~Dictionary() { diff --git a/core/engine.cpp b/core/engine.cpp index c609ae9520..53c7a73b43 100644 --- a/core/engine.cpp +++ b/core/engine.cpp @@ -84,22 +84,47 @@ Dictionary Engine::get_version_info() const { #else dict["patch"] = 0; #endif - dict["status"] = _MKSTR(VERSION_STATUS); - dict["revision"] = _MKSTR(VERSION_REVISION); + dict["status"] = VERSION_STATUS; + dict["build"] = VERSION_BUILD; dict["year"] = VERSION_YEAR; - String hash = String(VERSION_HASH); + String hash = VERSION_HASH; dict["hash"] = hash.length() == 0 ? String("unknown") : hash; String stringver = String(dict["major"]) + "." + String(dict["minor"]); if ((int)dict["patch"] != 0) stringver += "." + String(dict["patch"]); - stringver += "-" + String(dict["status"]) + " (" + String(dict["revision"]) + ")"; + stringver += "-" + String(dict["status"]) + " (" + String(dict["build"]) + ")"; dict["string"] = stringver; return dict; } +void Engine::add_singleton(const Singleton &p_singleton) { + + singletons.push_back(p_singleton); + singleton_ptrs[p_singleton.name] = p_singleton.ptr; +} + +Object *Engine::get_singleton_object(const String &p_name) const { + + const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name); + ERR_EXPLAIN("Failed to retrieve non-existent singleton '" + p_name + "'"); + ERR_FAIL_COND_V(!E, NULL); + return E->get(); +}; + +bool Engine::has_singleton(const String &p_name) const { + + return singleton_ptrs.has(p_name); +}; + +void Engine::get_singletons(List<Singleton> *p_singletons) { + + for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) + p_singletons->push_back(E->get()); +} + Engine *Engine::singleton = NULL; Engine *Engine::get_singleton() { diff --git a/core/engine.h b/core/engine.h index 3b4979582f..4a573c1539 100644 --- a/core/engine.h +++ b/core/engine.h @@ -37,6 +37,17 @@ class Engine { +public: + struct Singleton { + StringName name; + Object *ptr; + Singleton(const StringName &p_name = StringName(), Object *p_ptr = NULL) + : name(p_name), + ptr(p_ptr) { + } + }; + +private: friend class Main; uint64_t frames_drawn; @@ -54,6 +65,9 @@ class Engine { uint64_t _idle_frames; bool _in_physics; + List<Singleton> singletons; + Map<StringName, Object *> singleton_ptrs; + bool editor_hint; static Engine *singleton; @@ -83,6 +97,11 @@ public: void set_frame_delay(uint32_t p_msec); uint32_t get_frame_delay() const; + void add_singleton(const Singleton &p_singleton); + void get_singletons(List<Singleton> *p_singletons); + bool has_singleton(const String &p_name) const; + Object *get_singleton_object(const String &p_name) const; + _FORCE_INLINE_ bool get_use_pixel_snap() const { return _pixel_snap; } #ifdef TOOLS_ENABLED diff --git a/core/error_list.h b/core/error_list.h index 50d248b3d0..9a36b27aab 100644 --- a/core/error_list.h +++ b/core/error_list.h @@ -87,8 +87,6 @@ enum Error { ERR_HELP, ///< user requested help!! ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior. ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames - ERR_OMFG_THIS_IS_VERY_VERY_BAD, ///< shit happens, has never been used, though - ERR_WTF = ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above }; #endif diff --git a/core/error_macros.cpp b/core/error_macros.cpp index 7d85aa9001..a942b1dd2d 100644 --- a/core/error_macros.cpp +++ b/core/error_macros.cpp @@ -101,6 +101,6 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co void _err_print_index_error(const char *p_function, const char *p_file, int p_line, int64_t p_index, int64_t p_size, const char *p_index_str, const char *p_size_str, bool fatal) { String fstr(fatal ? "FATAL: " : ""); - String err(fstr + "Index" + p_index_str + "=" + itos(p_index) + " out of size (" + p_size_str + "=" + itos(p_size) + ")"); + String err(fstr + "Index " + p_index_str + "=" + itos(p_index) + " out of size (" + p_size_str + "=" + itos(p_size) + ")"); _err_print_error(p_function, p_file, p_line, err.utf8().get_data()); } diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 8bddeae69a..fb432b85db 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -435,6 +435,8 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_5); BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_6); BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_7); + BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_8); + BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_9); BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_MAX); BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_LX); @@ -489,7 +491,6 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT(ERR_BUSY); BIND_GLOBAL_ENUM_CONSTANT(ERR_HELP); ///< user requested help!! BIND_GLOBAL_ENUM_CONSTANT(ERR_BUG); ///< a bug in the software certainly happened ), due to a double check failing or unexpected behavior. - BIND_GLOBAL_ENUM_CONSTANT(ERR_WTF); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_NONE); BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_RANGE); @@ -555,7 +556,7 @@ void register_global_constants() { BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM2D", Variant::TRANSFORM2D); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_PLANE", Variant::PLANE); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_QUAT", Variant::QUAT); // 10 - BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_RECT3", Variant::RECT3); + BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_AABB", Variant::AABB); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_BASIS", Variant::BASIS); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM", Variant::TRANSFORM); BIND_GLOBAL_ENUM_CONSTANT_CUSTOM("TYPE_COLOR", Variant::COLOR); diff --git a/core/helper/math_fieldwise.cpp b/core/helper/math_fieldwise.cpp index 228611f8b3..2cd8a4f392 100644 --- a/core/helper/math_fieldwise.cpp +++ b/core/helper/math_fieldwise.cpp @@ -46,8 +46,8 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const switch (p_source.get_type()) { - /* clang-format makes a mess of this macro usage */ - /* clang-format off */ + /* clang-format makes a mess of this macro usage */ + /* clang-format off */ case Variant::VECTOR2: { @@ -106,9 +106,9 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } - case Variant::RECT3: { + case Variant::AABB: { - SETUP_TYPE(Rect3) + SETUP_TYPE(AABB) /**/ TRY_TRANSFER_FIELD("px", position.x) else TRY_TRANSFER_FIELD("py", position.y) diff --git a/core/image.cpp b/core/image.cpp index 42684e7ea7..422c0e407b 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -757,22 +757,24 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { _copy_internals_from(dst); } -void Image::crop(int p_width, int p_height) { +void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) { if (!_can_modify(format)) { ERR_EXPLAIN("Cannot crop in indexed, compressed or custom image formats."); ERR_FAIL(); } + ERR_FAIL_COND(p_x < 0); + ERR_FAIL_COND(p_y < 0); ERR_FAIL_COND(p_width <= 0); ERR_FAIL_COND(p_height <= 0); - ERR_FAIL_COND(p_width > MAX_WIDTH); - ERR_FAIL_COND(p_height > MAX_HEIGHT); + ERR_FAIL_COND(p_x + p_width > MAX_WIDTH); + ERR_FAIL_COND(p_y + p_height > MAX_HEIGHT); /* to save memory, cropping should be done in-place, however, since this function will most likely either not be used much, or in critical areas, for now it wont, because it's a waste of time. */ - if (p_width == width && p_height == height) + if (p_width == width && p_height == height && p_x == 0 && p_y == 0) return; uint8_t pdata[16]; //largest is 16 @@ -784,9 +786,11 @@ void Image::crop(int p_width, int p_height) { PoolVector<uint8_t>::Read r = data.read(); PoolVector<uint8_t>::Write w = dst.data.write(); - for (int y = 0; y < p_height; y++) { + int m_h = p_y + p_height; + int m_w = p_x + p_width; + for (int y = p_y; y < m_h; y++) { - for (int x = 0; x < p_width; x++) { + for (int x = p_x; x < m_w; x++) { if ((x >= width || y >= height)) { for (uint32_t i = 0; i < pixel_size; i++) @@ -795,7 +799,7 @@ void Image::crop(int p_width, int p_height) { _get_pixelb(x, y, pixel_size, r.ptr(), pdata); } - dst._put_pixelb(x, y, pixel_size, w.ptr(), pdata); + dst._put_pixelb(x - p_x, y - p_y, pixel_size, w.ptr(), pdata); } } } @@ -805,6 +809,11 @@ void Image::crop(int p_width, int p_height) { _copy_internals_from(dst); } +void Image::crop(int p_width, int p_height) { + + crop_from_point(0, 0, p_width, p_height); +} + void Image::flip_y() { if (!_can_modify(format)) { diff --git a/core/image.h b/core/image.h index 27df65a898..24693aa706 100644 --- a/core/image.h +++ b/core/image.h @@ -207,6 +207,7 @@ public: /** * Crop the image to a specific size, if larger, then the image is filled by black */ + void crop_from_point(int p_x, int p_y, int p_width, int p_height); void crop(int p_width, int p_height); void flip_x(); diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp index daa6b01d6e..2b60150832 100644 --- a/core/io/config_file.cpp +++ b/core/io/config_file.cpp @@ -75,7 +75,7 @@ void ConfigFile::set_value(const String &p_section, const String &p_key, const V } else { if (!values.has(p_section)) { - values[p_section] = Map<String, Variant>(); + values[p_section] = OrderedHashMap<String, Variant>(); } values[p_section][p_key] = p_value; @@ -106,16 +106,16 @@ bool ConfigFile::has_section_key(const String &p_section, const String &p_key) c void ConfigFile::get_sections(List<String> *r_sections) const { - for (const Map<String, Map<String, Variant> >::Element *E = values.front(); E; E = E->next()) { - r_sections->push_back(E->key()); + for (OrderedHashMap<String, OrderedHashMap<String, Variant> >::ConstElement E = values.front(); E; E = E.next()) { + r_sections->push_back(E.key()); } } void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const { ERR_FAIL_COND(!values.has(p_section)); - for (const Map<String, Variant>::Element *E = values[p_section].front(); E; E = E->next()) { - r_keys->push_back(E->key()); + for (OrderedHashMap<String, Variant>::ConstElement E = values[p_section].front(); E; E = E.next()) { + r_keys->push_back(E.key()); } } @@ -135,17 +135,17 @@ Error ConfigFile::save(const String &p_path) { return err; } - for (Map<String, Map<String, Variant> >::Element *E = values.front(); E; E = E->next()) { + for (OrderedHashMap<String, OrderedHashMap<String, Variant> >::Element E = values.front(); E; E = E.next()) { if (E != values.front()) file->store_string("\n"); - file->store_string("[" + E->key() + "]\n\n"); + file->store_string("[" + E.key() + "]\n\n"); - for (Map<String, Variant>::Element *F = E->get().front(); F; F = F->next()) { + for (OrderedHashMap<String, Variant>::Element F = E.get().front(); F; F = F.next()) { String vstr; - VariantWriter::write_to_string(F->get(), vstr); - file->store_string(F->key() + "=" + vstr + "\n"); + VariantWriter::write_to_string(F.get(), vstr); + file->store_string(F.key() + "=" + vstr + "\n"); } } diff --git a/core/io/config_file.h b/core/io/config_file.h index 8ed8a069e4..29bd369a24 100644 --- a/core/io/config_file.h +++ b/core/io/config_file.h @@ -30,13 +30,14 @@ #ifndef CONFIG_FILE_H #define CONFIG_FILE_H +#include "core/ordered_hash_map.h" #include "reference.h" class ConfigFile : public Reference { GDCLASS(ConfigFile, Reference); - Map<String, Map<String, Variant> > values; + OrderedHashMap<String, OrderedHashMap<String, Variant> > values; PoolStringArray _get_sections() const; PoolStringArray _get_section_keys(const String &p_section) const; diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h index 309fc16d09..67751e840f 100644 --- a/core/io/file_access_buffered_fa.h +++ b/core/io/file_access_buffered_fa.h @@ -55,10 +55,10 @@ class FileAccessBufferedFA : public FileAccessBuffered { // on dvector //PoolVector<uint8_t>::Write write = cache.buffer.write(); - //f.get_buffer(write.ptr(), p_size); + //f.get_buffer(write.ptrw(), p_size); // on vector - f.get_buffer(cache.buffer.ptr(), p_size); + f.get_buffer(cache.buffer.ptrw(), p_size); return p_size; }; diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 514e3c65f0..c6f31dc8f0 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -51,7 +51,7 @@ void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_ if (write_max > write_buffer_size) { \ write_buffer_size = next_power_of_2(write_max); \ buffer.resize(write_buffer_size); \ - write_ptr = buffer.ptr(); \ + write_ptr = buffer.ptrw(); \ } \ } @@ -76,14 +76,14 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) { comp_buffer.resize(max_bs); buffer.resize(block_size); - read_ptr = buffer.ptr(); - f->get_buffer(comp_buffer.ptr(), read_blocks[0].csize); + read_ptr = buffer.ptrw(); + f->get_buffer(comp_buffer.ptrw(), read_blocks[0].csize); at_end = false; read_eof = false; read_block_count = bc; read_block_size = read_blocks.size() == 1 ? read_total : block_size; - Compression::decompress(buffer.ptr(), read_block_size, comp_buffer.ptr(), read_blocks[0].csize, cmode); + Compression::decompress(buffer.ptrw(), read_block_size, comp_buffer.ptr(), read_blocks[0].csize, cmode); read_block = 0; read_pos = 0; @@ -114,7 +114,7 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) { write_buffer_size = 256; buffer.resize(256); write_max = 0; - write_ptr = buffer.ptr(); + write_ptr = buffer.ptrw(); //don't store anything else unless it's done saving! } else { @@ -160,7 +160,7 @@ void FileAccessCompressed::close() { Vector<uint8_t> cblock; cblock.resize(Compression::get_max_compressed_buffer_size(bl, cmode)); - int s = Compression::compress(cblock.ptr(), bp, bl, cmode); + int s = Compression::compress(cblock.ptrw(), bp, bl, cmode); f->store_buffer(cblock.ptr(), s); block_sizes.push_back(s); @@ -211,8 +211,8 @@ void FileAccessCompressed::seek(size_t p_position) { read_block = block_idx; f->seek(read_blocks[read_block].offset); - f->get_buffer(comp_buffer.ptr(), read_blocks[read_block].csize); - Compression::decompress(buffer.ptr(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); + f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize); + Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size; } @@ -282,8 +282,8 @@ uint8_t FileAccessCompressed::get_8() const { if (read_block < read_block_count) { //read another block of compressed data - f->get_buffer(comp_buffer.ptr(), read_blocks[read_block].csize); - Compression::decompress(buffer.ptr(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); + f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize); + Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size; read_pos = 0; @@ -315,8 +315,8 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const { if (read_block < read_block_count) { //read another block of compressed data - f->get_buffer(comp_buffer.ptr(), read_blocks[read_block].csize); - Compression::decompress(buffer.ptr(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); + f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize); + Compression::decompress(buffer.ptrw(), read_blocks.size() == 1 ? read_total : block_size, comp_buffer.ptr(), read_blocks[read_block].csize, cmode); read_block_size = read_block == read_block_count - 1 ? read_total % block_size : block_size; read_pos = 0; diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index e5da307153..71ebf57508 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -80,11 +80,11 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 data.resize(ds); - uint32_t blen = p_base->get_buffer(data.ptr(), ds); + uint32_t blen = p_base->get_buffer(data.ptrw(), ds); ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT); aes256_context ctx; - aes256_init(&ctx, key.ptr()); + aes256_init(&ctx, key.ptrw()); for (size_t i = 0; i < ds; i += 16) { @@ -97,7 +97,7 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 MD5_CTX md5; MD5Init(&md5); - MD5Update(&md5, data.ptr(), data.size()); + MD5Update(&md5, (uint8_t *)data.ptr(), data.size()); MD5Final(&md5); ERR_FAIL_COND_V(String::md5(md5.digest) != String::md5(md5d), ERR_FILE_CORRUPT); @@ -141,17 +141,17 @@ void FileAccessEncrypted::close() { MD5_CTX md5; MD5Init(&md5); - MD5Update(&md5, data.ptr(), data.size()); + MD5Update(&md5, (uint8_t *)data.ptr(), data.size()); MD5Final(&md5); compressed.resize(len); - zeromem(compressed.ptr(), len); + zeromem(compressed.ptrw(), len); for (int i = 0; i < data.size(); i++) { compressed[i] = data[i]; } aes256_context ctx; - aes256_init(&ctx, key.ptr()); + aes256_init(&ctx, key.ptrw()); for (size_t i = 0; i < len; i += 16) { diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp index a224abd9e7..61a0521cae 100644 --- a/core/io/file_access_network.cpp +++ b/core/io/file_access_network.cpp @@ -147,7 +147,7 @@ void FileAccessNetworkClient::_thread_func() { Vector<uint8_t> block; block.resize(len); - client->get_data(block.ptr(), len); + client->get_data(block.ptrw(), len); if (fa) //may have been queued fa->_set_block(offset, block); @@ -434,12 +434,12 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const { _queue_page(page + j); } - buff = pages[page].buffer.ptr(); + buff = pages[page].buffer.ptrw(); //queue pages buffer_mutex->unlock(); } - buff = pages[page].buffer.ptr(); + buff = pages[page].buffer.ptrw(); last_page_buff = buff; last_page = page; } diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 46d52384e5..5097898314 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -30,6 +30,7 @@ #include "http_client.h" #include "io/stream_peer_ssl.h" +#ifndef JAVASCRIPT_ENABLED Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, bool p_verify_host) { close(); @@ -405,38 +406,6 @@ Error HTTPClient::poll() { return OK; } -Dictionary HTTPClient::_get_response_headers_as_dictionary() { - - List<String> rh; - get_response_headers(&rh); - Dictionary ret; - for (const List<String>::Element *E = rh.front(); E; E = E->next()) { - String s = E->get(); - int sp = s.find(":"); - if (sp == -1) - continue; - String key = s.substr(0, sp).strip_edges(); - String value = s.substr(sp + 1, s.length()).strip_edges(); - ret[key] = value; - } - - return ret; -} - -PoolStringArray HTTPClient::_get_response_headers() { - - List<String> rh; - get_response_headers(&rh); - PoolStringArray ret; - ret.resize(rh.size()); - int idx = 0; - for (const List<String>::Element *E = rh.front(); E; E = E->next()) { - ret.set(idx++, E->get()); - } - - return ret; -} - int HTTPClient::get_response_body_length() const { return body_size; @@ -612,6 +581,74 @@ Error HTTPClient::_get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received } } +void HTTPClient::set_read_chunk_size(int p_size) { + ERR_FAIL_COND(p_size < 256 || p_size > (1 << 24)); + read_chunk_size = p_size; +} + +HTTPClient::HTTPClient() { + + tcp_connection = StreamPeerTCP::create_ref(); + resolving = IP::RESOLVER_INVALID_ID; + status = STATUS_DISCONNECTED; + conn_port = 80; + body_size = 0; + chunked = false; + body_left = 0; + chunk_left = 0; + response_num = 0; + ssl = false; + blocking = false; + read_chunk_size = 4096; +} + +HTTPClient::~HTTPClient() { +} + +#endif // #ifndef JAVASCRIPT_ENABLED + +String HTTPClient::query_string_from_dict(const Dictionary &p_dict) { + String query = ""; + Array keys = p_dict.keys(); + for (int i = 0; i < keys.size(); ++i) { + query += "&" + String(keys[i]).http_escape() + "=" + String(p_dict[keys[i]]).http_escape(); + } + query.erase(0, 1); + return query; +} + +Dictionary HTTPClient::_get_response_headers_as_dictionary() { + + List<String> rh; + get_response_headers(&rh); + Dictionary ret; + for (const List<String>::Element *E = rh.front(); E; E = E->next()) { + String s = E->get(); + int sp = s.find(":"); + if (sp == -1) + continue; + String key = s.substr(0, sp).strip_edges(); + String value = s.substr(sp + 1, s.length()).strip_edges(); + ret[key] = value; + } + + return ret; +} + +PoolStringArray HTTPClient::_get_response_headers() { + + List<String> rh; + get_response_headers(&rh); + PoolStringArray ret; + ret.resize(rh.size()); + int idx = 0; + for (const List<String>::Element *E = rh.front(); E; E = E->next()) { + ret.set(idx++, E->get()); + } + + return ret; +} + void HTTPClient::_bind_methods() { ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port", "use_ssl", "verify_host"), &HTTPClient::connect_to_host, DEFVAL(false), DEFVAL(true)); @@ -717,37 +754,3 @@ void HTTPClient::_bind_methods() { BIND_ENUM_CONSTANT(RESPONSE_INSUFFICIENT_STORAGE); BIND_ENUM_CONSTANT(RESPONSE_NOT_EXTENDED); } - -void HTTPClient::set_read_chunk_size(int p_size) { - ERR_FAIL_COND(p_size < 256 || p_size > (1 << 24)); - read_chunk_size = p_size; -} - -String HTTPClient::query_string_from_dict(const Dictionary &p_dict) { - String query = ""; - Array keys = p_dict.keys(); - for (int i = 0; i < keys.size(); ++i) { - query += "&" + String(keys[i]).http_escape() + "=" + String(p_dict[keys[i]]).http_escape(); - } - query.erase(0, 1); - return query; -} - -HTTPClient::HTTPClient() { - - tcp_connection = StreamPeerTCP::create_ref(); - resolving = IP::RESOLVER_INVALID_ID; - status = STATUS_DISCONNECTED; - conn_port = 80; - body_size = 0; - chunked = false; - body_left = 0; - chunk_left = 0; - response_num = 0; - ssl = false; - blocking = false; - read_chunk_size = 4096; -} - -HTTPClient::~HTTPClient() { -} diff --git a/core/io/http_client.h b/core/io/http_client.h index f8a3349e6e..db5dd115bd 100644 --- a/core/io/http_client.h +++ b/core/io/http_client.h @@ -131,6 +131,7 @@ public: }; private: +#ifndef JAVASCRIPT_ENABLED Status status; IP::ResolverID resolving; int conn_port; @@ -152,13 +153,18 @@ private: int response_num; Vector<String> response_headers; + int read_chunk_size; + + Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received); + +#else +#include "platform/javascript/http_client.h.inc" +#endif - static void _bind_methods(); PoolStringArray _get_response_headers(); Dictionary _get_response_headers_as_dictionary(); - int read_chunk_size; - Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received); + static void _bind_methods(); public: //Error connect_and_get(const String& p_url,bool p_verify_host=true); //connects to a full url and perform request diff --git a/core/io/logger.cpp b/core/io/logger.cpp index ce2ce44b1d..7177359c8a 100644 --- a/core/io/logger.cpp +++ b/core/io/logger.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "logger.h" + #include "os/dir_access.h" #include "os/os.h" #include "print_string.h" @@ -259,6 +260,10 @@ void CompositeLogger::log_error(const char *p_function, const char *p_file, int } } +void CompositeLogger::add_logger(Logger *p_logger) { + loggers.push_back(p_logger); +} + CompositeLogger::~CompositeLogger() { for (int i = 0; i < loggers.size(); ++i) { memdelete(loggers[i]); diff --git a/core/io/logger.h b/core/io/logger.h index cf0cc7699f..f8a394193f 100644 --- a/core/io/logger.h +++ b/core/io/logger.h @@ -101,6 +101,8 @@ public: virtual void logv(const char *p_format, va_list p_list, bool p_err); virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR); + void add_logger(Logger *p_logger); + virtual ~CompositeLogger(); }; diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index d388a622de..37320d7a77 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -159,7 +159,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = str; } break; - // math types + // math types case Variant::VECTOR2: { @@ -245,10 +245,10 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int (*r_len) += 4 * 4; } break; - case Variant::RECT3: { + case Variant::AABB: { ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA); - Rect3 val; + AABB val; val.position.x = decode_float(&buf[0]); val.position.y = decode_float(&buf[4]); val.position.z = decode_float(&buf[8]); @@ -324,7 +324,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int ERR_FAIL_COND_V(len < 12, ERR_INVALID_DATA); Vector<StringName> names; Vector<StringName> subnames; - StringName prop; uint32_t namecount = strlen &= 0x7FFFFFFF; uint32_t subnamecount = decode_uint32(buf + 4); @@ -333,9 +332,10 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int len -= 12; buf += 12; + if (flags & 2) // Obsolete format with property seperate from subpath + subnamecount++; + uint32_t total = namecount + subnamecount; - if (flags & 2) - total++; if (r_len) (*r_len) += 12; @@ -359,10 +359,8 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int if (i < namecount) names.push_back(str); - else if (i < namecount + subnamecount) - subnames.push_back(str); else - prop = str; + subnames.push_back(str); buf += strlen + pad; len -= strlen + pad; @@ -371,7 +369,7 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int (*r_len) += 4 + strlen + pad; } - r_variant = NodePath(names, subnames, flags & 1, prop); + r_variant = NodePath(names, subnames, flags & 1); } else { //old format, just a string @@ -919,8 +917,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo uint32_t flags = 0; if (np.is_absolute()) flags |= 1; - if (np.get_property() != StringName()) - flags |= 2; encode_uint32(flags, buf + 8); @@ -930,8 +926,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 12; int total = np.get_name_count() + np.get_subname_count(); - if (np.get_property() != StringName()) - total++; for (int i = 0; i < total; i++) { @@ -939,10 +933,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo if (i < np.get_name_count()) str = np.get_name(i); - else if (i < np.get_name_count() + np.get_subname_count()) - str = np.get_subname(i - np.get_subname_count()); else - str = np.get_property(); + str = np.get_subname(i - np.get_name_count()); CharString utf8 = str.utf8(); @@ -967,7 +959,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo _encode_string(p_variant, buf, r_len); } break; - // math types + // math types case Variant::VECTOR2: { @@ -1045,10 +1037,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 4 * 4; } break; - case Variant::RECT3: { + case Variant::AABB: { if (buf) { - Rect3 aabb = p_variant; + AABB aabb = p_variant; encode_float(aabb.position.x, &buf[0]); encode_float(aabb.position.y, &buf[4]); encode_float(aabb.position.z, &buf[8]); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 03c3c5f615..df0d41ea9d 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -52,7 +52,7 @@ enum { VARIANT_VECTOR3 = 12, VARIANT_PLANE = 13, VARIANT_QUAT = 14, - VARIANT_RECT3 = 15, + VARIANT_AABB = 15, VARIANT_MATRIX3 = 16, VARIANT_TRANSFORM = 17, VARIANT_MATRIX32 = 18, @@ -84,8 +84,10 @@ enum { OBJECT_INTERNAL_RESOURCE = 2, OBJECT_EXTERNAL_RESOURCE_INDEX = 3, //version 2: added 64 bits support for float and int - FORMAT_VERSION = 2, - FORMAT_VERSION_CAN_RENAME_DEPS = 1 + //version 3: changed nodepath encoding + FORMAT_VERSION = 3, + FORMAT_VERSION_CAN_RENAME_DEPS = 1, + FORMAT_VERSION_NO_NODEPATH_PROPERTY = 3, }; @@ -196,9 +198,9 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { r_v = v; } break; - case VARIANT_RECT3: { + case VARIANT_AABB: { - Rect3 v; + AABB v; v.position.x = f->get_real(); v.position.y = f->get_real(); v.position.z = f->get_real(); @@ -267,21 +269,22 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { Vector<StringName> names; Vector<StringName> subnames; - StringName property; bool absolute; int name_count = f->get_16(); uint32_t subname_count = f->get_16(); absolute = subname_count & 0x8000; subname_count &= 0x7FFF; + if (ver_format < FORMAT_VERSION_NO_NODEPATH_PROPERTY) { + subname_count += 1; // has a property field, so we should count it as well + } for (int i = 0; i < name_count; i++) names.push_back(_get_string()); for (uint32_t i = 0; i < subname_count; i++) subnames.push_back(_get_string()); - property = _get_string(); - NodePath np = NodePath(names, subnames, absolute, property); + NodePath np = NodePath(names, subnames, absolute); r_v = np; @@ -856,7 +859,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) { uint32_t ver_major = f->get_32(); uint32_t ver_minor = f->get_32(); - uint32_t ver_format = f->get_32(); + ver_format = f->get_32(); print_bl("big endian: " + itos(big_endian)); #ifdef BIG_ENDIAN_ENABLED @@ -1374,10 +1377,10 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, f->store_real(val.w); } break; - case Variant::RECT3: { + case Variant::AABB: { - f->store_32(VARIANT_RECT3); - Rect3 val = p_property; + f->store_32(VARIANT_AABB); + AABB val = p_property; f->store_real(val.position.x); f->store_real(val.position.y); f->store_real(val.position.z); @@ -1454,7 +1457,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property, f->store_32(get_string_index(np.get_name(i))); for (int i = 0; i < np.get_subname_count(); i++) f->store_32(get_string_index(np.get_subname(i))); - f->store_32(get_string_index(np.get_property())); } break; case Variant::_RID: { @@ -1685,7 +1687,6 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant get_string_index(np.get_name(i)); for (int i = 0; i < np.get_subname_count(); i++) get_string_index(np.get_subname(i)); - get_string_index(np.get_property()); } break; default: {} diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h index 2316f05b3c..687da0a9b4 100644 --- a/core/io/resource_format_binary.h +++ b/core/io/resource_format_binary.h @@ -41,6 +41,7 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader { String res_path; String type; Ref<Resource> resource; + uint32_t ver_format; FileAccess *f; diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 2583eb369d..42a258a10d 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -220,7 +220,7 @@ void StreamPeer::put_var(const Variant &p_variant) { encode_variant(p_variant, NULL, len); buf.resize(len); put_32(len); - encode_variant(p_variant, buf.ptr(), len); + encode_variant(p_variant, buf.ptrw(), len); put_data(buf.ptr(), buf.size()); } @@ -340,7 +340,7 @@ String StreamPeer::get_utf8_string(int p_bytes) { Vector<uint8_t> buf; Error err = buf.resize(p_bytes); ERR_FAIL_COND_V(err != OK, String()); - err = get_data(buf.ptr(), p_bytes); + err = get_data(buf.ptrw(), p_bytes); ERR_FAIL_COND_V(err != OK, String()); String ret; @@ -353,7 +353,7 @@ Variant StreamPeer::get_var() { Vector<uint8_t> var; Error err = var.resize(len); ERR_FAIL_COND_V(err != OK, Variant()); - err = get_data(var.ptr(), len); + err = get_data(var.ptrw(), len); ERR_FAIL_COND_V(err != OK, Variant()); Variant ret; diff --git a/core/list.h b/core/list.h index da201e9868..448be4a5ab 100644 --- a/core/list.h +++ b/core/list.h @@ -306,6 +306,8 @@ public: if (!p_element->next_ptr) { _data->last = n; + } else { + p_element->next_ptr->prev_ptr = n; } p_element->next_ptr = n; @@ -330,6 +332,8 @@ public: if (!p_element->prev_ptr) { _data->first = n; + } else { + p_element->prev_ptr->next_ptr = n; } p_element->prev_ptr = n; diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp index f43af49754..7e26761abf 100644 --- a/core/math/a_star.cpp +++ b/core/math/a_star.cpp @@ -159,6 +159,21 @@ Array AStar::get_points() { return point_list; } +PoolVector<int> AStar::get_point_connections(int p_id) { + + ERR_FAIL_COND_V(!points.has(p_id), PoolVector<int>()); + + PoolVector<int> point_list; + + Point *p = points[p_id]; + + for (int i = 0; i < p->neighbours.size(); i++) { + point_list.push_back(p->neighbours[i]->id); + } + + return point_list; +} + bool AStar::are_points_connected(int p_id, int p_with_id) const { Segment s(p_id, p_with_id); @@ -444,6 +459,8 @@ void AStar::_bind_methods() { ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point); ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points); + ClassDB::bind_method(D_METHOD("get_point_connections"), &AStar::get_point_connections); + ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true)); ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points); ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar::are_points_connected); diff --git a/core/math/a_star.h b/core/math/a_star.h index 23773e82e2..b7b7e54125 100644 --- a/core/math/a_star.h +++ b/core/math/a_star.h @@ -109,6 +109,7 @@ public: void set_point_weight_scale(int p_id, real_t p_weight_scale); void remove_point(int p_id); bool has_point(int p_id) const; + PoolVector<int> get_point_connections(int p_id); Array get_points(); void connect_points(int p_id, int p_with_id, bool bidirectional = true); diff --git a/core/math/rect3.cpp b/core/math/aabb.cpp index 6f01000f61..737a42b337 100644 --- a/core/math/rect3.cpp +++ b/core/math/aabb.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rect3.cpp */ +/* aabb.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,25 +27,25 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "rect3.h" +#include "aabb.h" #include "print_string.h" -real_t Rect3::get_area() const { +real_t AABB::get_area() const { return size.x * size.y * size.z; } -bool Rect3::operator==(const Rect3 &p_rval) const { +bool AABB::operator==(const AABB &p_rval) const { return ((position == p_rval.position) && (size == p_rval.size)); } -bool Rect3::operator!=(const Rect3 &p_rval) const { +bool AABB::operator!=(const AABB &p_rval) const { return ((position != p_rval.position) || (size != p_rval.size)); } -void Rect3::merge_with(const Rect3 &p_aabb) { +void AABB::merge_with(const AABB &p_aabb) { Vector3 beg_1, beg_2; Vector3 end_1, end_2; @@ -68,7 +68,7 @@ void Rect3::merge_with(const Rect3 &p_aabb) { size = max - min; } -Rect3 Rect3::intersection(const Rect3 &p_aabb) const { +AABB AABB::intersection(const AABB &p_aabb) const { Vector3 src_min = position; Vector3 src_max = position + size; @@ -78,7 +78,7 @@ Rect3 Rect3::intersection(const Rect3 &p_aabb) const { Vector3 min, max; if (src_min.x > dst_max.x || src_max.x < dst_min.x) - return Rect3(); + return AABB(); else { min.x = (src_min.x > dst_min.x) ? src_min.x : dst_min.x; @@ -86,7 +86,7 @@ Rect3 Rect3::intersection(const Rect3 &p_aabb) const { } if (src_min.y > dst_max.y || src_max.y < dst_min.y) - return Rect3(); + return AABB(); else { min.y = (src_min.y > dst_min.y) ? src_min.y : dst_min.y; @@ -94,17 +94,17 @@ Rect3 Rect3::intersection(const Rect3 &p_aabb) const { } if (src_min.z > dst_max.z || src_max.z < dst_min.z) - return Rect3(); + return AABB(); else { min.z = (src_min.z > dst_min.z) ? src_min.z : dst_min.z; max.z = (src_max.z < dst_max.z) ? src_max.z : dst_max.z; } - return Rect3(min, max - min); + return AABB(min, max - min); } -bool Rect3::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const { +bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const { Vector3 c1, c2; Vector3 end = position + size; @@ -147,7 +147,7 @@ bool Rect3::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 return true; } -bool Rect3::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const { +bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const { real_t min = 0, max = 1; int axis = 0; @@ -205,7 +205,7 @@ bool Rect3::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vecto return true; } -bool Rect3::intersects_plane(const Plane &p_plane) const { +bool AABB::intersects_plane(const Plane &p_plane) const { Vector3 points[8] = { Vector3(position.x, position.y, position.z), @@ -232,7 +232,7 @@ bool Rect3::intersects_plane(const Plane &p_plane) const { return under && over; } -Vector3 Rect3::get_longest_axis() const { +Vector3 AABB::get_longest_axis() const { Vector3 axis(1, 0, 0); real_t max_size = size.x; @@ -249,7 +249,7 @@ Vector3 Rect3::get_longest_axis() const { return axis; } -int Rect3::get_longest_axis_index() const { +int AABB::get_longest_axis_index() const { int axis = 0; real_t max_size = size.x; @@ -267,7 +267,7 @@ int Rect3::get_longest_axis_index() const { return axis; } -Vector3 Rect3::get_shortest_axis() const { +Vector3 AABB::get_shortest_axis() const { Vector3 axis(1, 0, 0); real_t max_size = size.x; @@ -284,7 +284,7 @@ Vector3 Rect3::get_shortest_axis() const { return axis; } -int Rect3::get_shortest_axis_index() const { +int AABB::get_shortest_axis_index() const { int axis = 0; real_t max_size = size.x; @@ -302,25 +302,25 @@ int Rect3::get_shortest_axis_index() const { return axis; } -Rect3 Rect3::merge(const Rect3 &p_with) const { +AABB AABB::merge(const AABB &p_with) const { - Rect3 aabb = *this; + AABB aabb = *this; aabb.merge_with(p_with); return aabb; } -Rect3 Rect3::expand(const Vector3 &p_vector) const { - Rect3 aabb = *this; +AABB AABB::expand(const Vector3 &p_vector) const { + AABB aabb = *this; aabb.expand_to(p_vector); return aabb; } -Rect3 Rect3::grow(real_t p_by) const { +AABB AABB::grow(real_t p_by) const { - Rect3 aabb = *this; + AABB aabb = *this; aabb.grow_by(p_by); return aabb; } -void Rect3::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { +void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { ERR_FAIL_INDEX(p_edge, 12); switch (p_edge) { @@ -394,7 +394,7 @@ void Rect3::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const { } } -Rect3::operator String() const { +AABB::operator String() const { return String() + position + " - " + size; } diff --git a/core/math/rect3.h b/core/math/aabb.h index c3a2f5fbfb..c60213496a 100644 --- a/core/math/rect3.h +++ b/core/math/aabb.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* rect3.h */ +/* aabb.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -39,7 +39,7 @@ * This is implemented by a point (position) and the box size */ -class Rect3 { +class AABB { public: Vector3 position; Vector3 size; @@ -60,16 +60,16 @@ public: const Vector3 &get_size() const { return size; } void set_size(const Vector3 &p_size) { size = p_size; } - bool operator==(const Rect3 &p_rval) const; - bool operator!=(const Rect3 &p_rval) const; + bool operator==(const AABB &p_rval) const; + bool operator!=(const AABB &p_rval) const; - _FORCE_INLINE_ bool intersects(const Rect3 &p_aabb) const; /// Both AABBs overlap - _FORCE_INLINE_ bool intersects_inclusive(const Rect3 &p_aabb) const; /// Both AABBs (or their faces) overlap - _FORCE_INLINE_ bool encloses(const Rect3 &p_aabb) const; /// p_aabb is completely inside this + _FORCE_INLINE_ bool intersects(const AABB &p_aabb) const; /// Both AABBs overlap + _FORCE_INLINE_ bool intersects_inclusive(const AABB &p_aabb) const; /// Both AABBs (or their faces) overlap + _FORCE_INLINE_ bool encloses(const AABB &p_aabb) const; /// p_aabb is completely inside this - Rect3 merge(const Rect3 &p_with) const; - void merge_with(const Rect3 &p_aabb); ///merge with another AABB - Rect3 intersection(const Rect3 &p_aabb) const; ///get box where two intersect, empty if no intersection occurs + AABB merge(const AABB &p_with) const; + void merge_with(const AABB &p_aabb); ///merge with another AABB + AABB intersection(const AABB &p_aabb) const; ///get box where two intersect, empty if no intersection occurs bool intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip = NULL, Vector3 *r_normal = NULL) const; bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip = NULL, Vector3 *r_normal = NULL) const; _FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const; @@ -88,26 +88,26 @@ public: int get_shortest_axis_index() const; _FORCE_INLINE_ real_t get_shortest_axis_size() const; - Rect3 grow(real_t p_by) const; + AABB grow(real_t p_by) const; _FORCE_INLINE_ void grow_by(real_t p_amount); void get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const; _FORCE_INLINE_ Vector3 get_endpoint(int p_point) const; - Rect3 expand(const Vector3 &p_vector) const; + AABB expand(const Vector3 &p_vector) const; _FORCE_INLINE_ void project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const; _FORCE_INLINE_ void expand_to(const Vector3 &p_vector); /** expand to contain a point if necessary */ operator String() const; - _FORCE_INLINE_ Rect3() {} - inline Rect3(const Vector3 &p_pos, const Vector3 &p_size) + _FORCE_INLINE_ AABB() {} + inline AABB(const Vector3 &p_pos, const Vector3 &p_size) : position(p_pos), size(p_size) { } }; -inline bool Rect3::intersects(const Rect3 &p_aabb) const { +inline bool AABB::intersects(const AABB &p_aabb) const { if (position.x >= (p_aabb.position.x + p_aabb.size.x)) return false; @@ -125,7 +125,7 @@ inline bool Rect3::intersects(const Rect3 &p_aabb) const { return true; } -inline bool Rect3::intersects_inclusive(const Rect3 &p_aabb) const { +inline bool AABB::intersects_inclusive(const AABB &p_aabb) const { if (position.x > (p_aabb.position.x + p_aabb.size.x)) return false; @@ -143,7 +143,7 @@ inline bool Rect3::intersects_inclusive(const Rect3 &p_aabb) const { return true; } -inline bool Rect3::encloses(const Rect3 &p_aabb) const { +inline bool AABB::encloses(const AABB &p_aabb) const { Vector3 src_min = position; Vector3 src_max = position + size; @@ -159,7 +159,7 @@ inline bool Rect3::encloses(const Rect3 &p_aabb) const { (src_max.z > dst_max.z)); } -Vector3 Rect3::get_support(const Vector3 &p_normal) const { +Vector3 AABB::get_support(const Vector3 &p_normal) const { Vector3 half_extents = size * 0.5; Vector3 ofs = position + half_extents; @@ -171,7 +171,7 @@ Vector3 Rect3::get_support(const Vector3 &p_normal) const { ofs; } -Vector3 Rect3::get_endpoint(int p_point) const { +Vector3 AABB::get_endpoint(int p_point) const { switch (p_point) { case 0: return Vector3(position.x, position.y, position.z); @@ -187,7 +187,7 @@ Vector3 Rect3::get_endpoint(int p_point) const { ERR_FAIL_V(Vector3()); } -bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) const { +bool AABB::intersects_convex_shape(const Plane *p_planes, int p_plane_count) const { Vector3 half_extents = size * 0.5; Vector3 ofs = position + half_extents; @@ -206,7 +206,7 @@ bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) co return true; } -bool Rect3::has_point(const Vector3 &p_point) const { +bool AABB::has_point(const Vector3 &p_point) const { if (p_point.x < position.x) return false; @@ -224,7 +224,7 @@ bool Rect3::has_point(const Vector3 &p_point) const { return true; } -inline void Rect3::expand_to(const Vector3 &p_vector) { +inline void AABB::expand_to(const Vector3 &p_vector) { Vector3 begin = position; Vector3 end = position + size; @@ -247,7 +247,7 @@ inline void Rect3::expand_to(const Vector3 &p_vector) { size = end - begin; } -void Rect3::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const { +void AABB::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const { Vector3 half_extents(size.x * 0.5, size.y * 0.5, size.z * 0.5); Vector3 center(position.x + half_extents.x, position.y + half_extents.y, position.z + half_extents.z); @@ -258,7 +258,7 @@ void Rect3::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t & r_max = distance + length; } -inline real_t Rect3::get_longest_axis_size() const { +inline real_t AABB::get_longest_axis_size() const { real_t max_size = size.x; @@ -273,7 +273,7 @@ inline real_t Rect3::get_longest_axis_size() const { return max_size; } -inline real_t Rect3::get_shortest_axis_size() const { +inline real_t AABB::get_shortest_axis_size() const { real_t max_size = size.x; @@ -288,7 +288,7 @@ inline real_t Rect3::get_shortest_axis_size() const { return max_size; } -bool Rect3::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const { +bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const { real_t divx = 1.0 / p_dir.x; real_t divy = 1.0 / p_dir.y; @@ -332,7 +332,7 @@ bool Rect3::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, rea return ((tmin < t1) && (tmax > t0)); } -void Rect3::grow_by(real_t p_amount) { +void AABB::grow_by(real_t p_amount) { position.x -= p_amount; position.y -= p_amount; diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp index be950568cf..bdc040160f 100644 --- a/core/math/bsp_tree.cpp +++ b/core/math/bsp_tree.cpp @@ -31,7 +31,7 @@ #include "error_macros.h" #include "print_string.h" -void BSP_Tree::from_aabb(const Rect3 &p_aabb) { +void BSP_Tree::from_aabb(const AABB &p_aabb) { planes.clear(); @@ -67,7 +67,7 @@ Vector<Plane> BSP_Tree::get_planes() const { return planes; } -Rect3 BSP_Tree::get_aabb() const { +AABB BSP_Tree::get_aabb() const { return aabb; } @@ -577,7 +577,7 @@ BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) { error_radius = p_error_radius; } -BSP_Tree::BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const Rect3 &p_aabb, real_t p_error_radius) +BSP_Tree::BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB &p_aabb, real_t p_error_radius) : nodes(p_nodes), planes(p_planes), aabb(p_aabb), diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h index 2e762ba4de..f64a13ce39 100644 --- a/core/math/bsp_tree.h +++ b/core/math/bsp_tree.h @@ -30,11 +30,11 @@ #ifndef BSP_TREE_H #define BSP_TREE_H +#include "aabb.h" #include "dvector.h" #include "face3.h" #include "method_ptrcall.h" #include "plane.h" -#include "rect3.h" #include "variant.h" #include "vector.h" /** @@ -64,7 +64,7 @@ private: Vector<Node> nodes; Vector<Plane> planes; - Rect3 aabb; + AABB aabb; real_t error_radius; int _get_points_inside(int p_node, const Vector3 *p_points, int *p_indices, const Vector3 &p_center, const Vector3 &p_half_extents, int p_indices_count) const; @@ -76,7 +76,7 @@ public: bool is_empty() const { return nodes.size() == 0; } Vector<Node> get_nodes() const; Vector<Plane> get_planes() const; - Rect3 get_aabb() const; + AABB get_aabb() const; bool point_is_inside(const Vector3 &p_point) const; int get_points_inside(const Vector3 *p_points, int p_point_count) const; @@ -85,12 +85,12 @@ public: operator Variant() const; - void from_aabb(const Rect3 &p_aabb); + void from_aabb(const AABB &p_aabb); BSP_Tree(); BSP_Tree(const Variant &p_variant); BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius = 0); - BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const Rect3 &p_aabb, real_t p_error_radius = 0); + BSP_Tree(const Vector<Node> &p_nodes, const Vector<Plane> &p_planes, const AABB &p_aabb, real_t p_error_radius = 0); ~BSP_Tree(); }; diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 2c587762e8..42d2d0373a 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -140,6 +140,7 @@ void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_ real_t add = ((f1 + f2) * (p_oversample - 1.0)) / 2.0; f1 += add; f2 += add; + f3 *= p_oversample; // always apply KEEP_WIDTH aspect ratio f3 *= p_aspect; @@ -596,7 +597,7 @@ void CameraMatrix::make_scale(const Vector3 &p_scale) { matrix[2][2] = p_scale.z; } -void CameraMatrix::scale_translate_to_fit(const Rect3 &p_aabb) { +void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) { Vector3 min = p_aabb.position; Vector3 max = p_aabb.position + p_aabb.size; diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 3145d73356..15d6b8128e 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -86,7 +86,7 @@ struct CameraMatrix { operator String() const; - void scale_translate_to_fit(const Rect3 &p_aabb); + void scale_translate_to_fit(const AABB &p_aabb); void make_scale(const Vector3 &p_scale); int get_pixels_per_meter(int p_for_pixel_width) const; operator Transform() const; diff --git a/core/math/face3.cpp b/core/math/face3.cpp index e1b172e491..070ce77db4 100644 --- a/core/math/face3.cpp +++ b/core/math/face3.cpp @@ -189,13 +189,13 @@ ClockDirection Face3::get_clock_dir() const { return (normal.dot(vertex[0]) >= 0) ? CLOCKWISE : COUNTERCLOCKWISE; } -bool Face3::intersects_aabb(const Rect3 &p_aabb) const { +bool Face3::intersects_aabb(const AABB &p_aabb) const { /** TEST PLANE **/ if (!p_aabb.intersects_plane(get_plane())) return false; -/** TEST FACE AXIS */ + /** TEST FACE AXIS */ #define TEST_AXIS(m_ax) \ { \ diff --git a/core/math/face3.h b/core/math/face3.h index 8e4a25fb7a..561fa31238 100644 --- a/core/math/face3.h +++ b/core/math/face3.h @@ -30,8 +30,8 @@ #ifndef FACE3_H #define FACE3_H +#include "aabb.h" #include "plane.h" -#include "rect3.h" #include "transform.h" #include "vector3.h" @@ -76,16 +76,16 @@ public: void get_support(const Vector3 &p_normal, const Transform &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const; void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const; - Rect3 get_aabb() const { + AABB get_aabb() const { - Rect3 aabb(vertex[0], Vector3()); + AABB aabb(vertex[0], Vector3()); aabb.expand_to(vertex[1]); aabb.expand_to(vertex[2]); return aabb; } - bool intersects_aabb(const Rect3 &p_aabb) const; - _FORCE_INLINE_ bool intersects_aabb2(const Rect3 &p_aabb) const; + bool intersects_aabb(const AABB &p_aabb) const; + _FORCE_INLINE_ bool intersects_aabb2(const AABB &p_aabb) const; operator String() const; inline Face3() {} @@ -96,7 +96,7 @@ public: } }; -bool Face3::intersects_aabb2(const Rect3 &p_aabb) const { +bool Face3::intersects_aabb2(const AABB &p_aabb) const { Vector3 perp = (vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]); @@ -256,6 +256,6 @@ bool Face3::intersects_aabb2(const Rect3 &p_aabb) const { return true; } -//this sucks... + //this sucks... #endif // FACE3_H diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp index 7c8fb6f17d..39bd34f03c 100644 --- a/core/math/geometry.cpp +++ b/core/math/geometry.cpp @@ -300,7 +300,7 @@ enum _CellFlags { static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, const Vector3 &voxelsize, const Face3 &p_face) { - Rect3 aabb(Vector3(x, y, z), Vector3(len_x, len_y, len_z)); + AABB aabb(Vector3(x, y, z), Vector3(len_x, len_y, len_z)); aabb.position = aabb.position * voxelsize; aabb.size = aabb.size * voxelsize; @@ -575,7 +575,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e PoolVector<Face3>::Read facesr = p_array.read(); const Face3 *faces = facesr.ptr(); - Rect3 global_aabb; + AABB global_aabb; for (int i = 0; i < face_count; i++) { diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index 7715e5d6e5..bc0b3717ed 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -39,6 +39,7 @@ #include <math.h> #define Math_PI 3.14159265358979323846 +#define Math_TAU 6.28318530717958647692 #define Math_SQRT12 0.7071067811865475244008443621048490 #define Math_LN2 0.693147180559945309417 #define Math_INF INFINITY @@ -271,7 +272,7 @@ public: #elif defined(_MSC_VER) && _MSC_VER < 1800 __asm fld a __asm fistp b - /*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) +/*#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) // use AT&T inline assembly style, document that // we use memory as output (=m) and input (m) __asm__ __volatile__ ( diff --git a/core/math/octree.h b/core/math/octree.h index 95a67943fd..6acd4c5f75 100644 --- a/core/math/octree.h +++ b/core/math/octree.h @@ -30,10 +30,10 @@ #ifndef OCTREE_H #define OCTREE_H +#include "aabb.h" #include "list.h" #include "map.h" #include "print_string.h" -#include "rect3.h" #include "variant.h" #include "vector3.h" @@ -106,7 +106,7 @@ private: struct Octant { // cached for FAST plane check - Rect3 aabb; + AABB aabb; uint64_t last_pass; Octant *parent; @@ -152,8 +152,8 @@ private: OctreeElementID _id; Octant *common_parent; - Rect3 aabb; - Rect3 container_aabb; + AABB aabb; + AABB container_aabb; List<PairData *, AL> pair_list; @@ -334,7 +334,7 @@ private: } void _insert_element(Element *p_element, Octant *p_octant); - void _ensure_valid_root(const Rect3 &p_aabb); + void _ensure_valid_root(const AABB &p_aabb); bool _remove_element_from_octant(Element *p_element, Octant *p_octant, Octant *p_limit = NULL); void _remove_element(Element *p_element); void _pair_element(Element *p_element, Octant *p_octant); @@ -351,7 +351,7 @@ private: }; void _cull_convex(Octant *p_octant, _CullConvexData *p_cull); - void _cull_aabb(Octant *p_octant, const Rect3 &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask); + void _cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask); void _cull_segment(Octant *p_octant, const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask); void _cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask); @@ -370,8 +370,8 @@ private: } public: - OctreeElementID create(T *p_userdata, const Rect3 &p_aabb = Rect3(), int p_subindex = 0, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1); - void move(OctreeElementID p_id, const Rect3 &p_aabb); + OctreeElementID create(T *p_userdata, const AABB &p_aabb = AABB(), int p_subindex = 0, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1); + void move(OctreeElementID p_id, const AABB &p_aabb); void set_pairable(OctreeElementID p_id, bool p_pairable = false, uint32_t p_pairable_type = 0, uint32_t pairable_mask = 1); void erase(OctreeElementID p_id); @@ -380,7 +380,7 @@ public: int get_subindex(OctreeElementID p_id) const; int cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask = 0xFFFFFFFF); - int cull_aabb(const Rect3 &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF); + int cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF); int cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF); int cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array = NULL, uint32_t p_mask = 0xFFFFFFFF); @@ -479,7 +479,7 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct } else { /* check againt AABB where child should be */ - Rect3 aabb = p_octant->aabb; + AABB aabb = p_octant->aabb; aabb.size *= 0.5; if (i & 1) @@ -535,12 +535,12 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct } template <class T, bool use_pairs, class AL> -void Octree<T, use_pairs, AL>::_ensure_valid_root(const Rect3 &p_aabb) { +void Octree<T, use_pairs, AL>::_ensure_valid_root(const AABB &p_aabb) { if (!root) { // octre is empty - Rect3 base(Vector3(), Vector3(1.0, 1.0, 1.0) * unit_size); + AABB base(Vector3(), Vector3(1.0, 1.0, 1.0) * unit_size); while (!base.encloses(p_aabb)) { @@ -563,7 +563,7 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const Rect3 &p_aabb) { } else { - Rect3 base = root->aabb; + AABB base = root->aabb; while (!base.encloses(p_aabb)) { @@ -793,7 +793,7 @@ void Octree<T, use_pairs, AL>::_remove_element(Element *p_element) { } template <class T, bool use_pairs, class AL> -OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const Rect3 &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) { +OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) { // check for AABB validity #ifdef DEBUG_ENABLED @@ -833,7 +833,7 @@ OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const Rect3 &p_a } template <class T, bool use_pairs, class AL> -void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const Rect3 &p_aabb) { +void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) { #ifdef DEBUG_ENABLED // check for AABB validity @@ -859,7 +859,7 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const Rect3 &p_aabb) { if (old_has_surf) { _remove_element(&e); // removing e.common_parent = NULL; - e.aabb = Rect3(); + e.aabb = AABB(); _optimize(); } else { _ensure_valid_root(p_aabb); // inserting @@ -886,7 +886,7 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const Rect3 &p_aabb) { return; } - Rect3 combined = e.aabb; + AABB combined = e.aabb; combined.merge_with(p_aabb); _ensure_valid_root(combined); @@ -1072,7 +1072,7 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p } template <class T, bool use_pairs, class AL> -void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const Rect3 &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) { +void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) { if (*p_result_idx == p_result_max) return; //pointless @@ -1313,7 +1313,7 @@ int Octree<T, use_pairs, AL>::cull_convex(const Vector<Plane> &p_convex, T **p_r } template <class T, bool use_pairs, class AL> -int Octree<T, use_pairs, AL>::cull_aabb(const Rect3 &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) { +int Octree<T, use_pairs, AL>::cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) { if (!root) return 0; diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp index e0137b6921..946d9f6b79 100644 --- a/core/math/quick_hull.cpp +++ b/core/math/quick_hull.cpp @@ -38,7 +38,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me /* CREATE AABB VOLUME */ - Rect3 aabb; + AABB aabb; for (int i = 0; i < p_points.size(); i++) { if (i == 0) { diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h index 47ed22615b..f014d0decc 100644 --- a/core/math/quick_hull.h +++ b/core/math/quick_hull.h @@ -30,9 +30,9 @@ #ifndef QUICK_HULL_H #define QUICK_HULL_H +#include "aabb.h" #include "geometry.h" #include "list.h" -#include "rect3.h" #include "set.h" class QuickHull { diff --git a/core/math/transform.h b/core/math/transform.h index 566bf482a9..4d91869121 100644 --- a/core/math/transform.h +++ b/core/math/transform.h @@ -30,9 +30,9 @@ #ifndef TRANSFORM_H #define TRANSFORM_H +#include "aabb.h" #include "matrix3.h" #include "plane.h" -#include "rect3.h" /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -80,8 +80,8 @@ public: _FORCE_INLINE_ Plane xform(const Plane &p_plane) const; _FORCE_INLINE_ Plane xform_inv(const Plane &p_plane) const; - _FORCE_INLINE_ Rect3 xform(const Rect3 &p_aabb) const; - _FORCE_INLINE_ Rect3 xform_inv(const Rect3 &p_aabb) const; + _FORCE_INLINE_ AABB xform(const AABB &p_aabb) const; + _FORCE_INLINE_ AABB xform_inv(const AABB &p_aabb) const; void operator*=(const Transform &p_transform); Transform operator*(const Transform &p_transform) const; @@ -153,14 +153,14 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const { return Plane(normal, d); } -_FORCE_INLINE_ Rect3 Transform::xform(const Rect3 &p_aabb) const { +_FORCE_INLINE_ AABB Transform::xform(const AABB &p_aabb) const { /* define vertices */ Vector3 x = basis.get_axis(0) * p_aabb.size.x; Vector3 y = basis.get_axis(1) * p_aabb.size.y; Vector3 z = basis.get_axis(2) * p_aabb.size.z; Vector3 pos = xform(p_aabb.position); //could be even further optimized - Rect3 new_aabb; + AABB new_aabb; new_aabb.position = pos; new_aabb.expand_to(pos + x); new_aabb.expand_to(pos + y); @@ -172,7 +172,7 @@ _FORCE_INLINE_ Rect3 Transform::xform(const Rect3 &p_aabb) const { return new_aabb; } -_FORCE_INLINE_ Rect3 Transform::xform_inv(const Rect3 &p_aabb) const { +_FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const { /* define vertices */ Vector3 vertices[8] = { @@ -186,7 +186,7 @@ _FORCE_INLINE_ Rect3 Transform::xform_inv(const Rect3 &p_aabb) const { Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z) }; - Rect3 ret; + AABB ret; ret.position = xform_inv(vertices[0]); diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 3b246cb183..5f57c7c26a 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -44,7 +44,7 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in return -1; } - Rect3 aabb; + AABB aabb; aabb = p_bb[p_from]->aabb; for (int i = 1; i < p_size; i++) { @@ -166,7 +166,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { valid = true; } -Vector3 TriangleMesh::get_area_normal(const Rect3 &p_aabb) const { +Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const { uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth); diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h index 2bf67fffcb..4bd9fecf37 100644 --- a/core/math/triangle_mesh.h +++ b/core/math/triangle_mesh.h @@ -47,7 +47,7 @@ class TriangleMesh : public Reference { struct BVH { - Rect3 aabb; + AABB aabb; Vector3 center; //used for sorting int left; int right; @@ -88,7 +88,7 @@ public: bool is_valid() const; bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const; bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal) const; - Vector3 get_area_normal(const Rect3 &p_aabb) const; + Vector3 get_area_normal(const AABB &p_aabb) const; PoolVector<Face3> get_faces() const; void create(const PoolVector<Vector3> &p_faces); diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h index 2875eb912f..d819dfbc27 100644 --- a/core/method_ptrcall.h +++ b/core/method_ptrcall.h @@ -119,7 +119,7 @@ MAKE_PTRARG_BY_REFERENCE(Vector3); MAKE_PTRARG(Transform2D); MAKE_PTRARG_BY_REFERENCE(Plane); MAKE_PTRARG(Quat); -MAKE_PTRARG_BY_REFERENCE(Rect3); +MAKE_PTRARG_BY_REFERENCE(AABB); MAKE_PTRARG_BY_REFERENCE(Basis); MAKE_PTRARG_BY_REFERENCE(Transform); MAKE_PTRARG_BY_REFERENCE(Color); diff --git a/core/node_path.cpp b/core/node_path.cpp index 15f950f605..a12152aca6 100644 --- a/core/node_path.cpp +++ b/core/node_path.cpp @@ -48,8 +48,6 @@ uint32_t NodePath::hash() const { h = h ^ ssn[i].hash(); } - h = h ^ data->property.hash(); - return h; } @@ -81,13 +79,6 @@ StringName NodePath::get_name(int p_idx) const { return data->path[p_idx]; } -StringName NodePath::get_property() const { - - if (!data) - return StringName(); - return data->property; -} - int NodePath::get_subname_count() const { if (!data) @@ -128,9 +119,6 @@ bool NodePath::operator==(const NodePath &p_path) const { if (data->subpath.size() != p_path.data->subpath.size()) return false; - if (data->property != p_path.data->property) - return false; - for (int i = 0; i < data->path.size(); i++) { if (data->path[i] != p_path.data->path[i]) @@ -184,8 +172,6 @@ NodePath::operator String() const { ret += ":" + data->subpath[i].operator String(); } - if (data->property.operator String() != "") - ret += ":" + String(data->property); return ret; } @@ -205,6 +191,7 @@ Vector<StringName> NodePath::get_names() const { return data->path; return Vector<StringName>(); } + Vector<StringName> NodePath::get_subnames() const { if (data) @@ -212,6 +199,21 @@ Vector<StringName> NodePath::get_subnames() const { return Vector<StringName>(); } +StringName NodePath::get_concatenated_subnames() const { + ERR_FAIL_COND_V(!data, StringName()); + + if (!data->concatenated_subpath) { + int spc = data->subpath.size(); + String concatenated; + const StringName *ssn = data->subpath.ptr(); + for (int i = 0; i < spc; i++) { + concatenated += i == 0 ? ssn[i].operator String() : ":" + ssn[i]; + } + data->concatenated_subpath = concatenated; + } + return data->concatenated_subpath; +} + NodePath NodePath::rel_path_to(const NodePath &p_np) const { ERR_FAIL_COND_V(!is_absolute(), NodePath()); @@ -250,10 +252,27 @@ NodePath NodePath::rel_path_to(const NodePath &p_np) const { if (relpath.size() == 0) relpath.push_back("."); - return NodePath(relpath, p_np.get_subnames(), false, p_np.get_property()); + return NodePath(relpath, p_np.get_subnames(), false); } -NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute, const String &p_property) { +NodePath NodePath::get_as_property_path() const { + + if (!data->path.size()) { + return *this; + } else { + Vector<StringName> new_path = data->subpath; + + String initial_subname = data->path[0]; + for (size_t i = 1; i < data->path.size(); i++) { + initial_subname += i == 0 ? data->path[i].operator String() : "/" + data->path[i]; + } + new_path.insert(0, initial_subname); + + return NodePath(Vector<StringName>(), new_path, false); + } +} + +NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) { data = NULL; @@ -264,14 +283,14 @@ NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute, const Stri data->refcount.init(); data->absolute = p_absolute; data->path = p_path; - data->property = p_property; + data->has_slashes = true; } -NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute, const String &p_property) { +NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) { data = NULL; - if (p_path.size() == 0) + if (p_path.size() == 0 && p_subpath.size() == 0) return; data = memnew(Data); @@ -279,7 +298,7 @@ NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p data->absolute = p_absolute; data->path = p_path; data->subpath = p_subpath; - data->property = p_property; + data->has_slashes = true; } void NodePath::simplify() { @@ -320,11 +339,11 @@ NodePath::NodePath(const String &p_path) { return; String path = p_path; - StringName property; Vector<StringName> subpath; int absolute = (path[0] == '/') ? 1 : 0; bool last_is_slash = true; + bool has_slashes = false; int slices = 0; int subpath_pos = path.find(":"); @@ -337,16 +356,13 @@ NodePath::NodePath(const String &p_path) { if (path[i] == ':' || path[i] == 0) { String str = path.substr(from, i - from); - if (path[i] == ':') { - if (str == "") { - ERR_EXPLAIN("Invalid NodePath: " + p_path); - ERR_FAIL(); - } - subpath.push_back(str); - } else { - //property can be empty - property = str; + if (str == "") { + if (path[i] == 0) continue; // Allow end-of-path : + + ERR_EXPLAIN("Invalid NodePath: " + p_path); + ERR_FAIL(); } + subpath.push_back(str); from = i + 1; } @@ -360,6 +376,7 @@ NodePath::NodePath(const String &p_path) { if (path[i] == '/') { last_is_slash = true; + has_slashes = true; } else { if (last_is_slash) @@ -369,13 +386,13 @@ NodePath::NodePath(const String &p_path) { } } - if (slices == 0 && !absolute && !property) + if (slices == 0 && !absolute && !subpath.size()) return; data = memnew(Data); data->refcount.init(); data->absolute = absolute ? true : false; - data->property = property; + data->has_slashes = has_slashes; data->subpath = subpath; if (slices == 0) diff --git a/core/node_path.h b/core/node_path.h index eb5b9eb6cf..063c4f62db 100644 --- a/core/node_path.h +++ b/core/node_path.h @@ -41,10 +41,11 @@ class NodePath { struct Data { SafeRefCount refcount; - StringName property; Vector<StringName> path; Vector<StringName> subpath; + StringName concatenated_subpath; bool absolute; + bool has_slashes; }; Data *data; @@ -53,7 +54,7 @@ class NodePath { public: _FORCE_INLINE_ StringName get_sname() const { - if (data && data->path.size() == 1 && data->subpath.empty() && !data->property) { + if (data && data->path.size() == 1 && data->subpath.empty()) { return data->path[0]; } else { return operator String(); @@ -67,13 +68,13 @@ public: StringName get_subname(int p_idx) const; Vector<StringName> get_names() const; Vector<StringName> get_subnames() const; + StringName get_concatenated_subnames() const; NodePath rel_path_to(const NodePath &p_np) const; + NodePath get_as_property_path() const; void prepend_period(); - StringName get_property() const; - NodePath get_parent() const; uint32_t hash() const; @@ -88,8 +89,8 @@ public: void simplify(); NodePath simplified() const; - NodePath(const Vector<StringName> &p_path, bool p_absolute, const String &p_property = ""); - NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute, const String &p_property = ""); + NodePath(const Vector<StringName> &p_path, bool p_absolute); + NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute); NodePath(const NodePath &p_path); NodePath(const String &p_path); NodePath(); diff --git a/core/object.cpp b/core/object.cpp index 823cbe14d4..1be7337d96 100644 --- a/core/object.cpp +++ b/core/object.cpp @@ -517,6 +517,80 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const { } } +void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_value, bool *r_valid) { + if (p_names.empty()) { + if (r_valid) + *r_valid = false; + return; + } + if (p_names.size() == 1) { + set(p_names[0], p_value, r_valid); + return; + } + + bool valid = false; + if (!r_valid) r_valid = &valid; + + List<Variant> value_stack; + + value_stack.push_back(get(p_names[0], r_valid)); + + if (!*r_valid) { + value_stack.clear(); + return; + } + + for (int i = 1; i < p_names.size() - 1; i++) { + value_stack.push_back(value_stack.back()->get().get_named(p_names[i], r_valid)); + + if (!*r_valid) { + value_stack.clear(); + return; + } + } + + value_stack.push_back(p_value); // p_names[p_names.size() - 1] + + for (int i = p_names.size() - 1; i > 0; i--) { + + value_stack.back()->prev()->get().set_named(p_names[i], value_stack.back()->get(), r_valid); + value_stack.pop_back(); + + if (!*r_valid) { + value_stack.clear(); + return; + } + } + + set(p_names[0], value_stack.back()->get(), r_valid); + value_stack.pop_back(); + + ERR_FAIL_COND(!value_stack.empty()); +} + +Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) const { + if (p_names.empty()) { + if (r_valid) + *r_valid = false; + return Variant(); + } + bool valid = false; + + Variant current_value = get(p_names[0]); + for (int i = 1; i < p_names.size(); i++) { + current_value = current_value.get_named(p_names[i], &valid); + + if (!valid) { + if (r_valid) + *r_valid = false; + return Variant(); + } + } + if (r_valid) + *r_valid = true; + return current_value; +} + void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) const { if (script_instance && p_reversed) { @@ -744,7 +818,7 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) { } Variant::CallError ce; - return call(p_method, argptrs.ptr(), p_args.size(), ce); + return call(p_method, (const Variant **)argptrs.ptr(), p_args.size(), ce); } Variant Object::call(const StringName &p_name, VARIANT_ARG_DECLARE) { @@ -1109,7 +1183,7 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int bind_mem[p_argcount + j] = &c.binds[j]; } - args = bind_mem.ptr(); + args = (const Variant **)bind_mem.ptr(); argc = bind_mem.size(); } @@ -1416,6 +1490,16 @@ Variant Object::_get_bind(const String &p_name) const { return get(p_name); } +void Object::_set_indexed_bind(const NodePath &p_name, const Variant &p_value) { + + set_indexed(p_name.get_as_property_path().get_subnames(), p_value); +} + +Variant Object::_get_indexed_bind(const NodePath &p_name) const { + + return get_indexed(p_name.get_as_property_path().get_subnames()); +} + void Object::initialize_class() { static bool initialized = false; @@ -1513,6 +1597,8 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("is_class", "type"), &Object::is_class); ClassDB::bind_method(D_METHOD("set", "property", "value"), &Object::_set_bind); ClassDB::bind_method(D_METHOD("get", "property"), &Object::_get_bind); + ClassDB::bind_method(D_METHOD("set_indexed", "property", "value"), &Object::_set_indexed_bind); + ClassDB::bind_method(D_METHOD("get_indexed", "property"), &Object::_get_indexed_bind); ClassDB::bind_method(D_METHOD("get_property_list"), &Object::_get_property_list_bind); ClassDB::bind_method(D_METHOD("get_method_list"), &Object::_get_method_list_bind); ClassDB::bind_method(D_METHOD("notification", "what", "reversed"), &Object::notification, DEFVAL(false)); @@ -1661,6 +1747,50 @@ Variant::Type Object::get_static_property_type(const StringName &p_property, boo return Variant::NIL; } +Variant::Type Object::get_static_property_type_indexed(const Vector<StringName> &p_path, bool *r_valid) const { + + if (p_path.size() == 0) { + if (r_valid) + *r_valid = false; + + return Variant::NIL; + } + + bool valid = false; + Variant::Type t = get_static_property_type(p_path[0], &valid); + if (!valid) { + if (r_valid) + *r_valid = false; + + return Variant::NIL; + } + + Variant::CallError ce; + Variant check = Variant::construct(t, NULL, 0, ce); + + for (int i = 1; i < p_path.size(); i++) { + if (check.get_type() == Variant::OBJECT || check.get_type() == Variant::DICTIONARY || check.get_type() == Variant::ARRAY) { + // We cannot be sure about the type of properties this types can have + if (r_valid) + *r_valid = false; + return Variant::NIL; + } + + check = check.get_named(p_path[i], &valid); + + if (!valid) { + if (r_valid) + *r_valid = false; + return Variant::NIL; + } + } + + if (r_valid) + *r_valid = true; + + return check.get_type(); +} + bool Object::is_queued_for_deletion() const { return _is_queued_for_deletion; } diff --git a/core/object.h b/core/object.h index 7af2c78fc3..0a0c781649 100644 --- a/core/object.h +++ b/core/object.h @@ -1,4 +1,4 @@ -/*************************************************************************/ +/*************************************************************************/ /* object.h */ /*************************************************************************/ /* This file is part of: */ @@ -109,10 +109,11 @@ enum PropertyUsageFlags { PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE = 1 << 17, PROPERTY_USAGE_CLASS_IS_ENUM = 1 << 18, PROPERTY_USAGE_NIL_IS_VARIANT = 1 << 19, + PROPERTY_USAGE_INTERNAL = 1 << 20, PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK, PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED, - PROPERTY_USAGE_NOEDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK, + PROPERTY_USAGE_NOEDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNAL, }; #define ADD_SIGNAL(m_signal) ClassDB::add_signal(get_class_static(), m_signal) @@ -477,6 +478,8 @@ private: Array _get_incoming_connections() const; void _set_bind(const String &p_set, const Variant &p_value); Variant _get_bind(const String &p_name) const; + void _set_indexed_bind(const NodePath &p_name, const Variant &p_value); + Variant _get_indexed_bind(const NodePath &p_name) const; void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS]; @@ -627,6 +630,8 @@ public: void set(const StringName &p_name, const Variant &p_value, bool *r_valid = NULL); Variant get(const StringName &p_name, bool *r_valid = NULL) const; + void set_indexed(const Vector<StringName> &p_names, const Variant &p_value, bool *r_valid = NULL); + Variant get_indexed(const Vector<StringName> &p_names, bool *r_valid = NULL) const; void get_property_list(List<PropertyInfo> *p_list, bool p_reversed = false) const; @@ -687,6 +692,7 @@ public: bool is_blocking_signals() const; Variant::Type get_static_property_type(const StringName &p_property, bool *r_valid = NULL) const; + Variant::Type get_static_property_type_indexed(const Vector<StringName> &p_path, bool *r_valid = NULL) const; virtual void get_translatable_strings(List<String> *p_strings) const; diff --git a/core/ordered_hash_map.h b/core/ordered_hash_map.h index 9e95f963e1..1ed5a5d369 100644 --- a/core/ordered_hash_map.h +++ b/core/ordered_hash_map.h @@ -93,8 +93,12 @@ public: return *this; } - friend bool operator==(const Element &, const Element &); - friend bool operator!=(const Element &, const Element &); + _FORCE_INLINE_ bool operator==(const Element &p_other) const { + return this->list_element == p_other.list_element; + } + _FORCE_INLINE_ bool operator!=(const Element &p_other) const { + return this->list_element != p_other.list_element; + } operator bool() const { return (list_element != NULL); @@ -157,8 +161,12 @@ public: return ConstElement(list_element ? list_element->prev() : NULL); } - friend bool operator==(const ConstElement &, const ConstElement &); - friend bool operator!=(const ConstElement &, const ConstElement &); + _FORCE_INLINE_ bool operator==(const ConstElement &p_other) const { + return this->list_element == p_other.list_element; + } + _FORCE_INLINE_ bool operator!=(const ConstElement &p_other) const { + return this->list_element != p_other.list_element; + } operator bool() const { return (list_element != NULL); @@ -181,7 +189,7 @@ public: }; ConstElement find(const K &p_key) const { - typename InternalList::Element **list_element = map.getptr(p_key); + typename InternalList::Element *const *list_element = map.getptr(p_key); if (list_element) { return ConstElement(*list_element); } @@ -288,28 +296,4 @@ public: } }; -template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP> -bool operator==(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &first, - const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &second) { - return (first.list_element == second.list_element); -} - -template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP> -bool operator!=(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &first, - const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::Element &second) { - return (first.list_element != second.list_element); -} - -template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP> -bool operator==(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &first, - const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &second) { - return (first.list_element == second.list_element); -} - -template <class K, class V, class Hasher, class Comparator, uint8_t MIN_HASH_TABLE_POWER, uint8_t RELATIONSHIP> -bool operator!=(const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &first, - const typename OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>::ConstElement &second) { - return (first.list_element != second.list_element); -} - #endif // ORDERED_HASH_MAP_H diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp index 0875f78478..e19c8e8ea5 100644 --- a/core/os/dir_access.cpp +++ b/core/os/dir_access.cpp @@ -38,7 +38,7 @@ String DirAccess::_get_root_path() const { switch (_access_type) { case ACCESS_RESOURCES: return ProjectSettings::get_singleton()->get_resource_path(); - case ACCESS_USERDATA: return OS::get_singleton()->get_data_dir(); + case ACCESS_USERDATA: return OS::get_singleton()->get_user_data_dir(); default: return ""; } @@ -98,6 +98,7 @@ static Error _erase_recursive(DirAccess *da) { err = _erase_recursive(da); if (err) { print_line("err recurso " + E->get()); + da->change_dir(".."); return err; } err = da->change_dir(".."); @@ -217,7 +218,7 @@ String DirAccess::fix_path(String p_path) const { if (p_path.begins_with("user://")) { - String data_dir = OS::get_singleton()->get_data_dir(); + String data_dir = OS::get_singleton()->get_user_data_dir(); if (data_dir != "") { return p_path.replace_first("user:/", data_dir); @@ -332,6 +333,9 @@ Error DirAccess::copy(String p_from, String p_to, int chmod_flags) { if (err == OK && chmod_flags != -1) { fdst->close(); err = fdst->_chmod(p_to, chmod_flags); + // If running on a platform with no chmod support (i.e., Windows), don't fail + if (err == ERR_UNAVAILABLE) + err = OK; } memdelete(fsrc); @@ -340,6 +344,102 @@ Error DirAccess::copy(String p_from, String p_to, int chmod_flags) { return err; } +// Changes dir for the current scope, returning back to the original dir +// when scope exits +class DirChanger { + DirAccess *da; + String original_dir; + +public: + DirChanger(DirAccess *p_da, String p_dir) { + da = p_da; + original_dir = p_da->get_current_dir(); + p_da->change_dir(p_dir); + } + + ~DirChanger() { + da->change_dir(original_dir); + } +}; + +Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags) { + List<String> dirs; + + String curdir = get_current_dir(); + list_dir_begin(); + String n = get_next(); + while (n != String()) { + + if (n != "." && n != "..") { + + if (current_is_dir()) + dirs.push_back(n); + else { + String rel_path = n; + if (!n.is_rel_path()) { + list_dir_end(); + return ERR_BUG; + } + Error err = copy(get_current_dir() + "/" + n, p_to + rel_path, p_chmod_flags); + if (err) { + list_dir_end(); + return err; + } + } + } + + n = get_next(); + } + + list_dir_end(); + + for (List<String>::Element *E = dirs.front(); E; E = E->next()) { + String rel_path = E->get(); + String target_dir = p_to + rel_path; + if (!p_target_da->dir_exists(target_dir)) { + Error err = p_target_da->make_dir(target_dir); + ERR_FAIL_COND_V(err, err); + } + + Error err = change_dir(E->get()); + ERR_FAIL_COND_V(err, err); + err = _copy_dir(p_target_da, p_to + rel_path + "/", p_chmod_flags); + if (err) { + change_dir(".."); + ERR_PRINT("Failed to copy recursively"); + return err; + } + err = change_dir(".."); + if (err) { + ERR_PRINT("Failed to go back"); + return err; + } + } + + return OK; +} + +Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags) { + ERR_FAIL_COND_V(!dir_exists(p_from), ERR_FILE_NOT_FOUND); + + DirAccess *target_da = DirAccess::create_for_path(p_to); + ERR_FAIL_COND_V(!target_da, ERR_CANT_CREATE); + + if (!target_da->dir_exists(p_to)) { + Error err = target_da->make_dir_recursive(p_to); + if (err) { + memdelete(target_da); + } + ERR_FAIL_COND_V(err, err); + } + + DirChanger dir_changer(this, p_from); + Error err = _copy_dir(target_da, p_to + "/", p_chmod_flags); + memdelete(target_da); + + return err; +} + bool DirAccess::exists(String p_dir) { DirAccess *da = DirAccess::create_for_path(p_dir); diff --git a/core/os/dir_access.h b/core/os/dir_access.h index 7fa3ce5cf1..f3d1320041 100644 --- a/core/os/dir_access.h +++ b/core/os/dir_access.h @@ -52,6 +52,9 @@ public: private: AccessType _access_type; static CreateFunc create_func[ACCESS_MAX]; ///< set this to instance a filesystem object + + Error _copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags); + protected: String _get_root_path() const; String _get_root_string() const; @@ -89,6 +92,7 @@ public: static bool exists(String p_dir); virtual size_t get_space_left() = 0; + Error copy_dir(String p_from, String p_to, int chmod_flags = -1); virtual Error copy(String p_from, String p_to, int chmod_flags = -1); virtual Error rename(String p_from, String p_to) = 0; virtual Error remove(String p_name) = 0; diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index fcb3b58fed..7b2062936b 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -152,7 +152,7 @@ String FileAccess::fix_path(const String &p_path) const { if (r_path.begins_with("user://")) { - String data_dir = OS::get_singleton()->get_data_dir(); + String data_dir = OS::get_singleton()->get_user_data_dir(); if (data_dir != "") { return r_path.replace("user:/", data_dir); @@ -481,7 +481,7 @@ Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path) { ERR_FAIL_COND_V(!f, Vector<uint8_t>()); Vector<uint8_t> data; data.resize(f->get_len()); - f->get_buffer(data.ptr(), data.size()); + f->get_buffer(data.ptrw(), data.size()); memdelete(f); return data; } diff --git a/core/os/file_access.h b/core/os/file_access.h index 455dd1ea99..6fda3d9668 100644 --- a/core/os/file_access.h +++ b/core/os/file_access.h @@ -141,7 +141,7 @@ public: virtual Error reopen(const String &p_path, int p_mode_flags); ///< does not change the AccessType - virtual Error _chmod(const String &p_path, int p_mod) { return FAILED; } + virtual Error _chmod(const String &p_path, int p_mod) { return ERR_UNAVAILABLE; } static FileAccess *create(AccessType p_access); /// Create a file access (for the current platform) this is the only portable way of accessing files. static FileAccess *create_for_path(const String &p_path); diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp index 6b43f2c63b..9b2bd30868 100644 --- a/core/os/input_event.cpp +++ b/core/os/input_event.cpp @@ -177,6 +177,14 @@ bool InputEventWithModifiers::get_command() const { return command; } +void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModifiers *event) { + + set_alt(event->get_alt()); + set_shift(event->get_shift()); + set_control(event->get_control()); + set_metakey(event->get_metakey()); +} + void InputEventWithModifiers::_bind_methods() { ClassDB::bind_method(D_METHOD("set_alt", "enable"), &InputEventWithModifiers::set_alt); @@ -270,16 +278,16 @@ String InputEventKey::as_text() const { return kc; if (get_metakey()) { - kc = "Meta+" + kc; + kc = find_keycode_name(KEY_META) + ("+" + kc); } if (get_alt()) { - kc = "Alt+" + kc; + kc = find_keycode_name(KEY_ALT) + ("+" + kc); } if (get_shift()) { - kc = "Shift+" + kc; + kc = find_keycode_name(KEY_SHIFT) + ("+" + kc); } if (get_control()) { - kc = "Ctrl+" + kc; + kc = find_keycode_name(KEY_CONTROL) + ("+" + kc); } return kc; } @@ -436,10 +444,7 @@ Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, co mb->set_id(get_id()); mb->set_device(get_device()); - mb->set_alt(get_alt()); - mb->set_shift(get_shift()); - mb->set_control(get_control()); - mb->set_metakey(get_metakey()); + mb->set_modifiers_from_event(this); mb->set_position(l); mb->set_global_position(g); @@ -555,10 +560,7 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co mm->set_id(get_id()); mm->set_device(get_device()); - mm->set_alt(get_alt()); - mm->set_shift(get_shift()); - mm->set_control(get_control()); - mm->set_metakey(get_metakey()); + mm->set_modifiers_from_event(this); mm->set_position(l); mm->set_global_position(g); @@ -930,3 +932,99 @@ void InputEventAction::_bind_methods() { InputEventAction::InputEventAction() { pressed = false; } +///////////////////////////// + +void InputEventGesture::set_position(const Vector2 &p_pos) { + + pos = p_pos; +} + +void InputEventGesture::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventGesture::set_position); + ClassDB::bind_method(D_METHOD("get_position"), &InputEventGesture::get_position); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position"); +} + +Vector2 InputEventGesture::get_position() const { + + return pos; +} +///////////////////////////// + +void InputEventMagnifyGesture::set_factor(real_t p_factor) { + + factor = p_factor; +} + +real_t InputEventMagnifyGesture::get_factor() const { + + return factor; +} + +Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { + + Ref<InputEventMagnifyGesture> ev; + ev.instance(); + + ev->set_id(get_id()); + ev->set_device(get_device()); + ev->set_modifiers_from_event(this); + + ev->set_position(p_xform.xform(get_position() + p_local_ofs)); + ev->set_factor(get_factor()); + + return ev; +} + +void InputEventMagnifyGesture::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMagnifyGesture::set_factor); + ClassDB::bind_method(D_METHOD("get_factor"), &InputEventMagnifyGesture::get_factor); + + ADD_PROPERTY(PropertyInfo(Variant::REAL, "factor"), "set_factor", "get_factor"); +} + +InputEventMagnifyGesture::InputEventMagnifyGesture() { + + factor = 1.0; +} +///////////////////////////// + +void InputEventPanGesture::set_delta(const Vector2 &p_delta) { + + delta = p_delta; +} + +Vector2 InputEventPanGesture::get_delta() const { + return delta; +} + +Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const { + + Ref<InputEventPanGesture> ev; + ev.instance(); + + ev->set_id(get_id()); + ev->set_device(get_device()); + ev->set_modifiers_from_event(this); + + ev->set_position(p_xform.xform(get_position() + p_local_ofs)); + ev->set_delta(get_delta()); + + return ev; +} + +void InputEventPanGesture::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_delta", "delta"), &InputEventPanGesture::set_delta); + ClassDB::bind_method(D_METHOD("get_delta"), &InputEventPanGesture::get_delta); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "delta"), "set_delta", "get_delta"); +} + +InputEventPanGesture::InputEventPanGesture() { + + delta = Vector2(0, 0); +} diff --git a/core/os/input_event.h b/core/os/input_event.h index f2c8cc802d..614a3289ba 100644 --- a/core/os/input_event.h +++ b/core/os/input_event.h @@ -122,7 +122,9 @@ enum JoystickList { JOY_AXIS_5 = 5, JOY_AXIS_6 = 6, JOY_AXIS_7 = 7, - JOY_AXIS_MAX = 8, + JOY_AXIS_8 = 8, + JOY_AXIS_9 = 9, + JOY_AXIS_MAX = 10, JOY_ANALOG_LX = JOY_AXIS_0, JOY_ANALOG_LY = JOY_AXIS_1, @@ -211,6 +213,8 @@ public: void set_command(bool p_enabled); bool get_command() const; + void set_modifiers_from_event(const InputEventWithModifiers *event); + InputEventWithModifiers(); }; @@ -466,4 +470,51 @@ public: InputEventAction(); }; +class InputEventGesture : public InputEventWithModifiers { + + GDCLASS(InputEventGesture, InputEventWithModifiers) + + Vector2 pos; + +protected: + static void _bind_methods(); + +public: + void set_position(const Vector2 &p_pos); + Vector2 get_position() const; +}; + +class InputEventMagnifyGesture : public InputEventGesture { + + GDCLASS(InputEventMagnifyGesture, InputEventGesture) + real_t factor; + +protected: + static void _bind_methods(); + +public: + void set_factor(real_t p_factor); + real_t get_factor() const; + + virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; + + InputEventMagnifyGesture(); +}; + +class InputEventPanGesture : public InputEventGesture { + + GDCLASS(InputEventPanGesture, InputEventGesture) + Vector2 delta; + +protected: + static void _bind_methods(); + +public: + void set_delta(const Vector2 &p_delta); + Vector2 get_delta() const; + + virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const; + + InputEventPanGesture(); +}; #endif diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp index edf4f3e2f9..dead3b6ac0 100644 --- a/core/os/keyboard.cpp +++ b/core/os/keyboard.cpp @@ -60,7 +60,11 @@ static const _KeyCodeText _keycodes[] = { {KEY_PAGEDOWN ,"PageDown"}, {KEY_SHIFT ,"Shift"}, {KEY_CONTROL ,"Control"}, +#ifdef OSX_ENABLED + {KEY_META ,"Command"}, +#else {KEY_META ,"Meta"}, +#endif {KEY_ALT ,"Alt"}, {KEY_CAPSLOCK ,"CapsLock"}, {KEY_NUMLOCK ,"NumLock"}, @@ -390,14 +394,22 @@ bool keycode_has_unicode(uint32_t p_keycode) { String keycode_get_string(uint32_t p_code) { String codestr; - if (p_code & KEY_MASK_SHIFT) - codestr += "Shift+"; - if (p_code & KEY_MASK_ALT) - codestr += "Alt+"; - if (p_code & KEY_MASK_CTRL) - codestr += "Ctrl+"; - if (p_code & KEY_MASK_META) - codestr += "Meta+"; + if (p_code & KEY_MASK_SHIFT) { + codestr += find_keycode_name(KEY_SHIFT); + codestr += "+"; + } + if (p_code & KEY_MASK_ALT) { + codestr += find_keycode_name(KEY_ALT); + codestr += "+"; + } + if (p_code & KEY_MASK_CTRL) { + codestr += find_keycode_name(KEY_CONTROL); + codestr += "+"; + } + if (p_code & KEY_MASK_META) { + codestr += find_keycode_name(KEY_META); + codestr += "+"; + } p_code &= KEY_CODE_MASK; @@ -433,6 +445,21 @@ int find_keycode(const String &p_code) { return 0; } +const char *find_keycode_name(int p_keycode) { + + const _KeyCodeText *kct = &_keycodes[0]; + + while (kct->text) { + + if (kct->code == p_keycode) { + return kct->text; + } + kct++; + } + + return ""; +} + struct _KeyCodeReplace { int from; int to; diff --git a/core/os/keyboard.h b/core/os/keyboard.h index 509ff23a93..f49cbc6b18 100644 --- a/core/os/keyboard.h +++ b/core/os/keyboard.h @@ -326,6 +326,7 @@ enum KeyModifierMask { String keycode_get_string(uint32_t p_code); bool keycode_has_unicode(uint32_t p_keycode); int find_keycode(const String &p_code); +const char *find_keycode_name(int p_keycode); int keycode_get_count(); int keycode_get_value_by_index(int p_index); const char *keycode_get_name_by_index(int p_index); diff --git a/core/os/memory.cpp b/core/os/memory.cpp index 74d5cbbea1..439951f711 100644 --- a/core/os/memory.cpp +++ b/core/os/memory.cpp @@ -44,6 +44,26 @@ void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) { return p_allocfunc(p_size); } +#ifdef _MSC_VER +void operator delete(void *p_mem, const char *p_description) { + + ERR_EXPLAINC("Call to placement delete should not happen."); + CRASH_NOW(); +} + +void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) { + + ERR_EXPLAINC("Call to placement delete should not happen."); + CRASH_NOW(); +} + +void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) { + + ERR_EXPLAINC("Call to placement delete should not happen."); + CRASH_NOW(); +} +#endif + #ifdef DEBUG_ENABLED uint64_t Memory::mem_usage = 0; uint64_t Memory::max_usage = 0; diff --git a/core/os/memory.h b/core/os/memory.h index f8b3da579b..7801d56837 100644 --- a/core/os/memory.h +++ b/core/os/memory.h @@ -72,6 +72,14 @@ void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)); ///< ope void *operator new(size_t p_size, void *p_pointer, size_t check, const char *p_description); ///< operator new that takes a description and uses a pointer to the preallocated memory +#ifdef _MSC_VER +// When compiling with VC++ 2017, the above declarations of placement new generate many irrelevant warnings (C4291). +// The purpose of the following definitions is to muffle these warnings, not to provide a usable implementation of placement delete. +void operator delete(void *p_mem, const char *p_description); +void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)); +void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description); +#endif + #define memalloc(m_size) Memory::alloc_static(m_size) #define memrealloc(m_mem, m_size) Memory::realloc_static(m_mem, m_size) #define memfree(m_size) Memory::free_static(m_size) diff --git a/core/os/os.cpp b/core/os/os.cpp index eb5d5be33d..8088a6fa74 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -33,6 +33,7 @@ #include "input.h" #include "os/file_access.h" #include "project_settings.h" +#include "version_generated.gen.h" #include <stdarg.h> @@ -62,15 +63,21 @@ void OS::debug_break(){ // something }; -void OS::_set_logger(Logger *p_logger) { +void OS::_set_logger(CompositeLogger *p_logger) { if (_logger) { memdelete(_logger); } _logger = p_logger; } -void OS::initialize_logger() { - _set_logger(memnew(StdLogger)); +void OS::add_logger(Logger *p_logger) { + if (!_logger) { + Vector<Logger *> loggers; + loggers.push_back(p_logger); + _logger = memnew(CompositeLogger(loggers)); + } else { + _logger->add_logger(p_logger); + } } void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type) { @@ -115,6 +122,16 @@ bool OS::is_in_low_processor_usage_mode() const { return low_processor_usage_mode; } +void OS::set_low_processor_usage_mode_sleep_usec(int p_usec) { + + low_processor_usage_mode_sleep_usec = p_usec; +} + +int OS::get_low_processor_usage_mode_sleep_usec() const { + + return low_processor_usage_mode_sleep_usec; +} + void OS::set_clipboard(const String &p_text) { _local_clipboard = p_text; @@ -262,30 +279,69 @@ String OS::get_locale() const { return "en"; } -String OS::get_resource_dir() const { +// Helper function to ensure that a dir name/path will be valid on the OS +String OS::get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator) const { - return ProjectSettings::get_singleton()->get_resource_path(); + Vector<String> invalid_chars = String(": * ? \" < > |").split(" "); + if (p_allow_dir_separator) { + // Dir separators are allowed, but disallow ".." to avoid going up the filesystem + invalid_chars.push_back(".."); + } else { + invalid_chars.push_back("/"); + } + + String safe_dir_name = p_dir_name.replace("\\", "/").strip_edges(); + for (int i = 0; i < invalid_chars.size(); i++) { + safe_dir_name = safe_dir_name.replace(invalid_chars[i], "-"); + } + return safe_dir_name; } -String OS::get_system_dir(SystemDir p_dir) const { +// Path to data, config, cache, etc. OS-specific folders + +// Get properly capitalized engine name for system paths +String OS::get_godot_dir_name() const { + + // Default to lowercase, so only override when different case is needed + return String(VERSION_SHORT_NAME).to_lower(); +} + +// OS equivalent of XDG_DATA_HOME +String OS::get_data_path() const { return "."; } -String OS::get_safe_application_name() const { - String an = ProjectSettings::get_singleton()->get("application/config/name"); - Vector<String> invalid_char = String("\\ / : * ? \" < > |").split(" "); - for (int i = 0; i < invalid_char.size(); i++) { - an = an.replace(invalid_char[i], "-"); - } - return an; +// OS equivalent of XDG_CONFIG_HOME +String OS::get_config_path() const { + + return "."; +} + +// OS equivalent of XDG_CACHE_HOME +String OS::get_cache_path() const { + + return "."; } -String OS::get_data_dir() const { +// OS specific path for user:// +String OS::get_user_data_dir() const { return "."; }; +// Absolute path to res:// +String OS::get_resource_dir() const { + + return ProjectSettings::get_singleton()->get_resource_path(); +} + +// Access system-specific dirs like Documents, Downloads, etc. +String OS::get_system_dir(SystemDir p_dir) const { + + return "."; +} + Error OS::shell_open(String p_uri) { return ERR_UNAVAILABLE; }; @@ -374,9 +430,9 @@ OS::ScreenOrientation OS::get_screen_orientation() const { return (OS::ScreenOrientation)_orientation; } -void OS::_ensure_data_dir() { +void OS::_ensure_user_data_dir() { - String dd = get_data_dir(); + String dd = get_user_data_dir(); DirAccess *da = DirAccess::open(dd); if (da) { memdelete(da); @@ -516,6 +572,33 @@ bool OS::has_feature(const String &p_feature) { if (sizeof(void *) == 4 && p_feature == "32") { return true; } +#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) + if (p_feature == "x86_64") { + return true; + } +#elif (defined(__i386) || defined(__i386__)) + if (p_feature == "x86") { + return true; + } +#elif defined(__aarch64__) + if (p_feature == "arm64") { + return true; + } +#elif defined(__arm__) +#if defined(__ARM_ARCH_7A__) + if (p_feature == "armv7a" || p_feature == "armv7") { + return true; + } +#endif +#if defined(__ARM_ARCH_7S__) + if (p_feature == "armv7s" || p_feature == "armv7") { + return true; + } +#endif + if (p_feature == "arm") { + return true; + } +#endif if (_check_internal_feature_support(p_feature)) return true; @@ -534,6 +617,7 @@ OS::OS() { singleton = this; _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0. low_processor_usage_mode = false; + low_processor_usage_mode_sleep_usec = 10000; _verbose_stdout = false; _no_window = false; _exit_code = 0; @@ -545,7 +629,10 @@ OS::OS() { _stack_bottom = (void *)(&stack_bottom); _logger = NULL; - _set_logger(memnew(StdLogger)); + + Vector<Logger *> loggers; + loggers.push_back(memnew(StdLogger)); + _set_logger(memnew(CompositeLogger(loggers))); } OS::~OS() { diff --git a/core/os/os.h b/core/os/os.h index f5e479ac0b..91fbf082bf 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -50,6 +50,7 @@ class OS { List<String> _cmdline; bool _keep_screen_on; bool low_processor_usage_mode; + int low_processor_usage_mode_sleep_usec; bool _verbose_stdout; String _local_clipboard; uint64_t _msec_splash; @@ -62,10 +63,10 @@ class OS { void *_stack_bottom; - Logger *_logger; + CompositeLogger *_logger; protected: - void _set_logger(Logger *p_logger); + void _set_logger(CompositeLogger *p_logger); public: typedef void (*ImeCallback)(void *p_inp, String p_text, Point2 p_selection); @@ -90,13 +91,15 @@ public: bool fullscreen; bool resizable; bool borderless_window; + bool maximized; float get_aspect() const { return (float)width / (float)height; } - VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false) { + VideoMode(int p_width = 1024, int p_height = 600, bool p_fullscreen = false, bool p_resizable = true, bool p_borderless_window = false, bool p_maximized = false) { width = p_width; height = p_height; fullscreen = p_fullscreen; resizable = p_resizable; borderless_window = p_borderless_window; + maximized = p_maximized; } }; @@ -109,12 +112,11 @@ protected: virtual int get_video_driver_count() const = 0; virtual const char *get_video_driver_name(int p_driver) const = 0; - virtual VideoMode get_default_video_mode() const = 0; - virtual int get_audio_driver_count() const = 0; virtual const char *get_audio_driver_name(int p_driver) const = 0; - virtual void initialize_logger(); + void add_logger(Logger *p_logger); + virtual void initialize_core() = 0; virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) = 0; @@ -126,7 +128,7 @@ protected: virtual void set_cmdline(const char *p_execpath, const List<String> &p_args); - void _ensure_data_dir(); + void _ensure_user_data_dir(); virtual bool _check_internal_feature_support(const String &p_feature) = 0; public: @@ -193,7 +195,7 @@ public: virtual void set_ime_position(const Point2 &p_pos) {} virtual void set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp) {} - virtual Error open_dynamic_library(const String p_path, void *&p_library_handle) { return ERR_UNAVAILABLE; } + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle,bool p_also_set_library_path=false) { return ERR_UNAVAILABLE; } virtual Error close_dynamic_library(void *p_library_handle) { return ERR_UNAVAILABLE; } virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) { return ERR_UNAVAILABLE; } @@ -201,8 +203,9 @@ public: virtual bool is_keep_screen_on() const; virtual void set_low_processor_usage_mode(bool p_enabled); virtual bool is_in_low_processor_usage_mode() const; + virtual void set_low_processor_usage_mode_sleep_usec(int p_usec); + virtual int get_low_processor_usage_mode_sleep_usec() const; - virtual String get_installed_templates_path() const { return ""; } virtual String get_executable_path() const; virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false) = 0; virtual Error kill(const ProcessID &p_pid) = 0; @@ -335,11 +338,15 @@ public: virtual String get_locale() const; - String get_safe_application_name() const; - virtual String get_data_dir() const; - virtual String get_resource_dir() const; + String get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator = false) const; + virtual String get_godot_dir_name() const; - virtual Error move_to_trash(const String &p_path) { return FAILED; } + virtual String get_data_path() const; + virtual String get_config_path() const; + virtual String get_cache_path() const; + + virtual String get_user_data_dir() const; + virtual String get_resource_dir() const; enum SystemDir { SYSTEM_DIR_DESKTOP, @@ -354,6 +361,8 @@ public: virtual String get_system_dir(SystemDir p_dir) const; + virtual Error move_to_trash(const String &p_path) { return FAILED; } + virtual void set_no_window_mode(bool p_enable); virtual bool is_no_window_mode_enabled() const; diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp index ad8438e416..3748df12f7 100644 --- a/core/packed_data_container.cpp +++ b/core/packed_data_container.cpp @@ -234,7 +234,7 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd case Variant::TRANSFORM2D: case Variant::PLANE: case Variant::QUAT: - case Variant::RECT3: + case Variant::AABB: case Variant::BASIS: case Variant::TRANSFORM: case Variant::POOL_BYTE_ARRAY: diff --git a/core/print_string.cpp b/core/print_string.cpp index 92a04cbf0b..520fb3daec 100644 --- a/core/print_string.cpp +++ b/core/print_string.cpp @@ -82,7 +82,25 @@ void print_line(String p_string) { PrintHandlerList *l = print_handler_list; while (l) { - l->printfunc(l->userdata, p_string); + l->printfunc(l->userdata, p_string, false); + l = l->next; + } + + _global_unlock(); +} + +void print_error(String p_string) { + + if (!_print_error_enabled) + return; + + OS::get_singleton()->printerr("%s\n", p_string.utf8().get_data()); + + _global_lock(); + PrintHandlerList *l = print_handler_list; + while (l) { + + l->printfunc(l->userdata, p_string, true); l = l->next; } diff --git a/core/print_string.h b/core/print_string.h index 9f8420c31a..6b68380b9d 100644 --- a/core/print_string.h +++ b/core/print_string.h @@ -34,7 +34,7 @@ extern void (*_print_func)(String); -typedef void (*PrintHandlerFunc)(void *, const String &p_string); +typedef void (*PrintHandlerFunc)(void *, const String &p_string, bool p_error); struct PrintHandlerList { @@ -56,5 +56,6 @@ void remove_print_handler(PrintHandlerList *p_handler); extern bool _print_line_enabled; extern bool _print_error_enabled; extern void print_line(String p_string); +extern void print_error(String p_string); #endif diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 2e4fc26784..67b081de34 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -116,7 +116,7 @@ String ProjectSettings::globalize_path(const String &p_path) const { return p_path.replace("res://", ""); } else if (p_path.begins_with("user://")) { - String data_dir = OS::get_singleton()->get_data_dir(); + String data_dir = OS::get_singleton()->get_user_data_dir(); if (data_dir != "") { return p_path.replace("user:/", data_dir); @@ -429,7 +429,7 @@ Error ProjectSettings::_load_settings_binary(const String p_path) { uint32_t vlen = f->get_32(); Vector<uint8_t> d; d.resize(vlen); - f->get_buffer(d.ptr(), vlen); + f->get_buffer(d.ptrw(), vlen); Variant value; Error err = decode_variant(value, d.ptr(), d.size()); ERR_EXPLAIN("Error decoding property: " + key); @@ -776,32 +776,6 @@ Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default) { return ret; } -void ProjectSettings::add_singleton(const Singleton &p_singleton) { - - singletons.push_back(p_singleton); - singleton_ptrs[p_singleton.name] = p_singleton.ptr; -} - -Object *ProjectSettings::get_singleton_object(const String &p_name) const { - - const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name); - if (!E) - return NULL; - else - return E->get(); -}; - -bool ProjectSettings::has_singleton(const String &p_name) const { - - return get_singleton_object(p_name) != NULL; -}; - -void ProjectSettings::get_singletons(List<Singleton> *p_singletons) { - - for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) - p_singletons->push_back(E->get()); -} - Vector<String> ProjectSettings::get_optimizer_presets() const { List<PropertyInfo> pi; @@ -893,8 +867,6 @@ void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path); ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path); ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save); - ClassDB::bind_method(D_METHOD("has_singleton", "name"), &ProjectSettings::has_singleton); - ClassDB::bind_method(D_METHOD("get_singleton", "name"), &ProjectSettings::get_singleton_object); ClassDB::bind_method(D_METHOD("load_resource_pack", "pack"), &ProjectSettings::_load_resource_pack); ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ProjectSettings::property_can_revert); ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ProjectSettings::property_get_revert); @@ -919,7 +891,8 @@ ProjectSettings::ProjectSettings() { custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "tscn,scn,res"); GLOBAL_DEF("application/run/disable_stdout", false); GLOBAL_DEF("application/run/disable_stderr", false); - GLOBAL_DEF("application/config/use_shared_user_dir", true); + GLOBAL_DEF("application/config/use_custom_user_dir", false); + GLOBAL_DEF("application/config/custom_user_dir_name", ""); key.instance(); key->set_scancode(KEY_ENTER); diff --git a/core/project_settings.h b/core/project_settings.h index f75cad815f..1c4078cebb 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -45,14 +45,6 @@ class ProjectSettings : public Object { public: typedef Map<String, Variant> CustomMap; - struct Singleton { - StringName name; - Object *ptr; - Singleton(const StringName &p_name = StringName(), Object *p_ptr = NULL) - : name(p_name), - ptr(p_ptr) { - } - }; enum { //properties that are not for built in values begin from this value, so builtin ones are displayed first NO_BUILTIN_ORDER_BASE = 1 << 16 @@ -106,9 +98,6 @@ protected: Error _save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); Error _save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); - List<Singleton> singletons; - Map<StringName, Object *> singleton_ptrs; - Error _save_custom_bnd(const String &p_file); bool _load_resource_pack(const String &p_pack); @@ -145,17 +134,11 @@ public: Error save(); void set_custom_property_info(const String &p_prop, const PropertyInfo &p_info); - void add_singleton(const Singleton &p_singleton); - void get_singletons(List<Singleton> *p_singletons); - - bool has_singleton(const String &p_name) const; - Vector<String> get_optimizer_presets() const; List<String> get_input_presets() const { return input_presets; } void set_disable_feature_overrides(bool p_disable); - Object *get_singleton_object(const String &p_name) const; void register_global_defaults(); diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index c6d7cd44e8..17f951e4f4 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -34,6 +34,7 @@ #include "compressed_translation.h" #include "core/io/xml_parser.h" #include "core_string_names.h" +#include "engine.h" #include "func_ref.h" #include "geometry.h" #include "input_map.h" @@ -128,6 +129,9 @@ void register_core_types() { ClassDB::register_class<InputEventScreenDrag>(); ClassDB::register_class<InputEventScreenTouch>(); ClassDB::register_class<InputEventAction>(); + ClassDB::register_virtual_class<InputEventGesture>(); + ClassDB::register_class<InputEventMagnifyGesture>(); + ClassDB::register_class<InputEventPanGesture>(); ClassDB::register_class<FuncRef>(); ClassDB::register_virtual_class<StreamPeer>(); @@ -203,19 +207,19 @@ void register_core_singletons() { ClassDB::register_class<InputMap>(); ClassDB::register_class<_JSON>(); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ProjectSettings", ProjectSettings::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("IP", IP::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Geometry", _Geometry::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ResourceLoader", _ResourceLoader::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ResourceSaver", _ResourceSaver::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("OS", _OS::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Engine", _Engine::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ClassDB", _classdb)); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Marshalls", _Marshalls::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("TranslationServer", TranslationServer::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Input", Input::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("InputMap", InputMap::get_singleton())); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JSON", _JSON::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("ProjectSettings", ProjectSettings::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("IP", IP::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("Geometry", _Geometry::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceLoader", _ResourceLoader::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("ResourceSaver", _ResourceSaver::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("OS", _OS::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("Engine", _Engine::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("ClassDB", _classdb)); + Engine::get_singleton()->add_singleton(Engine::Singleton("Marshalls", _Marshalls::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("TranslationServer", TranslationServer::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("Input", Input::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("InputMap", InputMap::get_singleton())); + Engine::get_singleton()->add_singleton(Engine::Singleton("JSON", _JSON::get_singleton())); } void unregister_core_types() { diff --git a/core/resource.cpp b/core/resource.cpp index 78e20bada4..d339eb78ad 100644 --- a/core/resource.cpp +++ b/core/resource.cpp @@ -184,6 +184,35 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res return Ref<Resource>(r); } +void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache) { + + print_line("configure for local: " + get_class()); + List<PropertyInfo> plist; + get_property_list(&plist); + + local_scene = p_for_scene; + + for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) { + + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + continue; + Variant p = get(E->get().name); + if (p.get_type() == Variant::OBJECT) { + + RES sr = p; + if (sr.is_valid()) { + + if (sr->is_local_to_scene()) { + if (!remap_cache.has(sr)) { + sr->configure_for_local_scene(p_for_scene, remap_cache); + remap_cache[sr] = sr; + } + } + } + } + } +} + Ref<Resource> Resource::duplicate(bool p_subresources) const { List<PropertyInfo> plist; diff --git a/core/resource.h b/core/resource.h index 7dc3b67291..19714a68d1 100644 --- a/core/resource.h +++ b/core/resource.h @@ -108,6 +108,7 @@ public: virtual Ref<Resource> duplicate(bool p_subresources = false) const; Ref<Resource> duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache); + void configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache); void set_local_to_scene(bool p_enable); bool is_local_to_scene() const; diff --git a/core/script_debugger_local.cpp b/core/script_debugger_local.cpp index 8d2600e52d..94c48f1c8f 100644 --- a/core/script_debugger_local.cpp +++ b/core/script_debugger_local.cpp @@ -212,7 +212,7 @@ void ScriptDebuggerLocal::idle_poll() { } SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort; - sort.sort(pinfo.ptr(), ofs); + sort.sort(pinfo.ptrw(), ofs); //falta el frame time @@ -264,7 +264,7 @@ void ScriptDebuggerLocal::profiling_end() { } SortArray<ScriptLanguage::ProfilingInfo, _ScriptDebuggerLocalProfileInfoSort> sort; - sort.sort(pinfo.ptr(), ofs); + sort.sort(pinfo.ptrw(), ofs); uint64_t total_us = 0; for (int i = 0; i < ofs; i++) { diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp index 2feb068ecb..495c99c122 100644 --- a/core/script_debugger_remote.cpp +++ b/core/script_debugger_remote.cpp @@ -29,11 +29,14 @@ /*************************************************************************/ #include "script_debugger_remote.h" +#include "engine.h" #include "io/ip.h" #include "io/marshalls.h" #include "os/input.h" #include "os/os.h" #include "project_settings.h" +#include "scene/main/node.h" + void ScriptDebuggerRemote::_send_video_memory() { List<ResourceUsage> usage; @@ -200,20 +203,39 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue) List<String> members; List<Variant> member_vals; - + if (ScriptInstance *inst = p_script->debug_get_stack_level_instance(lv)) { + members.push_back("self"); + member_vals.push_back(inst->get_owner()); + } p_script->debug_get_stack_level_members(lv, &members, &member_vals); - ERR_CONTINUE(members.size() != member_vals.size()); List<String> locals; List<Variant> local_vals; - p_script->debug_get_stack_level_locals(lv, &locals, &local_vals); - ERR_CONTINUE(locals.size() != local_vals.size()); + List<String> globals; + List<Variant> globals_vals; + p_script->debug_get_globals(&globals, &globals_vals); + ERR_CONTINUE(globals.size() != globals_vals.size()); + packet_peer_stream->put_var("stack_frame_vars"); - packet_peer_stream->put_var(2 + locals.size() * 2 + members.size() * 2); + packet_peer_stream->put_var(3 + (locals.size() + members.size() + globals.size()) * 2); + + { //locals + packet_peer_stream->put_var(locals.size()); + + List<String>::Element *E = locals.front(); + List<Variant>::Element *F = local_vals.front(); + + while (E) { + _put_variable(E->get(), F->get()); + + E = E->next(); + F = F->next(); + } + } { //members packet_peer_stream->put_var(members.size()); @@ -230,11 +252,11 @@ void ScriptDebuggerRemote::debug(ScriptLanguage *p_script, bool p_can_continue) } } - { //locals - packet_peer_stream->put_var(locals.size()); + { //globals + packet_peer_stream->put_var(globals.size()); - List<String>::Element *E = locals.front(); - List<Variant>::Element *F = local_vals.front(); + List<String>::Element *E = globals.front(); + List<Variant>::Element *F = globals_vals.front(); while (E) { _put_variable(E->get(), F->get()); @@ -531,56 +553,88 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) { if (!obj) return; - List<PropertyInfo> pinfo; - obj->get_property_list(&pinfo, true); + typedef Pair<PropertyInfo, Variant> PropertyDesc; + List<PropertyDesc> properties; - int props_to_send = 0; - for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + if (ScriptInstance *si = obj->get_script_instance()) { + if (!si->get_script().is_null()) { - if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { - props_to_send++; - } - } + Set<StringName> members; + si->get_script()->get_members(&members); + for (Set<StringName>::Element *E = members.front(); E; E = E->next()) { - packet_peer_stream->put_var("message:inspect_object"); - packet_peer_stream->put_var(props_to_send * 5 + 4); - packet_peer_stream->put_var(p_id); - packet_peer_stream->put_var(obj->get_class()); - if (obj->is_class("Resource") || obj->is_class("Node")) - packet_peer_stream->put_var(obj->call("get_path")); - else - packet_peer_stream->put_var(""); + Variant m; + if (si->get(E->get(), m)) { + PropertyInfo pi(m.get_type(), String("Members/") + E->get()); + properties.push_back(PropertyDesc(pi, m)); + } + } - packet_peer_stream->put_var(props_to_send); + Map<StringName, Variant> constants; + si->get_script()->get_constants(&constants); + for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { + PropertyInfo pi(E->value().get_type(), (String("Constants/") + E->key())); + properties.push_back(PropertyDesc(pi, E->value())); + } + } + } + if (Node *node = Object::cast_to<Node>(obj)) { + PropertyInfo pi(Variant::NODE_PATH, String("Node/path")); + properties.push_front(PropertyDesc(pi, node->get_path())); + } else if (Resource *res = Object::cast_to<Resource>(obj)) { + if (Script *s = Object::cast_to<Script>(res)) { + Map<StringName, Variant> constants; + s->get_constants(&constants); + for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { + PropertyInfo pi(E->value().get_type(), String("Constants/") + E->key()); + properties.push_front(PropertyDesc(pi, E->value())); + } + } + } + List<PropertyInfo> pinfo; + obj->get_property_list(&pinfo, true); for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { - if (E->get().usage & (PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CATEGORY)) { + properties.push_back(PropertyDesc(E->get(), obj->get(E->get().name))); + } + } - if (E->get().usage & PROPERTY_USAGE_CATEGORY) { - packet_peer_stream->put_var("*" + E->get().name); - } else { - packet_peer_stream->put_var(E->get().name); - } - - Variant var = obj->get(E->get().name); - packet_peer_stream->put_var(E->get().type); - //only send information that can be sent.. - - int len = 0; //test how big is this to encode - encode_variant(var, NULL, len); - - if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size - packet_peer_stream->put_var(PROPERTY_HINT_OBJECT_TOO_BIG); - packet_peer_stream->put_var(""); - packet_peer_stream->put_var(Variant()); - } else { - packet_peer_stream->put_var(E->get().hint); - packet_peer_stream->put_var(E->get().hint_string); - packet_peer_stream->put_var(var); - } + Array send_props; + for (int i = 0; i < properties.size(); i++) { + const PropertyInfo &pi = properties[i].first; + const Variant &var = properties[i].second; + RES res = var; + + Array prop; + prop.push_back(pi.name); + prop.push_back(pi.type); + + //only send information that can be sent.. + int len = 0; //test how big is this to encode + encode_variant(var, NULL, len); + if (len > packet_peer_stream->get_output_buffer_max_size()) { //limit to max size + prop.push_back(PROPERTY_HINT_OBJECT_TOO_BIG); + prop.push_back(""); + prop.push_back(pi.usage); + prop.push_back(Variant()); + } else { + prop.push_back(pi.hint); + if (res.is_null()) + prop.push_back(pi.hint_string); + else + prop.push_back(String("RES:") + res->get_path()); + prop.push_back(pi.usage); + prop.push_back(var); } + send_props.push_back(prop); } + + packet_peer_stream->put_var("message:inspect_object"); + packet_peer_stream->put_var(3); + packet_peer_stream->put_var(p_id); + packet_peer_stream->put_var(obj->get_class()); + packet_peer_stream->put_var(send_props); } void ScriptDebuggerRemote::_set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value) { @@ -589,7 +643,11 @@ void ScriptDebuggerRemote::_set_object_property(ObjectID p_id, const String &p_p if (!obj) return; - obj->set(p_property, p_value); + String prop_name = p_property; + if (p_property.begins_with("Members/")) + prop_name = p_property.substr(8, p_property.length()); + + obj->set(prop_name, p_value); } void ScriptDebuggerRemote::_poll_events() { @@ -691,7 +749,7 @@ void ScriptDebuggerRemote::_send_profiling_data(bool p_for_frame) { } SortArray<ScriptLanguage::ProfilingInfo *, ProfileInfoSort> sa; - sa.sort(profile_info_ptrs.ptr(), ofs); + sa.sort(profile_info_ptrs.ptrw(), ofs); int to_send = MIN(ofs, max_frame_functions); @@ -831,7 +889,7 @@ void ScriptDebuggerRemote::send_message(const String &p_message, const Array &p_ mutex->unlock(); } -void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string) { +void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string, bool p_error) { ScriptDebuggerRemote *sdr = (ScriptDebuggerRemote *)p_this; @@ -939,7 +997,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() tcp_client(StreamPeerTCP::create_ref()), packet_peer_stream(Ref<PacketPeerStream>(memnew(PacketPeerStream))), last_perf_time(0), - performance(ProjectSettings::get_singleton()->get_singleton_object("Performance")), + performance(Engine::get_singleton()->get_singleton_object("Performance")), requested_quit(false), mutex(Mutex::create()), max_cps(GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second")), diff --git a/core/script_debugger_remote.h b/core/script_debugger_remote.h index 22137d1350..90d2daf1f8 100644 --- a/core/script_debugger_remote.h +++ b/core/script_debugger_remote.h @@ -94,7 +94,7 @@ class ScriptDebuggerRemote : public ScriptDebugger { uint64_t msec_count; bool locking; //hack to avoid a deadloop - static void _print_handler(void *p_this, const String &p_string); + static void _print_handler(void *p_this, const String &p_string, bool p_error); PrintHandlerList phl; diff --git a/core/script_language.h b/core/script_language.h index 5da72d0492..3d01381f3b 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -120,6 +120,9 @@ public: virtual int get_member_line(const StringName &p_member) const { return -1; } + virtual void get_constants(Map<StringName, Variant> *p_constants) {} + virtual void get_members(Set<StringName> *p_constants) {} + Script() {} }; @@ -130,6 +133,7 @@ public: virtual void get_property_list(List<PropertyInfo> *p_properties) const = 0; virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = NULL) const = 0; + virtual Object *get_owner() { return NULL; } virtual void get_property_state(List<Pair<StringName, Variant> > &state); virtual void get_method_list(List<MethodInfo> *p_list) const = 0; @@ -244,7 +248,8 @@ public: virtual String debug_get_stack_level_source(int p_level) const = 0; virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) = 0; virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) = 0; - virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) = 0; + virtual ScriptInstance *debug_get_stack_level_instance(int p_level) { return NULL; } + virtual void debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1) = 0; virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1) = 0; struct StackInfo { diff --git a/core/string_buffer.cpp b/core/string_buffer.cpp index 195068f887..8489df2599 100644 --- a/core/string_buffer.cpp +++ b/core/string_buffer.cpp @@ -71,7 +71,7 @@ StringBuffer &StringBuffer::reserve(int p_size) { bool need_copy = string_length > 0 && buffer.empty(); buffer.resize(next_power_of_2(p_size)); if (need_copy) { - memcpy(buffer.ptr(), short_buffer, string_length * sizeof(CharType)); + memcpy(buffer.ptrw(), short_buffer, string_length * sizeof(CharType)); } return *this; diff --git a/core/string_buffer.h b/core/string_buffer.h index 3f36249148..b6ccd4af20 100644 --- a/core/string_buffer.h +++ b/core/string_buffer.h @@ -40,7 +40,7 @@ class StringBuffer { int string_length = 0; _FORCE_INLINE_ CharType *current_buffer_ptr() { - return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptr(); + return static_cast<Vector<CharType> &>(buffer).empty() ? short_buffer : buffer.ptrw(); } public: diff --git a/core/translation.cpp b/core/translation.cpp index 058db956e5..dcca58692a 100644 --- a/core/translation.cpp +++ b/core/translation.cpp @@ -333,6 +333,7 @@ static const char *locale_list[] = { "sq_KV", // Albanian (Kosovo) "sq_MK", // Albanian (Macedonia) "sr", // Serbian + "sr_Cyrl", // Serbian (Cyrillic) "sr_ME", // Serbian (Montenegro) "sr_RS", // Serbian (Serbia) "ss_ZA", // Swati (South Africa) @@ -693,6 +694,7 @@ static const char *locale_names[] = { "Albanian (Kosovo)", "Albanian (Macedonia)", "Serbian", + "Serbian (Cyrillic)", "Serbian (Montenegro)", "Serbian (Serbia)", "Swati (South Africa)", @@ -966,7 +968,7 @@ Vector<String> TranslationServer::get_all_locale_names() { const char **ptr = locale_names; while (*ptr) { - locales.push_back(*ptr); + locales.push_back(String::utf8(*ptr)); ptr++; } @@ -1168,6 +1170,6 @@ TranslationServer::TranslationServer() for (int i = 0; locale_list[i]; ++i) { - locale_name_map.insert(locale_list[i], locale_names[i]); + locale_name_map.insert(locale_list[i], String::utf8(locale_names[i])); } } diff --git a/core/type_info.h b/core/type_info.h index 9fb80af0eb..24d96c51e8 100644 --- a/core/type_info.h +++ b/core/type_info.h @@ -82,7 +82,7 @@ MAKE_TYPE_INFO(Vector3, Variant::VECTOR3) MAKE_TYPE_INFO(Transform2D, Variant::TRANSFORM2D) MAKE_TYPE_INFO(Plane, Variant::PLANE) MAKE_TYPE_INFO(Quat, Variant::QUAT) -MAKE_TYPE_INFO(Rect3, Variant::RECT3) +MAKE_TYPE_INFO(AABB, Variant::AABB) MAKE_TYPE_INFO(Basis, Variant::BASIS) MAKE_TYPE_INFO(Transform, Variant::TRANSFORM) MAKE_TYPE_INFO(Color, Variant::COLOR) diff --git a/core/ustring.cpp b/core/ustring.cpp index 415494ddc8..3a0708851e 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -115,7 +115,7 @@ void String::copy_from(const char *p_cstr) { resize(len + 1); // include 0 - CharType *dst = this->ptr(); + CharType *dst = this->ptrw(); for (int i = 0; i < len + 1; i++) { @@ -564,7 +564,7 @@ void String::erase(int p_pos, int p_chars) { String String::capitalize() const { - String aux = this->replace("_", " ").to_lower(); + String aux = this->camelcase_to_underscore(true).replace("_", " ").strip_edges(); String cap; for (int i = 0; i < aux.get_slice_count(" "); i++) { @@ -862,6 +862,17 @@ Vector<int> String::split_ints_mk(const Vector<String> &p_splitters, bool p_allo return ret; } +String String::join(Vector<String> parts) { + String ret; + for (int i = 0; i < parts.size(); ++i) { + if (i > 0) { + ret += *this; + } + ret += parts[i]; + } + return ret; +} + CharType String::char_uppercase(CharType p_char) { return _find_upper(p_char); @@ -1108,7 +1119,7 @@ String String::num_int64(int64_t p_num, int base, bool capitalize_hex) { chars++; String s; s.resize(chars + 1); - CharType *c = s.ptr(); + CharType *c = s.ptrw(); c[chars] = 0; n = num; do { @@ -3369,8 +3380,6 @@ bool String::is_valid_float() const { from++; } - //this was pulled out of my ass, i wonder if it's correct... - bool exponent_found = false; bool period_found = false; bool sign_found = false; diff --git a/core/ustring.h b/core/ustring.h index 353c8e6c1d..9c24133b55 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -169,6 +169,8 @@ public: Vector<int> split_ints(const String &p_splitter, bool p_allow_empty = true) const; Vector<int> split_ints_mk(const Vector<String> &p_splitters, bool p_allow_empty = true) const; + String join(Vector<String> parts); + static CharType char_uppercase(CharType p_char); static CharType char_lowercase(CharType p_char); String to_upper() const; diff --git a/core/variant.cpp b/core/variant.cpp index f70e4a5218..0f97b98a6f 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -94,9 +94,9 @@ String Variant::get_type_name(Variant::Type p_type) { } break;*/ - case RECT3: { + case AABB: { - return "Rect3"; + return "AABB"; } break; case QUAT: { @@ -267,6 +267,7 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { static const Type valid[] = { QUAT, + VECTOR3, NIL }; @@ -512,6 +513,7 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type static const Type valid[] = { QUAT, + VECTOR3, NIL }; @@ -754,9 +756,9 @@ bool Variant::is_zero() const { } break;*/ - case RECT3: { + case AABB: { - return *_data._rect3 == Rect3(); + return *_data._aabb == ::AABB(); } break; case QUAT: { @@ -954,9 +956,9 @@ void Variant::reference(const Variant &p_variant) { memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem))); } break; - case RECT3: { + case AABB: { - _data._rect3 = memnew(Rect3(*p_variant._data._rect3)); + _data._aabb = memnew(::AABB(*p_variant._data._aabb)); } break; case QUAT: { @@ -1079,9 +1081,9 @@ void Variant::clear() { memdelete(_data._transform2d); } break; - case RECT3: { + case AABB: { - memdelete(_data._rect3); + memdelete(_data._aabb); } break; case BASIS: { @@ -1426,7 +1428,7 @@ Variant::operator String() const { case PLANE: return operator Plane(); //case QUAT: - case RECT3: return operator Rect3(); + case AABB: return operator ::AABB(); case QUAT: return "(" + operator Quat() + ")"; case BASIS: { @@ -1617,12 +1619,12 @@ Variant::operator Plane() const { else return Plane(); } -Variant::operator Rect3() const { +Variant::operator ::AABB() const { - if (type == RECT3) - return *_data._rect3; + if (type == AABB) + return *_data._aabb; else - return Rect3(); + return ::AABB(); } Variant::operator Basis() const { @@ -1631,7 +1633,9 @@ Variant::operator Basis() const { return *_data._basis; else if (type == QUAT) return *reinterpret_cast<const Quat *>(_data._mem); - else if (type == TRANSFORM) + else if (type == VECTOR3) { + return Basis(*reinterpret_cast<const Vector3 *>(_data._mem)); + } else if (type == TRANSFORM) // unexposed in Variant::can_convert? return _data._transform->basis; else return Basis(); @@ -2188,10 +2192,10 @@ Variant::Variant(const Plane &p_plane) { type = PLANE; memnew_placement(_data._mem, Plane(p_plane)); } -Variant::Variant(const Rect3 &p_aabb) { +Variant::Variant(const ::AABB &p_aabb) { - type = RECT3; - _data._rect3 = memnew(Rect3(p_aabb)); + type = AABB; + _data._aabb = memnew(::AABB(p_aabb)); } Variant::Variant(const Basis &p_matrix) { @@ -2524,9 +2528,9 @@ void Variant::operator=(const Variant &p_variant) { *reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem); } break; - case RECT3: { + case AABB: { - *_data._rect3 = *(p_variant._data._rect3); + *_data._aabb = *(p_variant._data._aabb); } break; case QUAT: { @@ -2686,13 +2690,13 @@ uint32_t Variant::hash() const { } break;*/ - case RECT3: { + case AABB: { uint32_t hash = 5831; for (int i = 0; i < 3; i++) { - hash = hash_djb2_one_float(_data._rect3->position[i], hash); - hash = hash_djb2_one_float(_data._rect3->size[i], hash); + hash = hash_djb2_one_float(_data._aabb->position[i], hash); + hash = hash_djb2_one_float(_data._aabb->size[i], hash); } return hash; @@ -2952,9 +2956,9 @@ bool Variant::hash_compare(const Variant &p_variant) const { (hash_compare_scalar(l->d, r->d)); } break; - case RECT3: { - const Rect3 *l = _data._rect3; - const Rect3 *r = p_variant._data._rect3; + case AABB: { + const ::AABB *l = _data._aabb; + const ::AABB *r = p_variant._data._aabb; return (hash_compare_vector3(l->position, r->position) && (hash_compare_vector3(l->size, r->size))); diff --git a/core/variant.h b/core/variant.h index 45066af401..8ba4d576cf 100644 --- a/core/variant.h +++ b/core/variant.h @@ -34,6 +34,7 @@ @author Juan Linietsky <reduzio@gmail.com> */ +#include "aabb.h" #include "array.h" #include "color.h" #include "dictionary.h" @@ -45,7 +46,6 @@ #include "node_path.h" #include "plane.h" #include "quat.h" -#include "rect3.h" #include "ref_ptr.h" #include "rid.h" #include "transform.h" @@ -89,7 +89,7 @@ public: TRANSFORM2D, PLANE, QUAT, // 10 - RECT3, + AABB, BASIS, TRANSFORM, @@ -136,7 +136,7 @@ private: int64_t _int; double _real; Transform2D *_transform2d; - Rect3 *_rect3; + ::AABB *_aabb; Basis *_basis; Transform *_transform; RefPtr *_resource; @@ -184,7 +184,7 @@ public: operator Rect2() const; operator Vector3() const; operator Plane() const; - operator Rect3() const; + operator ::AABB() const; operator Quat() const; operator Basis() const; operator Transform() const; @@ -253,7 +253,7 @@ public: Variant(const Rect2 &p_rect2); Variant(const Vector3 &p_vector3); Variant(const Plane &p_plane); - Variant(const Rect3 &p_aabb); + Variant(const ::AABB &p_aabb); Variant(const Quat &p_quat); Variant(const Basis &p_transform); Variant(const Transform2D &p_transform); diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 1a29b92810..10f5ca0ce1 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -437,6 +437,8 @@ struct _VariantCall { VCALL_LOCALMEM0R(Color, contrasted); VCALL_LOCALMEM2R(Color, linear_interpolate); VCALL_LOCALMEM1R(Color, blend); + VCALL_LOCALMEM1R(Color, lightened); + VCALL_LOCALMEM1R(Color, darkened); VCALL_LOCALMEM1R(Color, to_html); VCALL_LOCALMEM0R(RID, get_id); @@ -446,7 +448,8 @@ struct _VariantCall { VCALL_LOCALMEM1R(NodePath, get_name); VCALL_LOCALMEM0R(NodePath, get_subname_count); VCALL_LOCALMEM1R(NodePath, get_subname); - VCALL_LOCALMEM0R(NodePath, get_property); + VCALL_LOCALMEM0R(NodePath, get_concatenated_subnames); + VCALL_LOCALMEM0R(NodePath, get_as_property_path); VCALL_LOCALMEM0R(NodePath, is_empty); VCALL_LOCALMEM0R(Dictionary, size); @@ -483,6 +486,8 @@ struct _VariantCall { VCALL_LOCALMEM1(Array, erase); VCALL_LOCALMEM0(Array, sort); VCALL_LOCALMEM2(Array, sort_custom); + VCALL_LOCALMEM2R(Array, bsearch); + VCALL_LOCALMEM4R(Array, bsearch_custom); VCALL_LOCALMEM0R(Array, duplicate); VCALL_LOCALMEM0(Array, invert); @@ -494,7 +499,7 @@ struct _VariantCall { PoolByteArray::Read r = ba->read(); CharString cs; cs.resize(ba->size() + 1); - copymem(cs.ptr(), r.ptr(), ba->size()); + copymem(cs.ptrw(), r.ptr(), ba->size()); cs[ba->size()] = 0; s = cs.get_data(); @@ -655,26 +660,26 @@ struct _VariantCall { #define VCALL_PTR5R(m_type, m_method) \ static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = reinterpret_cast<m_type *>(p_self._data._ptr)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3], *p_args[4]); } - VCALL_PTR0R(Rect3, get_area); - VCALL_PTR0R(Rect3, has_no_area); - VCALL_PTR0R(Rect3, has_no_surface); - VCALL_PTR1R(Rect3, intersects); - VCALL_PTR1R(Rect3, encloses); - VCALL_PTR1R(Rect3, merge); - VCALL_PTR1R(Rect3, intersection); - VCALL_PTR1R(Rect3, intersects_plane); - VCALL_PTR2R(Rect3, intersects_segment); - VCALL_PTR1R(Rect3, has_point); - VCALL_PTR1R(Rect3, get_support); - VCALL_PTR0R(Rect3, get_longest_axis); - VCALL_PTR0R(Rect3, get_longest_axis_index); - VCALL_PTR0R(Rect3, get_longest_axis_size); - VCALL_PTR0R(Rect3, get_shortest_axis); - VCALL_PTR0R(Rect3, get_shortest_axis_index); - VCALL_PTR0R(Rect3, get_shortest_axis_size); - VCALL_PTR1R(Rect3, expand); - VCALL_PTR1R(Rect3, grow); - VCALL_PTR1R(Rect3, get_endpoint); + VCALL_PTR0R(AABB, get_area); + VCALL_PTR0R(AABB, has_no_area); + VCALL_PTR0R(AABB, has_no_surface); + VCALL_PTR1R(AABB, intersects); + VCALL_PTR1R(AABB, encloses); + VCALL_PTR1R(AABB, merge); + VCALL_PTR1R(AABB, intersection); + VCALL_PTR1R(AABB, intersects_plane); + VCALL_PTR2R(AABB, intersects_segment); + VCALL_PTR1R(AABB, has_point); + VCALL_PTR1R(AABB, get_support); + VCALL_PTR0R(AABB, get_longest_axis); + VCALL_PTR0R(AABB, get_longest_axis_index); + VCALL_PTR0R(AABB, get_longest_axis_size); + VCALL_PTR0R(AABB, get_shortest_axis); + VCALL_PTR0R(AABB, get_shortest_axis_index); + VCALL_PTR0R(AABB, get_shortest_axis_size); + VCALL_PTR1R(AABB, expand); + VCALL_PTR1R(AABB, grow); + VCALL_PTR1R(AABB, get_endpoint); VCALL_PTR0R(Transform2D, inverse); VCALL_PTR0R(Transform2D, affine_inverse); @@ -755,7 +760,7 @@ struct _VariantCall { case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Vector3()); return; case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Plane()); return; - case Variant::RECT3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Rect3()); return; + case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::AABB()); return; default: r_ret = Variant(); } } @@ -766,7 +771,7 @@ struct _VariantCall { case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector3()); return; case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Plane()); return; - case Variant::RECT3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Rect3()); return; + case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::AABB()); return; default: r_ret = Variant(); } } @@ -878,9 +883,9 @@ struct _VariantCall { r_ret = Color::hex(*p_args[0]); } - static void Rect3_init1(Variant &r_ret, const Variant **p_args) { + static void AABB_init1(Variant &r_ret, const Variant **p_args) { - r_ret = Rect3(*p_args[0], *p_args[1]); + r_ret = ::AABB(*p_args[0], *p_args[1]); } static void Basis_init1(Variant &r_ret, const Variant **p_args) { @@ -897,11 +902,6 @@ struct _VariantCall { r_ret = Basis(p_args[0]->operator Vector3(), p_args[1]->operator real_t()); } - static void Basis_init3(Variant &r_ret, const Variant **p_args) { - - r_ret = Basis(p_args[0]->operator Vector3()); - } - static void Transform_init1(Variant &r_ret, const Variant **p_args) { Transform t; @@ -1058,8 +1058,8 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i case TRANSFORM2D: return Transform2D(); case PLANE: return Plane(); case QUAT: return Quat(); - case RECT3: - return Rect3(); // 10 + case AABB: + return ::AABB(); // 10 case BASIS: return Basis(); case TRANSFORM: return Transform(); @@ -1138,8 +1138,8 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i case VECTOR3: return (Vector3(*p_args[0])); case PLANE: return (Plane(*p_args[0])); case QUAT: return (Quat(*p_args[0])); - case RECT3: - return (Rect3(*p_args[0])); // 10 + case AABB: + return (::AABB(*p_args[0])); // 10 case BASIS: return (Basis(p_args[0]->operator Basis())); case TRANSFORM: return (Transform(p_args[0]->operator Transform())); @@ -1458,7 +1458,7 @@ void register_variant_methods() { ADDFUNC0R(STRING, STRING, String, get_basename, varray()); ADDFUNC1R(STRING, STRING, String, plus_file, STRING, "file", varray()); ADDFUNC1R(STRING, INT, String, ord_at, INT, "at", varray()); - ADDFUNC0(STRING, STRING, String, dedent, varray()); + ADDFUNC0R(STRING, STRING, String, dedent, varray()); ADDFUNC2(STRING, NIL, String, erase, INT, "position", INT, "chars", varray()); ADDFUNC0R(STRING, INT, String, hash, varray()); ADDFUNC0R(STRING, STRING, String, md5_text, varray()); @@ -1581,6 +1581,8 @@ void register_variant_methods() { ADDFUNC0R(COLOR, COLOR, Color, contrasted, varray()); ADDFUNC2R(COLOR, COLOR, Color, linear_interpolate, COLOR, "b", REAL, "t", varray()); ADDFUNC1R(COLOR, COLOR, Color, blend, COLOR, "over", varray()); + ADDFUNC1R(COLOR, COLOR, Color, lightened, REAL, "amount", varray()); + ADDFUNC1R(COLOR, COLOR, Color, darkened, REAL, "amount", varray()); ADDFUNC1R(COLOR, STRING, Color, to_html, BOOL, "with_alpha", varray(true)); ADDFUNC0R(_RID, INT, RID, get_id, varray()); @@ -1590,7 +1592,8 @@ void register_variant_methods() { ADDFUNC1R(NODE_PATH, STRING, NodePath, get_name, INT, "idx", varray()); ADDFUNC0R(NODE_PATH, INT, NodePath, get_subname_count, varray()); ADDFUNC1R(NODE_PATH, STRING, NodePath, get_subname, INT, "idx", varray()); - ADDFUNC0R(NODE_PATH, STRING, NodePath, get_property, varray()); + ADDFUNC0R(NODE_PATH, STRING, NodePath, get_concatenated_subnames, varray()); + ADDFUNC0R(NODE_PATH, NODE_PATH, NodePath, get_as_property_path, varray()); ADDFUNC0R(NODE_PATH, BOOL, NodePath, is_empty, varray()); ADDFUNC0R(DICTIONARY, INT, Dictionary, size, varray()); @@ -1625,6 +1628,8 @@ void register_variant_methods() { ADDFUNC0RNC(ARRAY, NIL, Array, pop_front, varray()); ADDFUNC0NC(ARRAY, NIL, Array, sort, varray()); ADDFUNC2NC(ARRAY, NIL, Array, sort_custom, OBJECT, "obj", STRING, "func", varray()); + ADDFUNC2R(ARRAY, INT, Array, bsearch, NIL, "value", BOOL, "before", varray(true)); + ADDFUNC4R(ARRAY, INT, Array, bsearch_custom, NIL, "value", OBJECT, "obj", STRING, "func", BOOL, "before", varray(true)); ADDFUNC0NC(ARRAY, NIL, Array, invert, varray()); ADDFUNC0RNC(ARRAY, ARRAY, Array, duplicate, varray()); @@ -1707,26 +1712,26 @@ void register_variant_methods() { //pointerbased - ADDFUNC0R(RECT3, REAL, Rect3, get_area, varray()); - ADDFUNC0R(RECT3, BOOL, Rect3, has_no_area, varray()); - ADDFUNC0R(RECT3, BOOL, Rect3, has_no_surface, varray()); - ADDFUNC1R(RECT3, BOOL, Rect3, intersects, RECT3, "with", varray()); - ADDFUNC1R(RECT3, BOOL, Rect3, encloses, RECT3, "with", varray()); - ADDFUNC1R(RECT3, RECT3, Rect3, merge, RECT3, "with", varray()); - ADDFUNC1R(RECT3, RECT3, Rect3, intersection, RECT3, "with", varray()); - ADDFUNC1R(RECT3, BOOL, Rect3, intersects_plane, PLANE, "plane", varray()); - ADDFUNC2R(RECT3, BOOL, Rect3, intersects_segment, VECTOR3, "from", VECTOR3, "to", varray()); - ADDFUNC1R(RECT3, BOOL, Rect3, has_point, VECTOR3, "point", varray()); - ADDFUNC1R(RECT3, VECTOR3, Rect3, get_support, VECTOR3, "dir", varray()); - ADDFUNC0R(RECT3, VECTOR3, Rect3, get_longest_axis, varray()); - ADDFUNC0R(RECT3, INT, Rect3, get_longest_axis_index, varray()); - ADDFUNC0R(RECT3, REAL, Rect3, get_longest_axis_size, varray()); - ADDFUNC0R(RECT3, VECTOR3, Rect3, get_shortest_axis, varray()); - ADDFUNC0R(RECT3, INT, Rect3, get_shortest_axis_index, varray()); - ADDFUNC0R(RECT3, REAL, Rect3, get_shortest_axis_size, varray()); - ADDFUNC1R(RECT3, RECT3, Rect3, expand, VECTOR3, "to_point", varray()); - ADDFUNC1R(RECT3, RECT3, Rect3, grow, REAL, "by", varray()); - ADDFUNC1R(RECT3, VECTOR3, Rect3, get_endpoint, INT, "idx", varray()); + ADDFUNC0R(AABB, REAL, AABB, get_area, varray()); + ADDFUNC0R(AABB, BOOL, AABB, has_no_area, varray()); + ADDFUNC0R(AABB, BOOL, AABB, has_no_surface, varray()); + ADDFUNC1R(AABB, BOOL, AABB, intersects, AABB, "with", varray()); + ADDFUNC1R(AABB, BOOL, AABB, encloses, AABB, "with", varray()); + ADDFUNC1R(AABB, AABB, AABB, merge, AABB, "with", varray()); + ADDFUNC1R(AABB, AABB, AABB, intersection, AABB, "with", varray()); + ADDFUNC1R(AABB, BOOL, AABB, intersects_plane, PLANE, "plane", varray()); + ADDFUNC2R(AABB, BOOL, AABB, intersects_segment, VECTOR3, "from", VECTOR3, "to", varray()); + ADDFUNC1R(AABB, BOOL, AABB, has_point, VECTOR3, "point", varray()); + ADDFUNC1R(AABB, VECTOR3, AABB, get_support, VECTOR3, "dir", varray()); + ADDFUNC0R(AABB, VECTOR3, AABB, get_longest_axis, varray()); + ADDFUNC0R(AABB, INT, AABB, get_longest_axis_index, varray()); + ADDFUNC0R(AABB, REAL, AABB, get_longest_axis_size, varray()); + ADDFUNC0R(AABB, VECTOR3, AABB, get_shortest_axis, varray()); + ADDFUNC0R(AABB, INT, AABB, get_shortest_axis_index, varray()); + ADDFUNC0R(AABB, REAL, AABB, get_shortest_axis_size, varray()); + ADDFUNC1R(AABB, AABB, AABB, expand, VECTOR3, "to_point", varray()); + ADDFUNC1R(AABB, AABB, AABB, grow, REAL, "by", varray()); + ADDFUNC1R(AABB, VECTOR3, AABB, get_endpoint, INT, "idx", varray()); ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, inverse, varray()); ADDFUNC0R(TRANSFORM2D, TRANSFORM2D, Transform2D, affine_inverse, varray()); @@ -1791,11 +1796,10 @@ void register_variant_methods() { _VariantCall::add_constructor(_VariantCall::Color_init1, Variant::COLOR, "r", Variant::REAL, "g", Variant::REAL, "b", Variant::REAL, "a", Variant::REAL); _VariantCall::add_constructor(_VariantCall::Color_init2, Variant::COLOR, "r", Variant::REAL, "g", Variant::REAL, "b", Variant::REAL); - _VariantCall::add_constructor(_VariantCall::Rect3_init1, Variant::RECT3, "position", Variant::VECTOR3, "size", Variant::VECTOR3); + _VariantCall::add_constructor(_VariantCall::AABB_init1, Variant::AABB, "position", Variant::VECTOR3, "size", Variant::VECTOR3); _VariantCall::add_constructor(_VariantCall::Basis_init1, Variant::BASIS, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3); _VariantCall::add_constructor(_VariantCall::Basis_init2, Variant::BASIS, "axis", Variant::VECTOR3, "phi", Variant::REAL); - _VariantCall::add_constructor(_VariantCall::Basis_init3, Variant::BASIS, "euler", Variant::VECTOR3); _VariantCall::add_constructor(_VariantCall::Transform_init1, Variant::TRANSFORM, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3, "origin", Variant::VECTOR3); _VariantCall::add_constructor(_VariantCall::Transform_init2, Variant::TRANSFORM, "basis", Variant::BASIS, "origin", Variant::VECTOR3); diff --git a/core/variant_op.cpp b/core/variant_op.cpp index 6362090902..c793d70ed8 100644 --- a/core/variant_op.cpp +++ b/core/variant_op.cpp @@ -48,7 +48,7 @@ CASE_TYPE(PREFIX, OP, TRANSFORM2D) \ CASE_TYPE(PREFIX, OP, PLANE) \ CASE_TYPE(PREFIX, OP, QUAT) \ - CASE_TYPE(PREFIX, OP, RECT3) \ + CASE_TYPE(PREFIX, OP, AABB) \ CASE_TYPE(PREFIX, OP, BASIS) \ CASE_TYPE(PREFIX, OP, TRANSFORM) \ CASE_TYPE(PREFIX, OP, COLOR) \ @@ -81,7 +81,7 @@ TYPE(PREFIX, OP, TRANSFORM2D), \ TYPE(PREFIX, OP, PLANE), \ TYPE(PREFIX, OP, QUAT), \ - TYPE(PREFIX, OP, RECT3), \ + TYPE(PREFIX, OP, AABB), \ TYPE(PREFIX, OP, BASIS), \ TYPE(PREFIX, OP, TRANSFORM), \ TYPE(PREFIX, OP, COLOR), \ @@ -465,7 +465,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, VECTOR3, ==, Vector3); DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, PLANE, ==, Plane); DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, QUAT, ==, Quat); - DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, RECT3, ==, _rect3); + DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, AABB, ==, _aabb); DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, BASIS, ==, _basis); DEFAULT_OP_PTRREF_NULL(math, OP_EQUAL, TRANSFORM, ==, _transform); DEFAULT_OP_LOCALMEM_NULL(math, OP_EQUAL, COLOR, ==, Color); @@ -555,7 +555,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, VECTOR3, !=, Vector3); DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, PLANE, !=, Plane); DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, QUAT, !=, Quat); - DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, RECT3, !=, _rect3); + DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, AABB, !=, _aabb); DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, BASIS, !=, _basis); DEFAULT_OP_PTRREF_NULL(math, OP_NOT_EQUAL, TRANSFORM, !=, _transform); DEFAULT_OP_LOCALMEM_NULL(math, OP_NOT_EQUAL, COLOR, !=, Color); @@ -629,7 +629,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_LESS, TRANSFORM2D) CASE_TYPE(math, OP_LESS, PLANE) CASE_TYPE(math, OP_LESS, QUAT) - CASE_TYPE(math, OP_LESS, RECT3) + CASE_TYPE(math, OP_LESS, AABB) CASE_TYPE(math, OP_LESS, BASIS) CASE_TYPE(math, OP_LESS, TRANSFORM) CASE_TYPE(math, OP_LESS, COLOR) @@ -658,7 +658,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM2D) CASE_TYPE(math, OP_LESS_EQUAL, PLANE) CASE_TYPE(math, OP_LESS_EQUAL, QUAT) - CASE_TYPE(math, OP_LESS_EQUAL, RECT3) + CASE_TYPE(math, OP_LESS_EQUAL, AABB) CASE_TYPE(math, OP_LESS_EQUAL, BASIS) CASE_TYPE(math, OP_LESS_EQUAL, TRANSFORM) CASE_TYPE(math, OP_LESS_EQUAL, COLOR) @@ -733,7 +733,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_GREATER, TRANSFORM2D) CASE_TYPE(math, OP_GREATER, PLANE) CASE_TYPE(math, OP_GREATER, QUAT) - CASE_TYPE(math, OP_GREATER, RECT3) + CASE_TYPE(math, OP_GREATER, AABB) CASE_TYPE(math, OP_GREATER, BASIS) CASE_TYPE(math, OP_GREATER, TRANSFORM) CASE_TYPE(math, OP_GREATER, COLOR) @@ -762,7 +762,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM2D) CASE_TYPE(math, OP_GREATER_EQUAL, PLANE) CASE_TYPE(math, OP_GREATER_EQUAL, QUAT) - CASE_TYPE(math, OP_GREATER_EQUAL, RECT3) + CASE_TYPE(math, OP_GREATER_EQUAL, AABB) CASE_TYPE(math, OP_GREATER_EQUAL, BASIS) CASE_TYPE(math, OP_GREATER_EQUAL, TRANSFORM) CASE_TYPE(math, OP_GREATER_EQUAL, COLOR) @@ -818,7 +818,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_ADD, RECT2) CASE_TYPE(math, OP_ADD, TRANSFORM2D) CASE_TYPE(math, OP_ADD, PLANE) - CASE_TYPE(math, OP_ADD, RECT3) + CASE_TYPE(math, OP_ADD, AABB) CASE_TYPE(math, OP_ADD, BASIS) CASE_TYPE(math, OP_ADD, TRANSFORM) CASE_TYPE(math, OP_ADD, NODE_PATH) @@ -842,7 +842,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_SUBTRACT, RECT2) CASE_TYPE(math, OP_SUBTRACT, TRANSFORM2D) CASE_TYPE(math, OP_SUBTRACT, PLANE) - CASE_TYPE(math, OP_SUBTRACT, RECT3) + CASE_TYPE(math, OP_SUBTRACT, AABB) CASE_TYPE(math, OP_SUBTRACT, BASIS) CASE_TYPE(math, OP_SUBTRACT, TRANSFORM) CASE_TYPE(math, OP_SUBTRACT, NODE_PATH) @@ -923,7 +923,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_MULTIPLY, STRING) CASE_TYPE(math, OP_MULTIPLY, RECT2) CASE_TYPE(math, OP_MULTIPLY, PLANE) - CASE_TYPE(math, OP_MULTIPLY, RECT3) + CASE_TYPE(math, OP_MULTIPLY, AABB) CASE_TYPE(math, OP_MULTIPLY, NODE_PATH) CASE_TYPE(math, OP_MULTIPLY, _RID) CASE_TYPE(math, OP_MULTIPLY, OBJECT) @@ -964,7 +964,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_DIVIDE, RECT2) CASE_TYPE(math, OP_DIVIDE, TRANSFORM2D) CASE_TYPE(math, OP_DIVIDE, PLANE) - CASE_TYPE(math, OP_DIVIDE, RECT3) + CASE_TYPE(math, OP_DIVIDE, AABB) CASE_TYPE(math, OP_DIVIDE, BASIS) CASE_TYPE(math, OP_DIVIDE, TRANSFORM) CASE_TYPE(math, OP_DIVIDE, NODE_PATH) @@ -995,7 +995,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_POSITIVE, STRING) CASE_TYPE(math, OP_POSITIVE, RECT2) CASE_TYPE(math, OP_POSITIVE, TRANSFORM2D) - CASE_TYPE(math, OP_POSITIVE, RECT3) + CASE_TYPE(math, OP_POSITIVE, AABB) CASE_TYPE(math, OP_POSITIVE, BASIS) CASE_TYPE(math, OP_POSITIVE, TRANSFORM) CASE_TYPE(math, OP_POSITIVE, COLOR) @@ -1029,7 +1029,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_NEGATE, STRING) CASE_TYPE(math, OP_NEGATE, RECT2) CASE_TYPE(math, OP_NEGATE, TRANSFORM2D) - CASE_TYPE(math, OP_NEGATE, RECT3) + CASE_TYPE(math, OP_NEGATE, AABB) CASE_TYPE(math, OP_NEGATE, BASIS) CASE_TYPE(math, OP_NEGATE, TRANSFORM) CASE_TYPE(math, OP_NEGATE, NODE_PATH) @@ -1088,7 +1088,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, CASE_TYPE(math, OP_MODULE, TRANSFORM2D) CASE_TYPE(math, OP_MODULE, PLANE) CASE_TYPE(math, OP_MODULE, QUAT) - CASE_TYPE(math, OP_MODULE, RECT3) + CASE_TYPE(math, OP_MODULE, AABB) CASE_TYPE(math, OP_MODULE, BASIS) CASE_TYPE(math, OP_MODULE, TRANSFORM) CASE_TYPE(math, OP_MODULE, COLOR) @@ -1384,10 +1384,10 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool } } break; // 10 - case RECT3: { + case AABB: { if (p_value.type == Variant::VECTOR3) { - Rect3 *v = _data._rect3; + ::AABB *v = _data._aabb; //scalar name if (p_index == CoreStringNames::singleton->position) { v->position = *reinterpret_cast<const Vector3 *>(p_value._data._mem); @@ -1609,9 +1609,9 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const { } } break; // 10 - case RECT3: { + case AABB: { - const Rect3 *v = _data._rect3; + const ::AABB *v = _data._aabb; //scalar name if (p_index == CoreStringNames::singleton->position) { return v->position; @@ -1982,7 +1982,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) } } break; // 10 - case RECT3: { + case AABB: { if (p_value.type != Variant::VECTOR3) return; @@ -1991,7 +1991,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) //scalar name const String *str = reinterpret_cast<const String *>(p_index._data._mem); - Rect3 *v = _data._rect3; + ::AABB *v = _data._aabb; if (*str == "position") { valid = true; v->position = p_value; @@ -2400,13 +2400,13 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const { } } break; // 10 - case RECT3: { + case AABB: { if (p_index.get_type() == Variant::STRING) { //scalar name const String *str = reinterpret_cast<const String *>(p_index._data._mem); - const Rect3 *v = _data._rect3; + const ::AABB *v = _data._aabb; if (*str == "position") { valid = true; return v->position; @@ -2835,7 +2835,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::REAL, "w")); } break; // 10 - case RECT3: { + case AABB: { p_list->push_back(PropertyInfo(Variant::VECTOR3, "position")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "size")); p_list->push_back(PropertyInfo(Variant::VECTOR3, "end")); @@ -3457,10 +3457,10 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst) r_dst = *reinterpret_cast<const Vector3 *>(a._data._mem) + *reinterpret_cast<const Vector3 *>(b._data._mem) * c; } return; - case RECT3: { - const Rect3 *ra = reinterpret_cast<const Rect3 *>(a._data._mem); - const Rect3 *rb = reinterpret_cast<const Rect3 *>(b._data._mem); - r_dst = Rect3(ra->position + rb->position * c, ra->size + rb->size * c); + case AABB: { + const ::AABB *ra = reinterpret_cast<const ::AABB *>(a._data._mem); + const ::AABB *rb = reinterpret_cast<const ::AABB *>(b._data._mem); + r_dst = ::AABB(ra->position + rb->position * c, ra->size + rb->size * c); } return; case QUAT: { @@ -3591,8 +3591,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant & r_dst = reinterpret_cast<const Quat *>(a._data._mem)->slerp(*reinterpret_cast<const Quat *>(b._data._mem), c); } return; - case RECT3: { - r_dst = Rect3(a._data._rect3->position.linear_interpolate(b._data._rect3->position, c), a._data._rect3->size.linear_interpolate(b._data._rect3->size, c)); + case AABB: { + r_dst = ::AABB(a._data._aabb->position.linear_interpolate(b._data._aabb->position, c), a._data._aabb->size.linear_interpolate(b._data._aabb->size, c)); } return; case BASIS: { diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index d60d10cd3a..1c02c627b5 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -595,7 +595,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, value = Quat(args[0], args[1], args[2], args[3]); return OK; - } else if (id == "Rect3" || id == "AABB") { + } else if (id == "AABB" || id == "Rect3") { Vector<float> args; Error err = _parse_construct<float>(p_stream, args, line, r_err_str); @@ -606,7 +606,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, r_err_str = "Expected 6 arguments for constructor"; } - value = Rect3(Vector3(args[0], args[1], args[2]), Vector3(args[3], args[4], args[5])); + value = AABB(Vector3(args[0], args[1], args[2]), Vector3(args[3], args[4], args[5])); return OK; } else if (id == "Basis" || id == "Matrix3") { //compatibility @@ -1634,10 +1634,10 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, "Plane( " + rtosfix(p.normal.x) + ", " + rtosfix(p.normal.y) + ", " + rtosfix(p.normal.z) + ", " + rtosfix(p.d) + " )"); } break; - case Variant::RECT3: { + case Variant::AABB: { - Rect3 aabb = p_variant; - p_store_string_func(p_store_string_ud, "Rect3( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )"); + AABB aabb = p_variant; + p_store_string_func(p_store_string_ud, "AABB( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )"); } break; case Variant::QUAT: { diff --git a/core/vector.h b/core/vector.h index 03eaf65099..a5c4b3b155 100644 --- a/core/vector.h +++ b/core/vector.h @@ -96,7 +96,7 @@ class Vector { void _copy_on_write(); public: - _FORCE_INLINE_ T *ptr() { + _FORCE_INLINE_ T *ptrw() { if (!_ptr) return NULL; _copy_on_write(); return (T *)_get_data(); @@ -361,7 +361,7 @@ template <class T> void Vector<T>::remove(int p_index) { ERR_FAIL_INDEX(p_index, size()); - T *p = ptr(); + T *p = ptrw(); int len = size(); for (int i = p_index; i < len - 1; i++) { diff --git a/core/version.h b/core/version.h index 7d2c47df6a..b217d82c5d 100644 --- a/core/version.h +++ b/core/version.h @@ -30,8 +30,8 @@ #include "version_generated.gen.h" #ifdef VERSION_PATCH -#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) "." _MKSTR(VERSION_STATUS) "." _MKSTR(VERSION_REVISION) VERSION_MODULE_CONFIG +#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_PATCH) "." VERSION_STATUS "." VERSION_BUILD VERSION_MODULE_CONFIG #else -#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." _MKSTR(VERSION_STATUS) "." _MKSTR(VERSION_REVISION) VERSION_MODULE_CONFIG +#define VERSION_MKSTRING "" _MKSTR(VERSION_MAJOR) "." _MKSTR(VERSION_MINOR) "." VERSION_STATUS "." VERSION_BUILD VERSION_MODULE_CONFIG #endif // VERSION_PATCH -#define VERSION_FULL_NAME "" _MKSTR(VERSION_NAME) " v" VERSION_MKSTRING +#define VERSION_FULL_NAME "" VERSION_NAME " v" VERSION_MKSTRING |