From b7cc2bb1e281b360fdbf4b845cfa61e3a5998ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Tue, 12 Feb 2019 13:30:56 +0100 Subject: Core: Ensure classes match their header filename Also drop some unused files. Renamed: - `core/dvector.h` -> `pool_vector.h` - `core/io/resource_import.h` -> `resource_importer.h` - `core/sort.h` -> `sort_array.h` - `core/string_db.h` -> `string_name.h` Dropped: - `core/allocators.h` - `core/os/shell.h` - `core/variant_construct_string.cpp` --- core/allocators.h | 195 ------- core/core_string_names.h | 2 +- core/dvector.cpp | 71 --- core/dvector.h | 643 ---------------------- core/global_constants.h | 2 +- core/hashfuncs.h | 2 +- core/image.h | 2 +- core/io/file_access_buffered.h | 2 +- core/io/file_access_buffered_fa.h | 2 +- core/io/resource_import.cpp | 373 ------------- core/io/resource_import.h | 113 ---- core/io/resource_importer.cpp | 373 +++++++++++++ core/io/resource_importer.h | 113 ++++ core/io/resource_loader.cpp | 2 +- core/list.h | 2 +- core/math/bsp_tree.h | 2 +- core/math/geometry.h | 2 +- core/math/triangle_mesh.cpp | 2 +- core/node_path.h | 2 +- core/os/shell.cpp | 46 -- core/os/shell.h | 52 -- core/pool_vector.cpp | 71 +++ core/pool_vector.h | 643 ++++++++++++++++++++++ core/register_core_types.cpp | 2 +- core/sort.h | 330 ----------- core/sort_array.h | 330 +++++++++++ core/string_db.cpp | 426 -------------- core/string_db.h | 172 ------ core/string_name.cpp | 426 ++++++++++++++ core/string_name.h | 172 ++++++ core/variant.h | 2 +- core/variant_construct_string.cpp | 438 --------------- core/vector.h | 2 +- drivers/gles2/rasterizer_storage_gles2.h | 2 +- drivers/windows/shell_windows.cpp | 67 --- drivers/windows/shell_windows.h | 52 -- editor/editor_file_system.cpp | 2 +- editor/import/editor_import_plugin.h | 2 +- editor/import/resource_importer_bitmask.h | 2 +- editor/import/resource_importer_csv_translation.h | 2 +- editor/import/resource_importer_image.h | 2 +- editor/import/resource_importer_layered_texture.h | 2 +- editor/import/resource_importer_scene.h | 2 +- editor/import/resource_importer_texture.h | 2 +- editor/import/resource_importer_wav.h | 2 +- editor/import_dock.h | 2 +- editor/plugins/spatial_editor_plugin.cpp | 2 +- modules/csg/csg.cpp | 2 +- modules/csg/csg.h | 2 +- modules/gdnative/gdnative/array.cpp | 2 +- modules/gdnative/gdnative/pool_arrays.cpp | 2 +- modules/gdnative/gdnative/string.cpp | 2 +- modules/gdnative/gdnative/string_name.cpp | 2 +- modules/gdscript/gdscript_function.h | 2 +- modules/gdscript/gdscript_tokenizer.h | 2 +- modules/mono/glue/base_object_glue.cpp | 2 +- modules/stb_vorbis/resource_importer_ogg_vorbis.h | 2 +- scene/scene_string_names.h | 2 +- servers/physics/shape_sw.cpp | 2 +- servers/physics_2d/shape_2d_sw.cpp | 2 +- servers/visual/shader_language.h | 2 +- servers/visual/visual_server_raster.cpp | 2 +- servers/visual/visual_server_raster.h | 1 - servers/visual/visual_server_scene.h | 2 - 64 files changed, 2170 insertions(+), 3023 deletions(-) delete mode 100644 core/allocators.h delete mode 100644 core/dvector.cpp delete mode 100644 core/dvector.h delete mode 100644 core/io/resource_import.cpp delete mode 100644 core/io/resource_import.h create mode 100644 core/io/resource_importer.cpp create mode 100644 core/io/resource_importer.h delete mode 100644 core/os/shell.cpp delete mode 100644 core/os/shell.h create mode 100644 core/pool_vector.cpp create mode 100644 core/pool_vector.h delete mode 100644 core/sort.h create mode 100644 core/sort_array.h delete mode 100644 core/string_db.cpp delete mode 100644 core/string_db.h create mode 100644 core/string_name.cpp create mode 100644 core/string_name.h delete mode 100644 core/variant_construct_string.cpp delete mode 100644 drivers/windows/shell_windows.cpp delete mode 100644 drivers/windows/shell_windows.h diff --git a/core/allocators.h b/core/allocators.h deleted file mode 100644 index 8d4af7a9fb..0000000000 --- a/core/allocators.h +++ /dev/null @@ -1,195 +0,0 @@ -/*************************************************************************/ -/* allocators.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef ALLOCATORS_H -#define ALLOCATORS_H - -#include "core/os/memory.h" - -template -class BalloonAllocator { - - enum { - - USED_FLAG = (1 << 30), - USED_MASK = USED_FLAG - 1 - }; - - struct Balloon { - - Balloon *next; - Balloon *prev; - uint32_t hand; - }; - - struct Hand { - - int used; - int allocated; - Balloon *first; - Balloon *last; - }; - - Hand hands[MAX_HANDS]; - -public: - void *alloc(size_t p_size) { - - size_t max = (1 << MAX_HANDS); - ERR_FAIL_COND_V(p_size > max, NULL); - - unsigned int hand = 0; - - while (p_size > (size_t)(1 << hand)) - ++hand; - - Hand &h = hands[hand]; - - if (h.used == h.allocated) { - - for (int i = 0; i < PREALLOC_COUNT; i++) { - - Balloon *b = (Balloon *)memalloc(sizeof(Balloon) + (1 << hand)); - b->hand = hand; - if (h.last) { - - b->prev = h.last; - h.last->next = b; - h.last = b; - } else { - - b->prev = NULL; - h.last = b; - h.first = b; - } - } - - h.last->next = NULL; - h.allocated += PREALLOC_COUNT; - } - - Balloon *pick = h.last; - - ERR_FAIL_COND_V((pick->hand & USED_FLAG), NULL); - - // remove last - h.last = h.last->prev; - h.last->next = NULL; - - pick->next = h.first; - h.first->prev = pick; - pick->prev = NULL; - h.first = pick; - h.used++; - pick->hand |= USED_FLAG; - - return (void *)(pick + 1); - } - - void free(void *p_ptr) { - - Balloon *b = (Balloon *)p_ptr; - b -= 1; - - ERR_FAIL_COND(!(b->hand & USED_FLAG)); - - b->hand = b->hand & USED_MASK; // not used - int hand = b->hand; - - Hand &h = hands[hand]; - - if (b == h.first) - h.first = b->next; - - if (b->prev) - b->prev->next = b->next; - if (b->next) - b->next->prev = b->prev; - - if (h.last != b) { - h.last->next = b; - b->prev = h.last; - b->next = NULL; - h.last = b; - } - - h.used--; - - if (h.used <= (h.allocated - (PREALLOC_COUNT * 2))) { // this is done to ensure no alloc/free is done constantly - - for (int i = 0; i < PREALLOC_COUNT; i++) { - ERR_CONTINUE(h.last->hand & USED_FLAG); - - Balloon *new_last = h.last->prev; - if (new_last) - new_last->next = NULL; - memfree(h.last); - h.last = new_last; - } - h.allocated -= PREALLOC_COUNT; - } - } - - BalloonAllocator() { - - for (int i = 0; i < MAX_HANDS; i++) { - - hands[i].allocated = 0; - hands[i].used = 0; - hands[i].first = NULL; - hands[i].last = NULL; - } - } - - void clear() { - - for (int i = 0; i < MAX_HANDS; i++) { - - while (hands[i].first) { - - Balloon *b = hands[i].first; - hands[i].first = b->next; - memfree(b); - } - - hands[i].allocated = 0; - hands[i].used = 0; - hands[i].first = NULL; - hands[i].last = NULL; - } - } - - ~BalloonAllocator() { - - clear(); - } -}; - -#endif // ALLOCATORS_H diff --git a/core/core_string_names.h b/core/core_string_names.h index 1a837cdc2e..6fea40e1b2 100644 --- a/core/core_string_names.h +++ b/core/core_string_names.h @@ -31,7 +31,7 @@ #ifndef CORE_STRING_NAMES_H #define CORE_STRING_NAMES_H -#include "core/string_db.h" +#include "core/string_name.h" class CoreStringNames { diff --git a/core/dvector.cpp b/core/dvector.cpp deleted file mode 100644 index 592c3c053d..0000000000 --- a/core/dvector.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************/ -/* dvector.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "dvector.h" - -Mutex *dvector_lock = NULL; - -PoolAllocator *MemoryPool::memory_pool = NULL; -uint8_t *MemoryPool::pool_memory = NULL; -size_t *MemoryPool::pool_size = NULL; - -MemoryPool::Alloc *MemoryPool::allocs = NULL; -MemoryPool::Alloc *MemoryPool::free_list = NULL; -uint32_t MemoryPool::alloc_count = 0; -uint32_t MemoryPool::allocs_used = 0; -Mutex *MemoryPool::alloc_mutex = NULL; - -size_t MemoryPool::total_memory = 0; -size_t MemoryPool::max_memory = 0; - -void MemoryPool::setup(uint32_t p_max_allocs) { - - allocs = memnew_arr(Alloc, p_max_allocs); - alloc_count = p_max_allocs; - allocs_used = 0; - - for (uint32_t i = 0; i < alloc_count - 1; i++) { - - allocs[i].free_list = &allocs[i + 1]; - } - - free_list = &allocs[0]; - - alloc_mutex = Mutex::create(); -} - -void MemoryPool::cleanup() { - - memdelete_arr(allocs); - memdelete(alloc_mutex); - - ERR_EXPLAINC("There are still MemoryPool allocs in use at exit!"); - ERR_FAIL_COND(allocs_used > 0); -} diff --git a/core/dvector.h b/core/dvector.h deleted file mode 100644 index fc962b4940..0000000000 --- a/core/dvector.h +++ /dev/null @@ -1,643 +0,0 @@ -/*************************************************************************/ -/* dvector.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef DVECTOR_H -#define DVECTOR_H - -#include "core/os/copymem.h" -#include "core/os/memory.h" -#include "core/os/rw_lock.h" -#include "core/pool_allocator.h" -#include "core/safe_refcount.h" -#include "core/ustring.h" - -struct MemoryPool { - - //avoid accessing these directly, must be public for template access - - static PoolAllocator *memory_pool; - static uint8_t *pool_memory; - static size_t *pool_size; - - struct Alloc { - - SafeRefCount refcount; - uint32_t lock; - void *mem; - PoolAllocator::ID pool_id; - size_t size; - - Alloc *free_list; - - Alloc() : - lock(0), - mem(NULL), - pool_id(POOL_ALLOCATOR_INVALID_ID), - size(0), - free_list(NULL) { - } - }; - - static Alloc *allocs; - static Alloc *free_list; - static uint32_t alloc_count; - static uint32_t allocs_used; - static Mutex *alloc_mutex; - static size_t total_memory; - static size_t max_memory; - - static void setup(uint32_t p_max_allocs = (1 << 16)); - static void cleanup(); -}; - -/** - @author Juan Linietsky -*/ - -template -class PoolVector { - - MemoryPool::Alloc *alloc; - - void _copy_on_write() { - - if (!alloc) - return; - - // ERR_FAIL_COND(alloc->lock>0); should not be illegal to lock this for copy on write, as it's a copy on write after all - - // Refcount should not be zero, otherwise it's a misuse of COW - if (alloc->refcount.get() == 1) - return; //nothing to do - - //must allocate something - - MemoryPool::alloc_mutex->lock(); - if (MemoryPool::allocs_used == MemoryPool::alloc_count) { - MemoryPool::alloc_mutex->unlock(); - ERR_EXPLAINC("All memory pool allocations are in use, can't COW."); - ERR_FAIL(); - } - - MemoryPool::Alloc *old_alloc = alloc; - - //take one from the free list - alloc = MemoryPool::free_list; - MemoryPool::free_list = alloc->free_list; - //increment the used counter - MemoryPool::allocs_used++; - - //copy the alloc data - alloc->size = old_alloc->size; - alloc->refcount.init(); - alloc->pool_id = POOL_ALLOCATOR_INVALID_ID; - alloc->lock = 0; - -#ifdef DEBUG_ENABLED - MemoryPool::total_memory += alloc->size; - if (MemoryPool::total_memory > MemoryPool::max_memory) { - MemoryPool::max_memory = MemoryPool::total_memory; - } -#endif - - MemoryPool::alloc_mutex->unlock(); - - if (MemoryPool::memory_pool) { - - } else { - alloc->mem = memalloc(alloc->size); - } - - { - Write w; - w._ref(alloc); - Read r; - r._ref(old_alloc); - - int cur_elements = alloc->size / sizeof(T); - T *dst = (T *)w.ptr(); - const T *src = (const T *)r.ptr(); - for (int i = 0; i < cur_elements; i++) { - memnew_placement(&dst[i], T(src[i])); - } - } - - if (old_alloc->refcount.unref()) { - //this should never happen but.. - -#ifdef DEBUG_ENABLED - MemoryPool::alloc_mutex->lock(); - MemoryPool::total_memory -= old_alloc->size; - MemoryPool::alloc_mutex->unlock(); -#endif - - { - Write w; - w._ref(old_alloc); - - int cur_elements = old_alloc->size / sizeof(T); - T *elems = (T *)w.ptr(); - for (int i = 0; i < cur_elements; i++) { - elems[i].~T(); - } - } - - if (MemoryPool::memory_pool) { - //resize memory pool - //if none, create - //if some resize - } else { - - memfree(old_alloc->mem); - old_alloc->mem = NULL; - old_alloc->size = 0; - - MemoryPool::alloc_mutex->lock(); - old_alloc->free_list = MemoryPool::free_list; - MemoryPool::free_list = old_alloc; - MemoryPool::allocs_used--; - MemoryPool::alloc_mutex->unlock(); - } - } - } - - void _reference(const PoolVector &p_dvector) { - - if (alloc == p_dvector.alloc) - return; - - _unreference(); - - if (!p_dvector.alloc) { - return; - } - - if (p_dvector.alloc->refcount.ref()) { - alloc = p_dvector.alloc; - } - } - - void _unreference() { - - if (!alloc) - return; - - if (!alloc->refcount.unref()) { - alloc = NULL; - return; - } - - //must be disposed! - - { - int cur_elements = alloc->size / sizeof(T); - - // Don't use write() here because it could otherwise provoke COW, - // which is not desirable here because we are destroying the last reference anyways - Write w; - // Reference to still prevent other threads from touching the alloc - w._ref(alloc); - - for (int i = 0; i < cur_elements; i++) { - - w[i].~T(); - } - } - -#ifdef DEBUG_ENABLED - MemoryPool::alloc_mutex->lock(); - MemoryPool::total_memory -= alloc->size; - MemoryPool::alloc_mutex->unlock(); -#endif - - if (MemoryPool::memory_pool) { - //resize memory pool - //if none, create - //if some resize - } else { - - memfree(alloc->mem); - alloc->mem = NULL; - alloc->size = 0; - - MemoryPool::alloc_mutex->lock(); - alloc->free_list = MemoryPool::free_list; - MemoryPool::free_list = alloc; - MemoryPool::allocs_used--; - MemoryPool::alloc_mutex->unlock(); - } - - alloc = NULL; - } - -public: - class Access { - friend class PoolVector; - - protected: - MemoryPool::Alloc *alloc; - T *mem; - - _FORCE_INLINE_ void _ref(MemoryPool::Alloc *p_alloc) { - alloc = p_alloc; - if (alloc) { - if (atomic_increment(&alloc->lock) == 1) { - if (MemoryPool::memory_pool) { - //lock it and get mem - } - } - - mem = (T *)alloc->mem; - } - } - - _FORCE_INLINE_ void _unref() { - - if (alloc) { - if (atomic_decrement(&alloc->lock) == 0) { - if (MemoryPool::memory_pool) { - //put mem back - } - } - - mem = NULL; - alloc = NULL; - } - } - - Access() { - alloc = NULL; - mem = NULL; - } - - public: - virtual ~Access() { - _unref(); - } - }; - - class Read : public Access { - public: - _FORCE_INLINE_ const T &operator[](int p_index) const { return this->mem[p_index]; } - _FORCE_INLINE_ const T *ptr() const { return this->mem; } - - void operator=(const Read &p_read) { - if (this->alloc == p_read.alloc) - return; - this->_unref(); - this->_ref(p_read.alloc); - } - - Read(const Read &p_read) { - this->_ref(p_read.alloc); - } - - Read() {} - }; - - class Write : public Access { - public: - _FORCE_INLINE_ T &operator[](int p_index) const { return this->mem[p_index]; } - _FORCE_INLINE_ T *ptr() const { return this->mem; } - - void operator=(const Write &p_read) { - if (this->alloc == p_read.alloc) - return; - this->_unref(); - this->_ref(p_read.alloc); - } - - Write(const Write &p_read) { - this->_ref(p_read.alloc); - } - - Write() {} - }; - - Read read() const { - - Read r; - if (alloc) { - r._ref(alloc); - } - return r; - } - Write write() { - - Write w; - if (alloc) { - _copy_on_write(); //make sure there is only one being acessed - w._ref(alloc); - } - return w; - } - - template - void fill_with(const MC &p_mc) { - - int c = p_mc.size(); - resize(c); - Write w = write(); - int idx = 0; - for (const typename MC::Element *E = p_mc.front(); E; E = E->next()) { - - w[idx++] = E->get(); - } - } - - void remove(int p_index) { - - int s = size(); - ERR_FAIL_INDEX(p_index, s); - Write w = write(); - for (int i = p_index; i < s - 1; i++) { - - w[i] = w[i + 1]; - }; - w = Write(); - resize(s - 1); - } - - inline int size() const; - T get(int p_index) const; - void set(int p_index, const T &p_val); - void push_back(const T &p_val); - void append(const T &p_val) { push_back(p_val); } - void append_array(const PoolVector &p_arr) { - int ds = p_arr.size(); - if (ds == 0) - return; - int bs = size(); - resize(bs + ds); - Write w = write(); - Read r = p_arr.read(); - for (int i = 0; i < ds; i++) - w[bs + i] = r[i]; - } - - PoolVector subarray(int p_from, int p_to) { - - if (p_from < 0) { - p_from = size() + p_from; - } - if (p_to < 0) { - p_to = size() + p_to; - } - - CRASH_BAD_INDEX(p_from, size()); - CRASH_BAD_INDEX(p_to, size()); - - PoolVector slice; - int span = 1 + p_to - p_from; - slice.resize(span); - Read r = read(); - Write w = slice.write(); - for (int i = 0; i < span; ++i) { - w[i] = r[p_from + i]; - } - - return slice; - } - - Error insert(int p_pos, const T &p_val) { - - int s = size(); - ERR_FAIL_INDEX_V(p_pos, s + 1, ERR_INVALID_PARAMETER); - resize(s + 1); - { - Write w = write(); - for (int i = s; i > p_pos; i--) - w[i] = w[i - 1]; - w[p_pos] = p_val; - } - - return OK; - } - - String join(String delimiter) { - String rs = ""; - int s = size(); - Read r = read(); - for (int i = 0; i < s; i++) { - rs += r[i] + delimiter; - } - rs.erase(rs.length() - delimiter.length(), delimiter.length()); - return rs; - } - - bool is_locked() const { return alloc && alloc->lock > 0; } - - inline const T operator[](int p_index) const; - - Error resize(int p_size); - - void invert(); - - void operator=(const PoolVector &p_dvector) { _reference(p_dvector); } - PoolVector() { alloc = NULL; } - PoolVector(const PoolVector &p_dvector) { - alloc = NULL; - _reference(p_dvector); - } - ~PoolVector() { _unreference(); } -}; - -template -int PoolVector::size() const { - - return alloc ? alloc->size / sizeof(T) : 0; -} - -template -T PoolVector::get(int p_index) const { - - return operator[](p_index); -} - -template -void PoolVector::set(int p_index, const T &p_val) { - - if (p_index < 0 || p_index >= size()) { - ERR_FAIL_COND(p_index < 0 || p_index >= size()); - } - - Write w = write(); - w[p_index] = p_val; -} - -template -void PoolVector::push_back(const T &p_val) { - - resize(size() + 1); - set(size() - 1, p_val); -} - -template -const T PoolVector::operator[](int p_index) const { - - CRASH_BAD_INDEX(p_index, size()); - - Read r = read(); - return r[p_index]; -} - -template -Error PoolVector::resize(int p_size) { - - if (alloc == NULL) { - - if (p_size == 0) - return OK; //nothing to do here - - //must allocate something - MemoryPool::alloc_mutex->lock(); - if (MemoryPool::allocs_used == MemoryPool::alloc_count) { - MemoryPool::alloc_mutex->unlock(); - ERR_EXPLAINC("All memory pool allocations are in use."); - ERR_FAIL_V(ERR_OUT_OF_MEMORY); - } - - //take one from the free list - alloc = MemoryPool::free_list; - MemoryPool::free_list = alloc->free_list; - //increment the used counter - MemoryPool::allocs_used++; - - //cleanup the alloc - alloc->size = 0; - alloc->refcount.init(); - alloc->pool_id = POOL_ALLOCATOR_INVALID_ID; - MemoryPool::alloc_mutex->unlock(); - - } else { - - ERR_FAIL_COND_V(alloc->lock > 0, ERR_LOCKED); //can't resize if locked! - } - - size_t new_size = sizeof(T) * p_size; - - if (alloc->size == new_size) - return OK; //nothing to do - - if (p_size == 0) { - _unreference(); - return OK; - } - - _copy_on_write(); // make it unique - -#ifdef DEBUG_ENABLED - MemoryPool::alloc_mutex->lock(); - MemoryPool::total_memory -= alloc->size; - MemoryPool::total_memory += new_size; - if (MemoryPool::total_memory > MemoryPool::max_memory) { - MemoryPool::max_memory = MemoryPool::total_memory; - } - MemoryPool::alloc_mutex->unlock(); -#endif - - int cur_elements = alloc->size / sizeof(T); - - if (p_size > cur_elements) { - - if (MemoryPool::memory_pool) { - //resize memory pool - //if none, create - //if some resize - } else { - - if (alloc->size == 0) { - alloc->mem = memalloc(new_size); - } else { - alloc->mem = memrealloc(alloc->mem, new_size); - } - } - - alloc->size = new_size; - - Write w = write(); - - for (int i = cur_elements; i < p_size; i++) { - - memnew_placement(&w[i], T); - } - - } else { - - { - Write w = write(); - for (int i = p_size; i < cur_elements; i++) { - - w[i].~T(); - } - } - - if (MemoryPool::memory_pool) { - //resize memory pool - //if none, create - //if some resize - } else { - - if (new_size == 0) { - memfree(alloc->mem); - alloc->mem = NULL; - alloc->size = 0; - - MemoryPool::alloc_mutex->lock(); - alloc->free_list = MemoryPool::free_list; - MemoryPool::free_list = alloc; - MemoryPool::allocs_used--; - MemoryPool::alloc_mutex->unlock(); - - } else { - alloc->mem = memrealloc(alloc->mem, new_size); - alloc->size = new_size; - } - } - } - - return OK; -} - -template -void PoolVector::invert() { - T temp; - Write w = write(); - int s = size(); - int half_s = s / 2; - - for (int i = 0; i < half_s; i++) { - temp = w[i]; - w[i] = w[s - i - 1]; - w[s - i - 1] = temp; - } -} - -#endif diff --git a/core/global_constants.h b/core/global_constants.h index 47c1a4dafc..c798a3b9bc 100644 --- a/core/global_constants.h +++ b/core/global_constants.h @@ -31,7 +31,7 @@ #ifndef GLOBAL_CONSTANTS_H #define GLOBAL_CONSTANTS_H -#include "core/string_db.h" +#include "core/string_name.h" class GlobalConstants { public: diff --git a/core/hashfuncs.h b/core/hashfuncs.h index 811ce6264e..07d78dcbde 100644 --- a/core/hashfuncs.h +++ b/core/hashfuncs.h @@ -34,7 +34,7 @@ #include "core/math/math_defs.h" #include "core/math/math_funcs.h" #include "core/node_path.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/typedefs.h" #include "core/ustring.h" diff --git a/core/image.h b/core/image.h index b23f8cac46..872b84d565 100644 --- a/core/image.h +++ b/core/image.h @@ -32,8 +32,8 @@ #define IMAGE_H #include "core/color.h" -#include "core/dvector.h" #include "core/math/rect2.h" +#include "core/pool_vector.h" #include "core/resource.h" /** diff --git a/core/io/file_access_buffered.h b/core/io/file_access_buffered.h index 756045a674..4065d77c58 100644 --- a/core/io/file_access_buffered.h +++ b/core/io/file_access_buffered.h @@ -31,8 +31,8 @@ #ifndef FILE_ACCESS_BUFFERED_H #define FILE_ACCESS_BUFFERED_H -#include "core/dvector.h" #include "core/os/file_access.h" +#include "core/pool_vector.h" #include "core/ustring.h" class FileAccessBuffered : public FileAccess { diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h index 5180f2344f..be960fbc25 100644 --- a/core/io/file_access_buffered_fa.h +++ b/core/io/file_access_buffered_fa.h @@ -54,7 +54,7 @@ class FileAccessBufferedFA : public FileAccessBuffered { cache.offset = p_offset; cache.buffer.resize(p_size); - // on dvector + // on PoolVector //PoolVector::Write write = cache.buffer.write(); //f.get_buffer(write.ptrw(), p_size); diff --git a/core/io/resource_import.cpp b/core/io/resource_import.cpp deleted file mode 100644 index 63dc0b6a26..0000000000 --- a/core/io/resource_import.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/*************************************************************************/ -/* resource_import.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "resource_import.h" - -#include "core/os/os.h" -#include "core/variant_parser.h" - -Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const { - - Error err; - FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); - - if (!f) { - if (r_valid) { - *r_valid = false; - } - return err; - } - - VariantParser::StreamFile stream; - stream.f = f; - - String assign; - Variant value; - VariantParser::Tag next_tag; - - if (r_valid) { - *r_valid = true; - } - - int lines = 0; - String error_text; - bool path_found = false; //first match must have priority - while (true) { - - assign = Variant(); - next_tag.fields.clear(); - next_tag.name = String(); - - err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true); - if (err == ERR_FILE_EOF) { - memdelete(f); - return OK; - } else if (err != OK) { - ERR_PRINTS("ResourceFormatImporter::load - " + p_path + ".import:" + itos(lines) + " error: " + error_text); - memdelete(f); - return err; - } - - if (assign != String()) { - if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) { - String feature = assign.get_slicec('.', 1); - if (OS::get_singleton()->has_feature(feature)) { - r_path_and_type.path = value; - path_found = true; //first match must have priority - } - - } else if (!path_found && assign == "path") { - r_path_and_type.path = value; - path_found = true; //first match must have priority - } else if (assign == "type") { - r_path_and_type.type = value; - } else if (assign == "importer") { - r_path_and_type.importer = value; - } else if (assign == "valid") { - if (r_valid) { - *r_valid = value; - } - } - - } else if (next_tag.name != "remap") { - break; - } - } - - memdelete(f); - - if (r_path_and_type.path == String() || r_path_and_type.type == String()) { - return ERR_FILE_CORRUPT; - } - return OK; -} - -RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error) { - - PathAndType pat; - Error err = _get_path_and_type(p_path, pat); - - if (err != OK) { - - if (r_error) - *r_error = err; - - return RES(); - } - - RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error); - -#ifdef TOOLS_ENABLED - if (res.is_valid()) { - res->set_import_last_modified_time(res->get_last_modified_time()); //pass this, if used - res->set_import_path(pat.path); - } -#endif - - return res; -} - -void ResourceFormatImporter::get_recognized_extensions(List *p_extensions) const { - - Set found; - - for (int i = 0; i < importers.size(); i++) { - List local_exts; - importers[i]->get_recognized_extensions(&local_exts); - for (List::Element *F = local_exts.front(); F; F = F->next()) { - if (!found.has(F->get())) { - p_extensions->push_back(F->get()); - found.insert(F->get()); - } - } - } -} - -void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_type, List *p_extensions) const { - - if (p_type == "") { - return get_recognized_extensions(p_extensions); - } - - Set found; - - for (int i = 0; i < importers.size(); i++) { - String res_type = importers[i]->get_resource_type(); - if (res_type == String()) - continue; - - if (!ClassDB::is_parent_class(res_type, p_type)) - continue; - - List local_exts; - importers[i]->get_recognized_extensions(&local_exts); - for (List::Element *F = local_exts.front(); F; F = F->next()) { - if (!found.has(F->get())) { - p_extensions->push_back(F->get()); - found.insert(F->get()); - } - } - } -} - -bool ResourceFormatImporter::recognize_path(const String &p_path, const String &p_for_type) const { - - return FileAccess::exists(p_path + ".import"); -} - -bool ResourceFormatImporter::can_be_imported(const String &p_path) const { - - return ResourceFormatLoader::recognize_path(p_path); -} - -int ResourceFormatImporter::get_import_order(const String &p_path) const { - - Ref importer; - - if (FileAccess::exists(p_path + ".import")) { - - PathAndType pat; - Error err = _get_path_and_type(p_path, pat); - - if (err == OK) { - importer = get_importer_by_name(pat.importer); - } - } else { - - importer = get_importer_by_extension(p_path.get_extension().to_lower()); - } - - if (importer.is_valid()) - return importer->get_import_order(); - - return 0; -} - -bool ResourceFormatImporter::handles_type(const String &p_type) const { - - for (int i = 0; i < importers.size(); i++) { - - String res_type = importers[i]->get_resource_type(); - if (res_type == String()) - continue; - if (ClassDB::is_parent_class(res_type, p_type)) - return true; - } - - return true; -} - -String ResourceFormatImporter::get_internal_resource_path(const String &p_path) const { - - PathAndType pat; - Error err = _get_path_and_type(p_path, pat); - - if (err != OK) { - - return String(); - } - - return pat.path; -} - -void ResourceFormatImporter::get_internal_resource_path_list(const String &p_path, List *r_paths) { - - Error err; - FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); - - if (!f) - return; - - VariantParser::StreamFile stream; - stream.f = f; - - String assign; - Variant value; - VariantParser::Tag next_tag; - - int lines = 0; - String error_text; - while (true) { - - assign = Variant(); - next_tag.fields.clear(); - next_tag.name = String(); - - err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true); - if (err == ERR_FILE_EOF) { - memdelete(f); - return; - } else if (err != OK) { - ERR_PRINTS("ResourceFormatImporter::get_internal_resource_path_list - " + p_path + ".import:" + itos(lines) + " error: " + error_text); - memdelete(f); - return; - } - - if (assign != String()) { - if (assign.begins_with("path.")) { - r_paths->push_back(value); - } else if (assign == "path") { - r_paths->push_back(value); - } - } else if (next_tag.name != "remap") { - break; - } - } - memdelete(f); -} - -bool ResourceFormatImporter::is_import_valid(const String &p_path) const { - - bool valid = true; - PathAndType pat; - _get_path_and_type(p_path, pat, &valid); - return valid; -} - -String ResourceFormatImporter::get_resource_type(const String &p_path) const { - - PathAndType pat; - Error err = _get_path_and_type(p_path, pat); - - if (err != OK) { - - return ""; - } - - return pat.type; -} - -void ResourceFormatImporter::get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types) { - - PathAndType pat; - Error err = _get_path_and_type(p_path, pat); - - if (err != OK) { - - return; - } - - return ResourceLoader::get_dependencies(pat.path, p_dependencies, p_add_types); -} - -Ref ResourceFormatImporter::get_importer_by_name(const String &p_name) const { - - for (int i = 0; i < importers.size(); i++) { - if (importers[i]->get_importer_name() == p_name) { - return importers[i]; - } - } - - return Ref(); -} - -void ResourceFormatImporter::get_importers_for_extension(const String &p_extension, List > *r_importers) { - - for (int i = 0; i < importers.size(); i++) { - List local_exts; - importers[i]->get_recognized_extensions(&local_exts); - for (List::Element *F = local_exts.front(); F; F = F->next()) { - if (p_extension.to_lower() == F->get()) { - r_importers->push_back(importers[i]); - } - } - } -} - -Ref ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const { - - Ref importer; - float priority = 0; - - for (int i = 0; i < importers.size(); i++) { - - List local_exts; - importers[i]->get_recognized_extensions(&local_exts); - for (List::Element *F = local_exts.front(); F; F = F->next()) { - if (p_extension.to_lower() == F->get() && importers[i]->get_priority() > priority) { - importer = importers[i]; - priority = importers[i]->get_priority(); - } - } - } - - return importer; -} - -String ResourceFormatImporter::get_import_base_path(const String &p_for_file) const { - - return "res://.import/" + p_for_file.get_file() + "-" + p_for_file.md5_text(); -} - -ResourceFormatImporter *ResourceFormatImporter::singleton = NULL; - -ResourceFormatImporter::ResourceFormatImporter() { - singleton = this; -} diff --git a/core/io/resource_import.h b/core/io/resource_import.h deleted file mode 100644 index 96dd7983e6..0000000000 --- a/core/io/resource_import.h +++ /dev/null @@ -1,113 +0,0 @@ -/*************************************************************************/ -/* resource_import.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef RESOURCE_IMPORT_H -#define RESOURCE_IMPORT_H - -#include "core/io/resource_loader.h" - -class ResourceImporter; - -class ResourceFormatImporter : public ResourceFormatLoader { - - GDCLASS(ResourceFormatImporter, ResourceFormatLoader) - - struct PathAndType { - String path; - String type; - String importer; - }; - - Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = NULL) const; - - static ResourceFormatImporter *singleton; - - Vector > importers; - -public: - static ResourceFormatImporter *get_singleton() { return singleton; } - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); - virtual void get_recognized_extensions(List *p_extensions) const; - virtual void get_recognized_extensions_for_type(const String &p_type, List *p_extensions) const; - virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; - virtual bool handles_type(const String &p_type) const; - virtual String get_resource_type(const String &p_path) const; - virtual bool is_import_valid(const String &p_path) const; - virtual void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false); - - virtual bool can_be_imported(const String &p_path) const; - virtual int get_import_order(const String &p_path) const; - - String get_internal_resource_path(const String &p_path) const; - void get_internal_resource_path_list(const String &p_path, List *r_paths); - - void add_importer(const Ref &p_importer) { importers.push_back(p_importer); } - void remove_importer(const Ref &p_importer) { importers.erase(p_importer); } - Ref get_importer_by_name(const String &p_name) const; - Ref get_importer_by_extension(const String &p_extension) const; - void get_importers_for_extension(const String &p_extension, List > *r_importers); - - String get_import_base_path(const String &p_for_file) const; - ResourceFormatImporter(); -}; - -class ResourceImporter : public Reference { - - GDCLASS(ResourceImporter, Reference) -public: - virtual String get_importer_name() const = 0; - virtual String get_visible_name() const = 0; - virtual void get_recognized_extensions(List *p_extensions) const = 0; - virtual String get_save_extension() const = 0; - virtual String get_resource_type() const = 0; - virtual float get_priority() const { return 1.0; } - virtual int get_import_order() const { return 0; } - - struct ImportOption { - PropertyInfo option; - Variant default_value; - - ImportOption(const PropertyInfo &p_info, const Variant &p_default) : - option(p_info), - default_value(p_default) { - } - ImportOption() {} - }; - - virtual int get_preset_count() const { return 0; } - virtual String get_preset_name(int p_idx) const { return String(); } - - virtual void get_import_options(List *r_options, int p_preset = 0) const = 0; - virtual bool get_option_visibility(const String &p_option, const Map &p_options) const = 0; - - virtual Error import(const String &p_source_file, const String &p_save_path, const Map &p_options, List *r_platform_variants, List *r_gen_files = NULL) = 0; -}; - -#endif // RESOURCE_IMPORT_H diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp new file mode 100644 index 0000000000..9327e000f5 --- /dev/null +++ b/core/io/resource_importer.cpp @@ -0,0 +1,373 @@ +/*************************************************************************/ +/* resource_importer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "resource_importer.h" + +#include "core/os/os.h" +#include "core/variant_parser.h" + +Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const { + + Error err; + FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); + + if (!f) { + if (r_valid) { + *r_valid = false; + } + return err; + } + + VariantParser::StreamFile stream; + stream.f = f; + + String assign; + Variant value; + VariantParser::Tag next_tag; + + if (r_valid) { + *r_valid = true; + } + + int lines = 0; + String error_text; + bool path_found = false; //first match must have priority + while (true) { + + assign = Variant(); + next_tag.fields.clear(); + next_tag.name = String(); + + err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true); + if (err == ERR_FILE_EOF) { + memdelete(f); + return OK; + } else if (err != OK) { + ERR_PRINTS("ResourceFormatImporter::load - " + p_path + ".import:" + itos(lines) + " error: " + error_text); + memdelete(f); + return err; + } + + if (assign != String()) { + if (!path_found && assign.begins_with("path.") && r_path_and_type.path == String()) { + String feature = assign.get_slicec('.', 1); + if (OS::get_singleton()->has_feature(feature)) { + r_path_and_type.path = value; + path_found = true; //first match must have priority + } + + } else if (!path_found && assign == "path") { + r_path_and_type.path = value; + path_found = true; //first match must have priority + } else if (assign == "type") { + r_path_and_type.type = value; + } else if (assign == "importer") { + r_path_and_type.importer = value; + } else if (assign == "valid") { + if (r_valid) { + *r_valid = value; + } + } + + } else if (next_tag.name != "remap") { + break; + } + } + + memdelete(f); + + if (r_path_and_type.path == String() || r_path_and_type.type == String()) { + return ERR_FILE_CORRUPT; + } + return OK; +} + +RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error) { + + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err != OK) { + + if (r_error) + *r_error = err; + + return RES(); + } + + RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error); + +#ifdef TOOLS_ENABLED + if (res.is_valid()) { + res->set_import_last_modified_time(res->get_last_modified_time()); //pass this, if used + res->set_import_path(pat.path); + } +#endif + + return res; +} + +void ResourceFormatImporter::get_recognized_extensions(List *p_extensions) const { + + Set found; + + for (int i = 0; i < importers.size(); i++) { + List local_exts; + importers[i]->get_recognized_extensions(&local_exts); + for (List::Element *F = local_exts.front(); F; F = F->next()) { + if (!found.has(F->get())) { + p_extensions->push_back(F->get()); + found.insert(F->get()); + } + } + } +} + +void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_type, List *p_extensions) const { + + if (p_type == "") { + return get_recognized_extensions(p_extensions); + } + + Set found; + + for (int i = 0; i < importers.size(); i++) { + String res_type = importers[i]->get_resource_type(); + if (res_type == String()) + continue; + + if (!ClassDB::is_parent_class(res_type, p_type)) + continue; + + List local_exts; + importers[i]->get_recognized_extensions(&local_exts); + for (List::Element *F = local_exts.front(); F; F = F->next()) { + if (!found.has(F->get())) { + p_extensions->push_back(F->get()); + found.insert(F->get()); + } + } + } +} + +bool ResourceFormatImporter::recognize_path(const String &p_path, const String &p_for_type) const { + + return FileAccess::exists(p_path + ".import"); +} + +bool ResourceFormatImporter::can_be_imported(const String &p_path) const { + + return ResourceFormatLoader::recognize_path(p_path); +} + +int ResourceFormatImporter::get_import_order(const String &p_path) const { + + Ref importer; + + if (FileAccess::exists(p_path + ".import")) { + + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err == OK) { + importer = get_importer_by_name(pat.importer); + } + } else { + + importer = get_importer_by_extension(p_path.get_extension().to_lower()); + } + + if (importer.is_valid()) + return importer->get_import_order(); + + return 0; +} + +bool ResourceFormatImporter::handles_type(const String &p_type) const { + + for (int i = 0; i < importers.size(); i++) { + + String res_type = importers[i]->get_resource_type(); + if (res_type == String()) + continue; + if (ClassDB::is_parent_class(res_type, p_type)) + return true; + } + + return true; +} + +String ResourceFormatImporter::get_internal_resource_path(const String &p_path) const { + + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err != OK) { + + return String(); + } + + return pat.path; +} + +void ResourceFormatImporter::get_internal_resource_path_list(const String &p_path, List *r_paths) { + + Error err; + FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); + + if (!f) + return; + + VariantParser::StreamFile stream; + stream.f = f; + + String assign; + Variant value; + VariantParser::Tag next_tag; + + int lines = 0; + String error_text; + while (true) { + + assign = Variant(); + next_tag.fields.clear(); + next_tag.name = String(); + + err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true); + if (err == ERR_FILE_EOF) { + memdelete(f); + return; + } else if (err != OK) { + ERR_PRINTS("ResourceFormatImporter::get_internal_resource_path_list - " + p_path + ".import:" + itos(lines) + " error: " + error_text); + memdelete(f); + return; + } + + if (assign != String()) { + if (assign.begins_with("path.")) { + r_paths->push_back(value); + } else if (assign == "path") { + r_paths->push_back(value); + } + } else if (next_tag.name != "remap") { + break; + } + } + memdelete(f); +} + +bool ResourceFormatImporter::is_import_valid(const String &p_path) const { + + bool valid = true; + PathAndType pat; + _get_path_and_type(p_path, pat, &valid); + return valid; +} + +String ResourceFormatImporter::get_resource_type(const String &p_path) const { + + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err != OK) { + + return ""; + } + + return pat.type; +} + +void ResourceFormatImporter::get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types) { + + PathAndType pat; + Error err = _get_path_and_type(p_path, pat); + + if (err != OK) { + + return; + } + + return ResourceLoader::get_dependencies(pat.path, p_dependencies, p_add_types); +} + +Ref ResourceFormatImporter::get_importer_by_name(const String &p_name) const { + + for (int i = 0; i < importers.size(); i++) { + if (importers[i]->get_importer_name() == p_name) { + return importers[i]; + } + } + + return Ref(); +} + +void ResourceFormatImporter::get_importers_for_extension(const String &p_extension, List > *r_importers) { + + for (int i = 0; i < importers.size(); i++) { + List local_exts; + importers[i]->get_recognized_extensions(&local_exts); + for (List::Element *F = local_exts.front(); F; F = F->next()) { + if (p_extension.to_lower() == F->get()) { + r_importers->push_back(importers[i]); + } + } + } +} + +Ref ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const { + + Ref importer; + float priority = 0; + + for (int i = 0; i < importers.size(); i++) { + + List local_exts; + importers[i]->get_recognized_extensions(&local_exts); + for (List::Element *F = local_exts.front(); F; F = F->next()) { + if (p_extension.to_lower() == F->get() && importers[i]->get_priority() > priority) { + importer = importers[i]; + priority = importers[i]->get_priority(); + } + } + } + + return importer; +} + +String ResourceFormatImporter::get_import_base_path(const String &p_for_file) const { + + return "res://.import/" + p_for_file.get_file() + "-" + p_for_file.md5_text(); +} + +ResourceFormatImporter *ResourceFormatImporter::singleton = NULL; + +ResourceFormatImporter::ResourceFormatImporter() { + singleton = this; +} diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h new file mode 100644 index 0000000000..32c39a8085 --- /dev/null +++ b/core/io/resource_importer.h @@ -0,0 +1,113 @@ +/*************************************************************************/ +/* resource_importer.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RESOURCE_IMPORTER_H +#define RESOURCE_IMPORTER_H + +#include "core/io/resource_loader.h" + +class ResourceImporter; + +class ResourceFormatImporter : public ResourceFormatLoader { + + GDCLASS(ResourceFormatImporter, ResourceFormatLoader) + + struct PathAndType { + String path; + String type; + String importer; + }; + + Error _get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid = NULL) const; + + static ResourceFormatImporter *singleton; + + Vector > importers; + +public: + static ResourceFormatImporter *get_singleton() { return singleton; } + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual void get_recognized_extensions(List *p_extensions) const; + virtual void get_recognized_extensions_for_type(const String &p_type, List *p_extensions) const; + virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const; + virtual bool handles_type(const String &p_type) const; + virtual String get_resource_type(const String &p_path) const; + virtual bool is_import_valid(const String &p_path) const; + virtual void get_dependencies(const String &p_path, List *p_dependencies, bool p_add_types = false); + + virtual bool can_be_imported(const String &p_path) const; + virtual int get_import_order(const String &p_path) const; + + String get_internal_resource_path(const String &p_path) const; + void get_internal_resource_path_list(const String &p_path, List *r_paths); + + void add_importer(const Ref &p_importer) { importers.push_back(p_importer); } + void remove_importer(const Ref &p_importer) { importers.erase(p_importer); } + Ref get_importer_by_name(const String &p_name) const; + Ref get_importer_by_extension(const String &p_extension) const; + void get_importers_for_extension(const String &p_extension, List > *r_importers); + + String get_import_base_path(const String &p_for_file) const; + ResourceFormatImporter(); +}; + +class ResourceImporter : public Reference { + + GDCLASS(ResourceImporter, Reference) +public: + virtual String get_importer_name() const = 0; + virtual String get_visible_name() const = 0; + virtual void get_recognized_extensions(List *p_extensions) const = 0; + virtual String get_save_extension() const = 0; + virtual String get_resource_type() const = 0; + virtual float get_priority() const { return 1.0; } + virtual int get_import_order() const { return 0; } + + struct ImportOption { + PropertyInfo option; + Variant default_value; + + ImportOption(const PropertyInfo &p_info, const Variant &p_default) : + option(p_info), + default_value(p_default) { + } + ImportOption() {} + }; + + virtual int get_preset_count() const { return 0; } + virtual String get_preset_name(int p_idx) const { return String(); } + + virtual void get_import_options(List *r_options, int p_preset = 0) const = 0; + virtual bool get_option_visibility(const String &p_option, const Map &p_options) const = 0; + + virtual Error import(const String &p_source_file, const String &p_save_path, const Map &p_options, List *r_platform_variants, List *r_gen_files = NULL) = 0; +}; + +#endif // RESOURCE_IMPORTER_H diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 02e4d8dc7a..4aa002e9a2 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -30,7 +30,7 @@ #include "resource_loader.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" #include "core/os/file_access.h" #include "core/os/os.h" #include "core/path_remap.h" diff --git a/core/list.h b/core/list.h index dd4ea3bd89..c26aad6463 100644 --- a/core/list.h +++ b/core/list.h @@ -32,7 +32,7 @@ #define GLOBALS_LIST_H #include "core/os/memory.h" -#include "core/sort.h" +#include "core/sort_array.h" /** * Generic Templatized Linked List Implementation. diff --git a/core/math/bsp_tree.h b/core/math/bsp_tree.h index 0af532a2d5..a7a3697990 100644 --- a/core/math/bsp_tree.h +++ b/core/math/bsp_tree.h @@ -31,11 +31,11 @@ #ifndef BSP_TREE_H #define BSP_TREE_H -#include "core/dvector.h" #include "core/math/aabb.h" #include "core/math/face3.h" #include "core/math/plane.h" #include "core/method_ptrcall.h" +#include "core/pool_vector.h" #include "core/variant.h" #include "core/vector.h" /** diff --git a/core/math/geometry.h b/core/math/geometry.h index 29493516b8..f927a63ed5 100644 --- a/core/math/geometry.h +++ b/core/math/geometry.h @@ -31,12 +31,12 @@ #ifndef GEOMETRY_H #define GEOMETRY_H -#include "core/dvector.h" #include "core/math/face3.h" #include "core/math/rect2.h" #include "core/math/triangulate.h" #include "core/math/vector3.h" #include "core/object.h" +#include "core/pool_vector.h" #include "core/print_string.h" #include "core/vector.h" diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index cdf3d16b72..83784a1fa7 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -30,7 +30,7 @@ #include "triangle_mesh.h" -#include "core/sort.h" +#include "core/sort_array.h" int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) { diff --git a/core/node_path.h b/core/node_path.h index 17b1435723..24725123d6 100644 --- a/core/node_path.h +++ b/core/node_path.h @@ -31,7 +31,7 @@ #ifndef NODE_PATH_H #define NODE_PATH_H -#include "core/string_db.h" +#include "core/string_name.h" #include "core/ustring.h" /** diff --git a/core/os/shell.cpp b/core/os/shell.cpp deleted file mode 100644 index a859241cb6..0000000000 --- a/core/os/shell.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************/ -/* shell.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "shell.h" - -Shell *Shell::singleton = NULL; - -Shell *Shell::get_singleton() { - - return singleton; -} - -Shell::~Shell() { -} - -Shell::Shell() { - - singleton = this; -} diff --git a/core/os/shell.h b/core/os/shell.h deleted file mode 100644 index c1bd995b5b..0000000000 --- a/core/os/shell.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ -/* shell.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef SHELL_H -#define SHELL_H - -#include "core/typedefs.h" -#include "core/ustring.h" - -/** - @author Juan Linietsky -*/ -class Shell { - - static Shell *singleton; - -public: - static Shell *get_singleton(); - virtual void execute(String p_path) = 0; - - Shell(); - virtual ~Shell(); -}; - -#endif diff --git a/core/pool_vector.cpp b/core/pool_vector.cpp new file mode 100644 index 0000000000..b9d2316315 --- /dev/null +++ b/core/pool_vector.cpp @@ -0,0 +1,71 @@ +/*************************************************************************/ +/* pool_vector.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "pool_vector.h" + +Mutex *pool_vector_lock = NULL; + +PoolAllocator *MemoryPool::memory_pool = NULL; +uint8_t *MemoryPool::pool_memory = NULL; +size_t *MemoryPool::pool_size = NULL; + +MemoryPool::Alloc *MemoryPool::allocs = NULL; +MemoryPool::Alloc *MemoryPool::free_list = NULL; +uint32_t MemoryPool::alloc_count = 0; +uint32_t MemoryPool::allocs_used = 0; +Mutex *MemoryPool::alloc_mutex = NULL; + +size_t MemoryPool::total_memory = 0; +size_t MemoryPool::max_memory = 0; + +void MemoryPool::setup(uint32_t p_max_allocs) { + + allocs = memnew_arr(Alloc, p_max_allocs); + alloc_count = p_max_allocs; + allocs_used = 0; + + for (uint32_t i = 0; i < alloc_count - 1; i++) { + + allocs[i].free_list = &allocs[i + 1]; + } + + free_list = &allocs[0]; + + alloc_mutex = Mutex::create(); +} + +void MemoryPool::cleanup() { + + memdelete_arr(allocs); + memdelete(alloc_mutex); + + ERR_EXPLAINC("There are still MemoryPool allocs in use at exit!"); + ERR_FAIL_COND(allocs_used > 0); +} diff --git a/core/pool_vector.h b/core/pool_vector.h new file mode 100644 index 0000000000..102a620f17 --- /dev/null +++ b/core/pool_vector.h @@ -0,0 +1,643 @@ +/*************************************************************************/ +/* pool_vector.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef POOL_VECTOR_H +#define POOL_VECTOR_H + +#include "core/os/copymem.h" +#include "core/os/memory.h" +#include "core/os/rw_lock.h" +#include "core/pool_allocator.h" +#include "core/safe_refcount.h" +#include "core/ustring.h" + +struct MemoryPool { + + //avoid accessing these directly, must be public for template access + + static PoolAllocator *memory_pool; + static uint8_t *pool_memory; + static size_t *pool_size; + + struct Alloc { + + SafeRefCount refcount; + uint32_t lock; + void *mem; + PoolAllocator::ID pool_id; + size_t size; + + Alloc *free_list; + + Alloc() : + lock(0), + mem(NULL), + pool_id(POOL_ALLOCATOR_INVALID_ID), + size(0), + free_list(NULL) { + } + }; + + static Alloc *allocs; + static Alloc *free_list; + static uint32_t alloc_count; + static uint32_t allocs_used; + static Mutex *alloc_mutex; + static size_t total_memory; + static size_t max_memory; + + static void setup(uint32_t p_max_allocs = (1 << 16)); + static void cleanup(); +}; + +/** + @author Juan Linietsky +*/ + +template +class PoolVector { + + MemoryPool::Alloc *alloc; + + void _copy_on_write() { + + if (!alloc) + return; + + // ERR_FAIL_COND(alloc->lock>0); should not be illegal to lock this for copy on write, as it's a copy on write after all + + // Refcount should not be zero, otherwise it's a misuse of COW + if (alloc->refcount.get() == 1) + return; //nothing to do + + //must allocate something + + MemoryPool::alloc_mutex->lock(); + if (MemoryPool::allocs_used == MemoryPool::alloc_count) { + MemoryPool::alloc_mutex->unlock(); + ERR_EXPLAINC("All memory pool allocations are in use, can't COW."); + ERR_FAIL(); + } + + MemoryPool::Alloc *old_alloc = alloc; + + //take one from the free list + alloc = MemoryPool::free_list; + MemoryPool::free_list = alloc->free_list; + //increment the used counter + MemoryPool::allocs_used++; + + //copy the alloc data + alloc->size = old_alloc->size; + alloc->refcount.init(); + alloc->pool_id = POOL_ALLOCATOR_INVALID_ID; + alloc->lock = 0; + +#ifdef DEBUG_ENABLED + MemoryPool::total_memory += alloc->size; + if (MemoryPool::total_memory > MemoryPool::max_memory) { + MemoryPool::max_memory = MemoryPool::total_memory; + } +#endif + + MemoryPool::alloc_mutex->unlock(); + + if (MemoryPool::memory_pool) { + + } else { + alloc->mem = memalloc(alloc->size); + } + + { + Write w; + w._ref(alloc); + Read r; + r._ref(old_alloc); + + int cur_elements = alloc->size / sizeof(T); + T *dst = (T *)w.ptr(); + const T *src = (const T *)r.ptr(); + for (int i = 0; i < cur_elements; i++) { + memnew_placement(&dst[i], T(src[i])); + } + } + + if (old_alloc->refcount.unref()) { + //this should never happen but.. + +#ifdef DEBUG_ENABLED + MemoryPool::alloc_mutex->lock(); + MemoryPool::total_memory -= old_alloc->size; + MemoryPool::alloc_mutex->unlock(); +#endif + + { + Write w; + w._ref(old_alloc); + + int cur_elements = old_alloc->size / sizeof(T); + T *elems = (T *)w.ptr(); + for (int i = 0; i < cur_elements; i++) { + elems[i].~T(); + } + } + + if (MemoryPool::memory_pool) { + //resize memory pool + //if none, create + //if some resize + } else { + + memfree(old_alloc->mem); + old_alloc->mem = NULL; + old_alloc->size = 0; + + MemoryPool::alloc_mutex->lock(); + old_alloc->free_list = MemoryPool::free_list; + MemoryPool::free_list = old_alloc; + MemoryPool::allocs_used--; + MemoryPool::alloc_mutex->unlock(); + } + } + } + + void _reference(const PoolVector &p_pool_vector) { + + if (alloc == p_pool_vector.alloc) + return; + + _unreference(); + + if (!p_pool_vector.alloc) { + return; + } + + if (p_pool_vector.alloc->refcount.ref()) { + alloc = p_pool_vector.alloc; + } + } + + void _unreference() { + + if (!alloc) + return; + + if (!alloc->refcount.unref()) { + alloc = NULL; + return; + } + + //must be disposed! + + { + int cur_elements = alloc->size / sizeof(T); + + // Don't use write() here because it could otherwise provoke COW, + // which is not desirable here because we are destroying the last reference anyways + Write w; + // Reference to still prevent other threads from touching the alloc + w._ref(alloc); + + for (int i = 0; i < cur_elements; i++) { + + w[i].~T(); + } + } + +#ifdef DEBUG_ENABLED + MemoryPool::alloc_mutex->lock(); + MemoryPool::total_memory -= alloc->size; + MemoryPool::alloc_mutex->unlock(); +#endif + + if (MemoryPool::memory_pool) { + //resize memory pool + //if none, create + //if some resize + } else { + + memfree(alloc->mem); + alloc->mem = NULL; + alloc->size = 0; + + MemoryPool::alloc_mutex->lock(); + alloc->free_list = MemoryPool::free_list; + MemoryPool::free_list = alloc; + MemoryPool::allocs_used--; + MemoryPool::alloc_mutex->unlock(); + } + + alloc = NULL; + } + +public: + class Access { + friend class PoolVector; + + protected: + MemoryPool::Alloc *alloc; + T *mem; + + _FORCE_INLINE_ void _ref(MemoryPool::Alloc *p_alloc) { + alloc = p_alloc; + if (alloc) { + if (atomic_increment(&alloc->lock) == 1) { + if (MemoryPool::memory_pool) { + //lock it and get mem + } + } + + mem = (T *)alloc->mem; + } + } + + _FORCE_INLINE_ void _unref() { + + if (alloc) { + if (atomic_decrement(&alloc->lock) == 0) { + if (MemoryPool::memory_pool) { + //put mem back + } + } + + mem = NULL; + alloc = NULL; + } + } + + Access() { + alloc = NULL; + mem = NULL; + } + + public: + virtual ~Access() { + _unref(); + } + }; + + class Read : public Access { + public: + _FORCE_INLINE_ const T &operator[](int p_index) const { return this->mem[p_index]; } + _FORCE_INLINE_ const T *ptr() const { return this->mem; } + + void operator=(const Read &p_read) { + if (this->alloc == p_read.alloc) + return; + this->_unref(); + this->_ref(p_read.alloc); + } + + Read(const Read &p_read) { + this->_ref(p_read.alloc); + } + + Read() {} + }; + + class Write : public Access { + public: + _FORCE_INLINE_ T &operator[](int p_index) const { return this->mem[p_index]; } + _FORCE_INLINE_ T *ptr() const { return this->mem; } + + void operator=(const Write &p_read) { + if (this->alloc == p_read.alloc) + return; + this->_unref(); + this->_ref(p_read.alloc); + } + + Write(const Write &p_read) { + this->_ref(p_read.alloc); + } + + Write() {} + }; + + Read read() const { + + Read r; + if (alloc) { + r._ref(alloc); + } + return r; + } + Write write() { + + Write w; + if (alloc) { + _copy_on_write(); //make sure there is only one being acessed + w._ref(alloc); + } + return w; + } + + template + void fill_with(const MC &p_mc) { + + int c = p_mc.size(); + resize(c); + Write w = write(); + int idx = 0; + for (const typename MC::Element *E = p_mc.front(); E; E = E->next()) { + + w[idx++] = E->get(); + } + } + + void remove(int p_index) { + + int s = size(); + ERR_FAIL_INDEX(p_index, s); + Write w = write(); + for (int i = p_index; i < s - 1; i++) { + + w[i] = w[i + 1]; + }; + w = Write(); + resize(s - 1); + } + + inline int size() const; + T get(int p_index) const; + void set(int p_index, const T &p_val); + void push_back(const T &p_val); + void append(const T &p_val) { push_back(p_val); } + void append_array(const PoolVector &p_arr) { + int ds = p_arr.size(); + if (ds == 0) + return; + int bs = size(); + resize(bs + ds); + Write w = write(); + Read r = p_arr.read(); + for (int i = 0; i < ds; i++) + w[bs + i] = r[i]; + } + + PoolVector subarray(int p_from, int p_to) { + + if (p_from < 0) { + p_from = size() + p_from; + } + if (p_to < 0) { + p_to = size() + p_to; + } + + CRASH_BAD_INDEX(p_from, size()); + CRASH_BAD_INDEX(p_to, size()); + + PoolVector slice; + int span = 1 + p_to - p_from; + slice.resize(span); + Read r = read(); + Write w = slice.write(); + for (int i = 0; i < span; ++i) { + w[i] = r[p_from + i]; + } + + return slice; + } + + Error insert(int p_pos, const T &p_val) { + + int s = size(); + ERR_FAIL_INDEX_V(p_pos, s + 1, ERR_INVALID_PARAMETER); + resize(s + 1); + { + Write w = write(); + for (int i = s; i > p_pos; i--) + w[i] = w[i - 1]; + w[p_pos] = p_val; + } + + return OK; + } + + String join(String delimiter) { + String rs = ""; + int s = size(); + Read r = read(); + for (int i = 0; i < s; i++) { + rs += r[i] + delimiter; + } + rs.erase(rs.length() - delimiter.length(), delimiter.length()); + return rs; + } + + bool is_locked() const { return alloc && alloc->lock > 0; } + + inline const T operator[](int p_index) const; + + Error resize(int p_size); + + void invert(); + + void operator=(const PoolVector &p_pool_vector) { _reference(p_pool_vector); } + PoolVector() { alloc = NULL; } + PoolVector(const PoolVector &p_pool_vector) { + alloc = NULL; + _reference(p_pool_vector); + } + ~PoolVector() { _unreference(); } +}; + +template +int PoolVector::size() const { + + return alloc ? alloc->size / sizeof(T) : 0; +} + +template +T PoolVector::get(int p_index) const { + + return operator[](p_index); +} + +template +void PoolVector::set(int p_index, const T &p_val) { + + if (p_index < 0 || p_index >= size()) { + ERR_FAIL_COND(p_index < 0 || p_index >= size()); + } + + Write w = write(); + w[p_index] = p_val; +} + +template +void PoolVector::push_back(const T &p_val) { + + resize(size() + 1); + set(size() - 1, p_val); +} + +template +const T PoolVector::operator[](int p_index) const { + + CRASH_BAD_INDEX(p_index, size()); + + Read r = read(); + return r[p_index]; +} + +template +Error PoolVector::resize(int p_size) { + + if (alloc == NULL) { + + if (p_size == 0) + return OK; //nothing to do here + + //must allocate something + MemoryPool::alloc_mutex->lock(); + if (MemoryPool::allocs_used == MemoryPool::alloc_count) { + MemoryPool::alloc_mutex->unlock(); + ERR_EXPLAINC("All memory pool allocations are in use."); + ERR_FAIL_V(ERR_OUT_OF_MEMORY); + } + + //take one from the free list + alloc = MemoryPool::free_list; + MemoryPool::free_list = alloc->free_list; + //increment the used counter + MemoryPool::allocs_used++; + + //cleanup the alloc + alloc->size = 0; + alloc->refcount.init(); + alloc->pool_id = POOL_ALLOCATOR_INVALID_ID; + MemoryPool::alloc_mutex->unlock(); + + } else { + + ERR_FAIL_COND_V(alloc->lock > 0, ERR_LOCKED); //can't resize if locked! + } + + size_t new_size = sizeof(T) * p_size; + + if (alloc->size == new_size) + return OK; //nothing to do + + if (p_size == 0) { + _unreference(); + return OK; + } + + _copy_on_write(); // make it unique + +#ifdef DEBUG_ENABLED + MemoryPool::alloc_mutex->lock(); + MemoryPool::total_memory -= alloc->size; + MemoryPool::total_memory += new_size; + if (MemoryPool::total_memory > MemoryPool::max_memory) { + MemoryPool::max_memory = MemoryPool::total_memory; + } + MemoryPool::alloc_mutex->unlock(); +#endif + + int cur_elements = alloc->size / sizeof(T); + + if (p_size > cur_elements) { + + if (MemoryPool::memory_pool) { + //resize memory pool + //if none, create + //if some resize + } else { + + if (alloc->size == 0) { + alloc->mem = memalloc(new_size); + } else { + alloc->mem = memrealloc(alloc->mem, new_size); + } + } + + alloc->size = new_size; + + Write w = write(); + + for (int i = cur_elements; i < p_size; i++) { + + memnew_placement(&w[i], T); + } + + } else { + + { + Write w = write(); + for (int i = p_size; i < cur_elements; i++) { + + w[i].~T(); + } + } + + if (MemoryPool::memory_pool) { + //resize memory pool + //if none, create + //if some resize + } else { + + if (new_size == 0) { + memfree(alloc->mem); + alloc->mem = NULL; + alloc->size = 0; + + MemoryPool::alloc_mutex->lock(); + alloc->free_list = MemoryPool::free_list; + MemoryPool::free_list = alloc; + MemoryPool::allocs_used--; + MemoryPool::alloc_mutex->unlock(); + + } else { + alloc->mem = memrealloc(alloc->mem, new_size); + alloc->size = new_size; + } + } + } + + return OK; +} + +template +void PoolVector::invert() { + T temp; + Write w = write(); + int s = size(); + int half_s = s / 2; + + for (int i = 0; i < half_s; i++) { + temp = w[i]; + w[i] = w[s - i - 1]; + w[s - i - 1] = temp; + } +} + +#endif // POOL_VECTOR_H diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index 60c2778603..97c96b4018 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -47,7 +47,7 @@ #include "core/io/packet_peer_udp.h" #include "core/io/pck_packer.h" #include "core/io/resource_format_binary.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" #include "core/io/stream_peer_ssl.h" #include "core/io/tcp_server.h" #include "core/io/translation_loader_po.h" diff --git a/core/sort.h b/core/sort.h deleted file mode 100644 index 4da7c323c7..0000000000 --- a/core/sort.h +++ /dev/null @@ -1,330 +0,0 @@ -/*************************************************************************/ -/* sort.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef SORT_H -#define SORT_H - -#include "core/typedefs.h" - -#define ERR_BAD_COMPARE(cond) \ - if (unlikely(cond)) { \ - ERR_PRINT("bad comparison function; sorting will be broken"); \ - break; \ - } - -template -struct _DefaultComparator { - - _FORCE_INLINE_ bool operator()(const T &a, const T &b) const { return (a < b); } -}; - -#ifdef DEBUG_ENABLED -#define SORT_ARRAY_VALIDATE_ENABLED true -#else -#define SORT_ARRAY_VALIDATE_ENABLED false -#endif - -template , bool Validate = SORT_ARRAY_VALIDATE_ENABLED> -class SortArray { - - enum { - - INTROSORT_THRESHOLD = 16 - }; - -public: - Comparator compare; - - inline const T &median_of_3(const T &a, const T &b, const T &c) const { - - if (compare(a, b)) - if (compare(b, c)) - return b; - else if (compare(a, c)) - return c; - else - return a; - else if (compare(a, c)) - return a; - else if (compare(b, c)) - return c; - else - return b; - } - - inline int bitlog(int n) const { - int k; - for (k = 0; n != 1; n >>= 1) - ++k; - return k; - } - - /* Heap / Heapsort functions */ - - inline void push_heap(int p_first, int p_hole_idx, int p_top_index, T p_value, T *p_array) const { - - int parent = (p_hole_idx - 1) / 2; - while (p_hole_idx > p_top_index && compare(p_array[p_first + parent], p_value)) { - - p_array[p_first + p_hole_idx] = p_array[p_first + parent]; - p_hole_idx = parent; - parent = (p_hole_idx - 1) / 2; - } - p_array[p_first + p_hole_idx] = p_value; - } - - inline void pop_heap(int p_first, int p_last, int p_result, T p_value, T *p_array) const { - - p_array[p_result] = p_array[p_first]; - adjust_heap(p_first, 0, p_last - p_first, p_value, p_array); - } - inline void pop_heap(int p_first, int p_last, T *p_array) const { - - pop_heap(p_first, p_last - 1, p_last - 1, p_array[p_last - 1], p_array); - } - - inline void adjust_heap(int p_first, int p_hole_idx, int p_len, T p_value, T *p_array) const { - - int top_index = p_hole_idx; - int second_child = 2 * p_hole_idx + 2; - - while (second_child < p_len) { - - if (compare(p_array[p_first + second_child], p_array[p_first + (second_child - 1)])) - second_child--; - - p_array[p_first + p_hole_idx] = p_array[p_first + second_child]; - p_hole_idx = second_child; - second_child = 2 * (second_child + 1); - } - - if (second_child == p_len) { - p_array[p_first + p_hole_idx] = p_array[p_first + (second_child - 1)]; - p_hole_idx = second_child - 1; - } - push_heap(p_first, p_hole_idx, top_index, p_value, p_array); - } - - inline void sort_heap(int p_first, int p_last, T *p_array) const { - - while (p_last - p_first > 1) { - - pop_heap(p_first, p_last--, p_array); - } - } - - inline void make_heap(int p_first, int p_last, T *p_array) const { - if (p_last - p_first < 2) - return; - int len = p_last - p_first; - int parent = (len - 2) / 2; - - while (true) { - adjust_heap(p_first, parent, len, p_array[p_first + parent], p_array); - if (parent == 0) - return; - parent--; - } - } - - inline void partial_sort(int p_first, int p_last, int p_middle, T *p_array) const { - - make_heap(p_first, p_middle, p_array); - for (int i = p_middle; i < p_last; i++) - if (compare(p_array[i], p_array[p_first])) - pop_heap(p_first, p_middle, i, p_array[i], p_array); - sort_heap(p_first, p_middle, p_array); - } - - inline void partial_select(int p_first, int p_last, int p_middle, T *p_array) const { - - make_heap(p_first, p_middle, p_array); - for (int i = p_middle; i < p_last; i++) - if (compare(p_array[i], p_array[p_first])) - pop_heap(p_first, p_middle, i, p_array[i], p_array); - } - - inline int partitioner(int p_first, int p_last, T p_pivot, T *p_array) const { - - const int unmodified_first = p_first; - const int unmodified_last = p_last; - - while (true) { - while (compare(p_array[p_first], p_pivot)) { - if (Validate) { - ERR_BAD_COMPARE(p_first == unmodified_last - 1) - } - p_first++; - } - p_last--; - while (compare(p_pivot, p_array[p_last])) { - if (Validate) { - ERR_BAD_COMPARE(p_last == unmodified_first) - } - p_last--; - } - - if (!(p_first < p_last)) - return p_first; - - SWAP(p_array[p_first], p_array[p_last]); - p_first++; - } - } - - inline void introsort(int p_first, int p_last, T *p_array, int p_max_depth) const { - - while (p_last - p_first > INTROSORT_THRESHOLD) { - - if (p_max_depth == 0) { - partial_sort(p_first, p_last, p_last, p_array); - return; - } - - p_max_depth--; - - int cut = partitioner( - p_first, - p_last, - median_of_3( - p_array[p_first], - p_array[p_first + (p_last - p_first) / 2], - p_array[p_last - 1]), - p_array); - - introsort(cut, p_last, p_array, p_max_depth); - p_last = cut; - } - } - - inline void introselect(int p_first, int p_nth, int p_last, T *p_array, int p_max_depth) const { - - while (p_last - p_first > 3) { - - if (p_max_depth == 0) { - partial_select(p_first, p_nth + 1, p_last, p_array); - SWAP(p_first, p_nth); - return; - } - - p_max_depth--; - - int cut = partitioner( - p_first, - p_last, - median_of_3( - p_array[p_first], - p_array[p_first + (p_last - p_first) / 2], - p_array[p_last - 1]), - p_array); - - if (cut <= p_nth) - p_first = cut; - else - p_last = cut; - } - - insertion_sort(p_first, p_last, p_array); - } - - inline void unguarded_linear_insert(int p_last, T p_value, T *p_array) const { - - int next = p_last - 1; - while (compare(p_value, p_array[next])) { - if (Validate) { - ERR_BAD_COMPARE(next == 0) - } - p_array[p_last] = p_array[next]; - p_last = next; - next--; - } - p_array[p_last] = p_value; - } - - inline void linear_insert(int p_first, int p_last, T *p_array) const { - - T val = p_array[p_last]; - if (compare(val, p_array[p_first])) { - - for (int i = p_last; i > p_first; i--) - p_array[i] = p_array[i - 1]; - - p_array[p_first] = val; - } else - unguarded_linear_insert(p_last, val, p_array); - } - - inline void insertion_sort(int p_first, int p_last, T *p_array) const { - - if (p_first == p_last) - return; - for (int i = p_first + 1; i != p_last; i++) - linear_insert(p_first, i, p_array); - } - - inline void unguarded_insertion_sort(int p_first, int p_last, T *p_array) const { - - for (int i = p_first; i != p_last; i++) - unguarded_linear_insert(i, p_array[i], p_array); - } - - inline void final_insertion_sort(int p_first, int p_last, T *p_array) const { - - if (p_last - p_first > INTROSORT_THRESHOLD) { - insertion_sort(p_first, p_first + INTROSORT_THRESHOLD, p_array); - unguarded_insertion_sort(p_first + INTROSORT_THRESHOLD, p_last, p_array); - } else { - - insertion_sort(p_first, p_last, p_array); - } - } - - inline void sort_range(int p_first, int p_last, T *p_array) const { - - if (p_first != p_last) { - introsort(p_first, p_last, p_array, bitlog(p_last - p_first) * 2); - final_insertion_sort(p_first, p_last, p_array); - } - } - - inline void sort(T *p_array, int p_len) const { - - sort_range(0, p_len, p_array); - } - - inline void nth_element(int p_first, int p_last, int p_nth, T *p_array) const { - - if (p_first == p_last || p_nth == p_last) - return; - introselect(p_first, p_nth, p_last, p_array, bitlog(p_last - p_first) * 2); - } -}; - -#endif diff --git a/core/sort_array.h b/core/sort_array.h new file mode 100644 index 0000000000..0f258aec3e --- /dev/null +++ b/core/sort_array.h @@ -0,0 +1,330 @@ +/*************************************************************************/ +/* sort_array.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef SORT_ARRAY_H +#define SORT_ARRAY_H + +#include "core/typedefs.h" + +#define ERR_BAD_COMPARE(cond) \ + if (unlikely(cond)) { \ + ERR_PRINT("bad comparison function; sorting will be broken"); \ + break; \ + } + +template +struct _DefaultComparator { + + _FORCE_INLINE_ bool operator()(const T &a, const T &b) const { return (a < b); } +}; + +#ifdef DEBUG_ENABLED +#define SORT_ARRAY_VALIDATE_ENABLED true +#else +#define SORT_ARRAY_VALIDATE_ENABLED false +#endif + +template , bool Validate = SORT_ARRAY_VALIDATE_ENABLED> +class SortArray { + + enum { + + INTROSORT_THRESHOLD = 16 + }; + +public: + Comparator compare; + + inline const T &median_of_3(const T &a, const T &b, const T &c) const { + + if (compare(a, b)) + if (compare(b, c)) + return b; + else if (compare(a, c)) + return c; + else + return a; + else if (compare(a, c)) + return a; + else if (compare(b, c)) + return c; + else + return b; + } + + inline int bitlog(int n) const { + int k; + for (k = 0; n != 1; n >>= 1) + ++k; + return k; + } + + /* Heap / Heapsort functions */ + + inline void push_heap(int p_first, int p_hole_idx, int p_top_index, T p_value, T *p_array) const { + + int parent = (p_hole_idx - 1) / 2; + while (p_hole_idx > p_top_index && compare(p_array[p_first + parent], p_value)) { + + p_array[p_first + p_hole_idx] = p_array[p_first + parent]; + p_hole_idx = parent; + parent = (p_hole_idx - 1) / 2; + } + p_array[p_first + p_hole_idx] = p_value; + } + + inline void pop_heap(int p_first, int p_last, int p_result, T p_value, T *p_array) const { + + p_array[p_result] = p_array[p_first]; + adjust_heap(p_first, 0, p_last - p_first, p_value, p_array); + } + inline void pop_heap(int p_first, int p_last, T *p_array) const { + + pop_heap(p_first, p_last - 1, p_last - 1, p_array[p_last - 1], p_array); + } + + inline void adjust_heap(int p_first, int p_hole_idx, int p_len, T p_value, T *p_array) const { + + int top_index = p_hole_idx; + int second_child = 2 * p_hole_idx + 2; + + while (second_child < p_len) { + + if (compare(p_array[p_first + second_child], p_array[p_first + (second_child - 1)])) + second_child--; + + p_array[p_first + p_hole_idx] = p_array[p_first + second_child]; + p_hole_idx = second_child; + second_child = 2 * (second_child + 1); + } + + if (second_child == p_len) { + p_array[p_first + p_hole_idx] = p_array[p_first + (second_child - 1)]; + p_hole_idx = second_child - 1; + } + push_heap(p_first, p_hole_idx, top_index, p_value, p_array); + } + + inline void sort_heap(int p_first, int p_last, T *p_array) const { + + while (p_last - p_first > 1) { + + pop_heap(p_first, p_last--, p_array); + } + } + + inline void make_heap(int p_first, int p_last, T *p_array) const { + if (p_last - p_first < 2) + return; + int len = p_last - p_first; + int parent = (len - 2) / 2; + + while (true) { + adjust_heap(p_first, parent, len, p_array[p_first + parent], p_array); + if (parent == 0) + return; + parent--; + } + } + + inline void partial_sort(int p_first, int p_last, int p_middle, T *p_array) const { + + make_heap(p_first, p_middle, p_array); + for (int i = p_middle; i < p_last; i++) + if (compare(p_array[i], p_array[p_first])) + pop_heap(p_first, p_middle, i, p_array[i], p_array); + sort_heap(p_first, p_middle, p_array); + } + + inline void partial_select(int p_first, int p_last, int p_middle, T *p_array) const { + + make_heap(p_first, p_middle, p_array); + for (int i = p_middle; i < p_last; i++) + if (compare(p_array[i], p_array[p_first])) + pop_heap(p_first, p_middle, i, p_array[i], p_array); + } + + inline int partitioner(int p_first, int p_last, T p_pivot, T *p_array) const { + + const int unmodified_first = p_first; + const int unmodified_last = p_last; + + while (true) { + while (compare(p_array[p_first], p_pivot)) { + if (Validate) { + ERR_BAD_COMPARE(p_first == unmodified_last - 1) + } + p_first++; + } + p_last--; + while (compare(p_pivot, p_array[p_last])) { + if (Validate) { + ERR_BAD_COMPARE(p_last == unmodified_first) + } + p_last--; + } + + if (!(p_first < p_last)) + return p_first; + + SWAP(p_array[p_first], p_array[p_last]); + p_first++; + } + } + + inline void introsort(int p_first, int p_last, T *p_array, int p_max_depth) const { + + while (p_last - p_first > INTROSORT_THRESHOLD) { + + if (p_max_depth == 0) { + partial_sort(p_first, p_last, p_last, p_array); + return; + } + + p_max_depth--; + + int cut = partitioner( + p_first, + p_last, + median_of_3( + p_array[p_first], + p_array[p_first + (p_last - p_first) / 2], + p_array[p_last - 1]), + p_array); + + introsort(cut, p_last, p_array, p_max_depth); + p_last = cut; + } + } + + inline void introselect(int p_first, int p_nth, int p_last, T *p_array, int p_max_depth) const { + + while (p_last - p_first > 3) { + + if (p_max_depth == 0) { + partial_select(p_first, p_nth + 1, p_last, p_array); + SWAP(p_first, p_nth); + return; + } + + p_max_depth--; + + int cut = partitioner( + p_first, + p_last, + median_of_3( + p_array[p_first], + p_array[p_first + (p_last - p_first) / 2], + p_array[p_last - 1]), + p_array); + + if (cut <= p_nth) + p_first = cut; + else + p_last = cut; + } + + insertion_sort(p_first, p_last, p_array); + } + + inline void unguarded_linear_insert(int p_last, T p_value, T *p_array) const { + + int next = p_last - 1; + while (compare(p_value, p_array[next])) { + if (Validate) { + ERR_BAD_COMPARE(next == 0) + } + p_array[p_last] = p_array[next]; + p_last = next; + next--; + } + p_array[p_last] = p_value; + } + + inline void linear_insert(int p_first, int p_last, T *p_array) const { + + T val = p_array[p_last]; + if (compare(val, p_array[p_first])) { + + for (int i = p_last; i > p_first; i--) + p_array[i] = p_array[i - 1]; + + p_array[p_first] = val; + } else + unguarded_linear_insert(p_last, val, p_array); + } + + inline void insertion_sort(int p_first, int p_last, T *p_array) const { + + if (p_first == p_last) + return; + for (int i = p_first + 1; i != p_last; i++) + linear_insert(p_first, i, p_array); + } + + inline void unguarded_insertion_sort(int p_first, int p_last, T *p_array) const { + + for (int i = p_first; i != p_last; i++) + unguarded_linear_insert(i, p_array[i], p_array); + } + + inline void final_insertion_sort(int p_first, int p_last, T *p_array) const { + + if (p_last - p_first > INTROSORT_THRESHOLD) { + insertion_sort(p_first, p_first + INTROSORT_THRESHOLD, p_array); + unguarded_insertion_sort(p_first + INTROSORT_THRESHOLD, p_last, p_array); + } else { + + insertion_sort(p_first, p_last, p_array); + } + } + + inline void sort_range(int p_first, int p_last, T *p_array) const { + + if (p_first != p_last) { + introsort(p_first, p_last, p_array, bitlog(p_last - p_first) * 2); + final_insertion_sort(p_first, p_last, p_array); + } + } + + inline void sort(T *p_array, int p_len) const { + + sort_range(0, p_len, p_array); + } + + inline void nth_element(int p_first, int p_last, int p_nth, T *p_array) const { + + if (p_first == p_last || p_nth == p_last) + return; + introselect(p_first, p_nth, p_last, p_array, bitlog(p_last - p_first) * 2); + } +}; + +#endif // SORT_ARRAY_H diff --git a/core/string_db.cpp b/core/string_db.cpp deleted file mode 100644 index c776c56023..0000000000 --- a/core/string_db.cpp +++ /dev/null @@ -1,426 +0,0 @@ -/*************************************************************************/ -/* string_db.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "string_db.h" - -#include "core/os/os.h" -#include "core/print_string.h" - -StaticCString StaticCString::create(const char *p_ptr) { - StaticCString scs; - scs.ptr = p_ptr; - return scs; -} - -StringName::_Data *StringName::_table[STRING_TABLE_LEN]; - -StringName _scs_create(const char *p_chr) { - - return (p_chr[0] ? StringName(StaticCString::create(p_chr)) : StringName()); -} - -bool StringName::configured = false; -Mutex *StringName::lock = NULL; - -void StringName::setup() { - - lock = Mutex::create(); - - ERR_FAIL_COND(configured); - for (int i = 0; i < STRING_TABLE_LEN; i++) { - - _table[i] = NULL; - } - configured = true; -} - -void StringName::cleanup() { - - lock->lock(); - - int lost_strings = 0; - for (int i = 0; i < STRING_TABLE_LEN; i++) { - - while (_table[i]) { - - _Data *d = _table[i]; - lost_strings++; - if (OS::get_singleton()->is_stdout_verbose()) { - if (d->cname) { - print_line("Orphan StringName: " + String(d->cname)); - } else { - print_line("Orphan StringName: " + String(d->name)); - } - } - - _table[i] = _table[i]->next; - memdelete(d); - } - } - if (lost_strings) { - print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit."); - } - lock->unlock(); - - memdelete(lock); -} - -void StringName::unref() { - - ERR_FAIL_COND(!configured); - - if (_data && _data->refcount.unref()) { - - lock->lock(); - - if (_data->prev) { - _data->prev->next = _data->next; - } else { - if (_table[_data->idx] != _data) { - ERR_PRINT("BUG!"); - } - _table[_data->idx] = _data->next; - } - - if (_data->next) { - _data->next->prev = _data->prev; - } - memdelete(_data); - lock->unlock(); - } - - _data = NULL; -} - -bool StringName::operator==(const String &p_name) const { - - if (!_data) { - - return (p_name.length() == 0); - } - - return (_data->get_name() == p_name); -} - -bool StringName::operator==(const char *p_name) const { - - if (!_data) { - - return (p_name[0] == 0); - } - - return (_data->get_name() == p_name); -} - -bool StringName::operator!=(const String &p_name) const { - - return !(operator==(p_name)); -} - -bool StringName::operator!=(const StringName &p_name) const { - - // the real magic of all this mess happens here. - // this is why path comparisons are very fast - return _data != p_name._data; -} - -void StringName::operator=(const StringName &p_name) { - - if (this == &p_name) - return; - - unref(); - - if (p_name._data && p_name._data->refcount.ref()) { - - _data = p_name._data; - } -} - -StringName::StringName(const StringName &p_name) { - - _data = NULL; - - ERR_FAIL_COND(!configured); - - if (p_name._data && p_name._data->refcount.ref()) { - _data = p_name._data; - } -} - -StringName::StringName(const char *p_name) { - - _data = NULL; - - ERR_FAIL_COND(!configured); - - if (!p_name || p_name[0] == 0) - return; //empty, ignore - - lock->lock(); - - uint32_t hash = String::hash(p_name); - - uint32_t idx = hash & STRING_TABLE_MASK; - - _data = _table[idx]; - - while (_data) { - - // compare hash first - if (_data->hash == hash && _data->get_name() == p_name) - break; - _data = _data->next; - } - - if (_data) { - if (_data->refcount.ref()) { - // exists - lock->unlock(); - return; - } else { - } - } - - _data = memnew(_Data); - _data->name = p_name; - _data->refcount.init(); - _data->hash = hash; - _data->idx = idx; - _data->cname = NULL; - _data->next = _table[idx]; - _data->prev = NULL; - if (_table[idx]) - _table[idx]->prev = _data; - _table[idx] = _data; - - lock->unlock(); -} - -StringName::StringName(const StaticCString &p_static_string) { - - _data = NULL; - - ERR_FAIL_COND(!configured); - - ERR_FAIL_COND(!p_static_string.ptr || !p_static_string.ptr[0]); - - lock->lock(); - - uint32_t hash = String::hash(p_static_string.ptr); - - uint32_t idx = hash & STRING_TABLE_MASK; - - _data = _table[idx]; - - while (_data) { - - // compare hash first - if (_data->hash == hash && _data->get_name() == p_static_string.ptr) - break; - _data = _data->next; - } - - if (_data) { - if (_data->refcount.ref()) { - // exists - lock->unlock(); - return; - } else { - } - } - - _data = memnew(_Data); - - _data->refcount.init(); - _data->hash = hash; - _data->idx = idx; - _data->cname = p_static_string.ptr; - _data->next = _table[idx]; - _data->prev = NULL; - if (_table[idx]) - _table[idx]->prev = _data; - _table[idx] = _data; - - lock->unlock(); -} - -StringName::StringName(const String &p_name) { - - _data = NULL; - - ERR_FAIL_COND(!configured); - - if (p_name == String()) - return; - - lock->lock(); - - uint32_t hash = p_name.hash(); - - uint32_t idx = hash & STRING_TABLE_MASK; - - _data = _table[idx]; - - while (_data) { - - if (_data->hash == hash && _data->get_name() == p_name) - break; - _data = _data->next; - } - - if (_data) { - if (_data->refcount.ref()) { - // exists - lock->unlock(); - return; - } else { - } - } - - _data = memnew(_Data); - _data->name = p_name; - _data->refcount.init(); - _data->hash = hash; - _data->idx = idx; - _data->cname = NULL; - _data->next = _table[idx]; - _data->prev = NULL; - if (_table[idx]) - _table[idx]->prev = _data; - _table[idx] = _data; - - lock->unlock(); -} - -StringName StringName::search(const char *p_name) { - - ERR_FAIL_COND_V(!configured, StringName()); - - ERR_FAIL_COND_V(!p_name, StringName()); - if (!p_name[0]) - return StringName(); - - lock->lock(); - - uint32_t hash = String::hash(p_name); - - uint32_t idx = hash & STRING_TABLE_MASK; - - _Data *_data = _table[idx]; - - while (_data) { - - // compare hash first - if (_data->hash == hash && _data->get_name() == p_name) - break; - _data = _data->next; - } - - if (_data && _data->refcount.ref()) { - lock->unlock(); - - return StringName(_data); - } - - lock->unlock(); - return StringName(); //does not exist -} - -StringName StringName::search(const CharType *p_name) { - - ERR_FAIL_COND_V(!configured, StringName()); - - ERR_FAIL_COND_V(!p_name, StringName()); - if (!p_name[0]) - return StringName(); - - lock->lock(); - - uint32_t hash = String::hash(p_name); - - uint32_t idx = hash & STRING_TABLE_MASK; - - _Data *_data = _table[idx]; - - while (_data) { - - // compare hash first - if (_data->hash == hash && _data->get_name() == p_name) - break; - _data = _data->next; - } - - if (_data && _data->refcount.ref()) { - lock->unlock(); - return StringName(_data); - } - - lock->unlock(); - return StringName(); //does not exist -} -StringName StringName::search(const String &p_name) { - - ERR_FAIL_COND_V(p_name == "", StringName()); - - lock->lock(); - - uint32_t hash = p_name.hash(); - - uint32_t idx = hash & STRING_TABLE_MASK; - - _Data *_data = _table[idx]; - - while (_data) { - - // compare hash first - if (_data->hash == hash && p_name == _data->get_name()) - break; - _data = _data->next; - } - - if (_data && _data->refcount.ref()) { - lock->unlock(); - return StringName(_data); - } - - lock->unlock(); - return StringName(); //does not exist -} - -StringName::StringName() { - - _data = NULL; -} - -StringName::~StringName() { - - unref(); -} diff --git a/core/string_db.h b/core/string_db.h deleted file mode 100644 index 06b24c28da..0000000000 --- a/core/string_db.h +++ /dev/null @@ -1,172 +0,0 @@ -/*************************************************************************/ -/* string_db.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef STRING_DB_H -#define STRING_DB_H - -#include "core/os/mutex.h" -#include "core/safe_refcount.h" -#include "core/ustring.h" -/** - @author Juan Linietsky -*/ - -struct StaticCString { - - const char *ptr; - static StaticCString create(const char *p_ptr); -}; - -class StringName { - - enum { - - STRING_TABLE_BITS = 12, - STRING_TABLE_LEN = 1 << STRING_TABLE_BITS, - STRING_TABLE_MASK = STRING_TABLE_LEN - 1 - }; - - struct _Data { - SafeRefCount refcount; - const char *cname; - String name; - - String get_name() const { return cname ? String(cname) : name; } - int idx; - uint32_t hash; - _Data *prev; - _Data *next; - _Data() { - cname = NULL; - next = prev = NULL; - idx = 0; - hash = 0; - } - }; - - static _Data *_table[STRING_TABLE_LEN]; - - _Data *_data; - - union _HashUnion { - - _Data *ptr; - uint32_t hash; - }; - - void unref(); - friend void register_core_types(); - friend void unregister_core_types(); - - static Mutex *lock; - static void setup(); - static void cleanup(); - static bool configured; - - StringName(_Data *p_data) { _data = p_data; } - -public: - operator const void *() const { return (_data && (_data->cname || !_data->name.empty())) ? (void *)1 : 0; } - - bool operator==(const String &p_name) const; - bool operator==(const char *p_name) const; - bool operator!=(const String &p_name) const; - _FORCE_INLINE_ bool operator<(const StringName &p_name) const { - - return _data < p_name._data; - } - _FORCE_INLINE_ bool operator==(const StringName &p_name) const { - // the real magic of all this mess happens here. - // this is why path comparisons are very fast - return _data == p_name._data; - } - _FORCE_INLINE_ uint32_t hash() const { - - if (_data) - return _data->hash; - else - return 0; - } - _FORCE_INLINE_ const void *data_unique_pointer() const { - return (void *)_data; - } - bool operator!=(const StringName &p_name) const; - - _FORCE_INLINE_ operator String() const { - - if (_data) { - if (_data->cname) - return String(_data->cname); - else - return _data->name; - } - - return String(); - } - - static StringName search(const char *p_name); - static StringName search(const CharType *p_name); - static StringName search(const String &p_name); - - struct AlphCompare { - - _FORCE_INLINE_ bool operator()(const StringName &l, const StringName &r) const { - - const char *l_cname = l._data ? l._data->cname : ""; - const char *r_cname = r._data ? r._data->cname : ""; - - if (l_cname) { - - if (r_cname) - return is_str_less(l_cname, r_cname); - else - return is_str_less(l_cname, r._data->name.ptr()); - } else { - - if (r_cname) - return is_str_less(l._data->name.ptr(), r_cname); - else - return is_str_less(l._data->name.ptr(), r._data->name.ptr()); - } - } - }; - - void operator=(const StringName &p_name); - StringName(const char *p_name); - StringName(const StringName &p_name); - StringName(const String &p_name); - StringName(const StaticCString &p_static_string); - StringName(); - ~StringName(); -}; - -StringName _scs_create(const char *p_chr); - -#endif diff --git a/core/string_name.cpp b/core/string_name.cpp new file mode 100644 index 0000000000..10b71ad3ac --- /dev/null +++ b/core/string_name.cpp @@ -0,0 +1,426 @@ +/*************************************************************************/ +/* string_name.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "string_name.h" + +#include "core/os/os.h" +#include "core/print_string.h" + +StaticCString StaticCString::create(const char *p_ptr) { + StaticCString scs; + scs.ptr = p_ptr; + return scs; +} + +StringName::_Data *StringName::_table[STRING_TABLE_LEN]; + +StringName _scs_create(const char *p_chr) { + + return (p_chr[0] ? StringName(StaticCString::create(p_chr)) : StringName()); +} + +bool StringName::configured = false; +Mutex *StringName::lock = NULL; + +void StringName::setup() { + + lock = Mutex::create(); + + ERR_FAIL_COND(configured); + for (int i = 0; i < STRING_TABLE_LEN; i++) { + + _table[i] = NULL; + } + configured = true; +} + +void StringName::cleanup() { + + lock->lock(); + + int lost_strings = 0; + for (int i = 0; i < STRING_TABLE_LEN; i++) { + + while (_table[i]) { + + _Data *d = _table[i]; + lost_strings++; + if (OS::get_singleton()->is_stdout_verbose()) { + if (d->cname) { + print_line("Orphan StringName: " + String(d->cname)); + } else { + print_line("Orphan StringName: " + String(d->name)); + } + } + + _table[i] = _table[i]->next; + memdelete(d); + } + } + if (lost_strings) { + print_verbose("StringName: " + itos(lost_strings) + " unclaimed string names at exit."); + } + lock->unlock(); + + memdelete(lock); +} + +void StringName::unref() { + + ERR_FAIL_COND(!configured); + + if (_data && _data->refcount.unref()) { + + lock->lock(); + + if (_data->prev) { + _data->prev->next = _data->next; + } else { + if (_table[_data->idx] != _data) { + ERR_PRINT("BUG!"); + } + _table[_data->idx] = _data->next; + } + + if (_data->next) { + _data->next->prev = _data->prev; + } + memdelete(_data); + lock->unlock(); + } + + _data = NULL; +} + +bool StringName::operator==(const String &p_name) const { + + if (!_data) { + + return (p_name.length() == 0); + } + + return (_data->get_name() == p_name); +} + +bool StringName::operator==(const char *p_name) const { + + if (!_data) { + + return (p_name[0] == 0); + } + + return (_data->get_name() == p_name); +} + +bool StringName::operator!=(const String &p_name) const { + + return !(operator==(p_name)); +} + +bool StringName::operator!=(const StringName &p_name) const { + + // the real magic of all this mess happens here. + // this is why path comparisons are very fast + return _data != p_name._data; +} + +void StringName::operator=(const StringName &p_name) { + + if (this == &p_name) + return; + + unref(); + + if (p_name._data && p_name._data->refcount.ref()) { + + _data = p_name._data; + } +} + +StringName::StringName(const StringName &p_name) { + + _data = NULL; + + ERR_FAIL_COND(!configured); + + if (p_name._data && p_name._data->refcount.ref()) { + _data = p_name._data; + } +} + +StringName::StringName(const char *p_name) { + + _data = NULL; + + ERR_FAIL_COND(!configured); + + if (!p_name || p_name[0] == 0) + return; //empty, ignore + + lock->lock(); + + uint32_t hash = String::hash(p_name); + + uint32_t idx = hash & STRING_TABLE_MASK; + + _data = _table[idx]; + + while (_data) { + + // compare hash first + if (_data->hash == hash && _data->get_name() == p_name) + break; + _data = _data->next; + } + + if (_data) { + if (_data->refcount.ref()) { + // exists + lock->unlock(); + return; + } else { + } + } + + _data = memnew(_Data); + _data->name = p_name; + _data->refcount.init(); + _data->hash = hash; + _data->idx = idx; + _data->cname = NULL; + _data->next = _table[idx]; + _data->prev = NULL; + if (_table[idx]) + _table[idx]->prev = _data; + _table[idx] = _data; + + lock->unlock(); +} + +StringName::StringName(const StaticCString &p_static_string) { + + _data = NULL; + + ERR_FAIL_COND(!configured); + + ERR_FAIL_COND(!p_static_string.ptr || !p_static_string.ptr[0]); + + lock->lock(); + + uint32_t hash = String::hash(p_static_string.ptr); + + uint32_t idx = hash & STRING_TABLE_MASK; + + _data = _table[idx]; + + while (_data) { + + // compare hash first + if (_data->hash == hash && _data->get_name() == p_static_string.ptr) + break; + _data = _data->next; + } + + if (_data) { + if (_data->refcount.ref()) { + // exists + lock->unlock(); + return; + } else { + } + } + + _data = memnew(_Data); + + _data->refcount.init(); + _data->hash = hash; + _data->idx = idx; + _data->cname = p_static_string.ptr; + _data->next = _table[idx]; + _data->prev = NULL; + if (_table[idx]) + _table[idx]->prev = _data; + _table[idx] = _data; + + lock->unlock(); +} + +StringName::StringName(const String &p_name) { + + _data = NULL; + + ERR_FAIL_COND(!configured); + + if (p_name == String()) + return; + + lock->lock(); + + uint32_t hash = p_name.hash(); + + uint32_t idx = hash & STRING_TABLE_MASK; + + _data = _table[idx]; + + while (_data) { + + if (_data->hash == hash && _data->get_name() == p_name) + break; + _data = _data->next; + } + + if (_data) { + if (_data->refcount.ref()) { + // exists + lock->unlock(); + return; + } else { + } + } + + _data = memnew(_Data); + _data->name = p_name; + _data->refcount.init(); + _data->hash = hash; + _data->idx = idx; + _data->cname = NULL; + _data->next = _table[idx]; + _data->prev = NULL; + if (_table[idx]) + _table[idx]->prev = _data; + _table[idx] = _data; + + lock->unlock(); +} + +StringName StringName::search(const char *p_name) { + + ERR_FAIL_COND_V(!configured, StringName()); + + ERR_FAIL_COND_V(!p_name, StringName()); + if (!p_name[0]) + return StringName(); + + lock->lock(); + + uint32_t hash = String::hash(p_name); + + uint32_t idx = hash & STRING_TABLE_MASK; + + _Data *_data = _table[idx]; + + while (_data) { + + // compare hash first + if (_data->hash == hash && _data->get_name() == p_name) + break; + _data = _data->next; + } + + if (_data && _data->refcount.ref()) { + lock->unlock(); + + return StringName(_data); + } + + lock->unlock(); + return StringName(); //does not exist +} + +StringName StringName::search(const CharType *p_name) { + + ERR_FAIL_COND_V(!configured, StringName()); + + ERR_FAIL_COND_V(!p_name, StringName()); + if (!p_name[0]) + return StringName(); + + lock->lock(); + + uint32_t hash = String::hash(p_name); + + uint32_t idx = hash & STRING_TABLE_MASK; + + _Data *_data = _table[idx]; + + while (_data) { + + // compare hash first + if (_data->hash == hash && _data->get_name() == p_name) + break; + _data = _data->next; + } + + if (_data && _data->refcount.ref()) { + lock->unlock(); + return StringName(_data); + } + + lock->unlock(); + return StringName(); //does not exist +} +StringName StringName::search(const String &p_name) { + + ERR_FAIL_COND_V(p_name == "", StringName()); + + lock->lock(); + + uint32_t hash = p_name.hash(); + + uint32_t idx = hash & STRING_TABLE_MASK; + + _Data *_data = _table[idx]; + + while (_data) { + + // compare hash first + if (_data->hash == hash && p_name == _data->get_name()) + break; + _data = _data->next; + } + + if (_data && _data->refcount.ref()) { + lock->unlock(); + return StringName(_data); + } + + lock->unlock(); + return StringName(); //does not exist +} + +StringName::StringName() { + + _data = NULL; +} + +StringName::~StringName() { + + unref(); +} diff --git a/core/string_name.h b/core/string_name.h new file mode 100644 index 0000000000..0984b0181f --- /dev/null +++ b/core/string_name.h @@ -0,0 +1,172 @@ +/*************************************************************************/ +/* string_name.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef STRING_NAME_H +#define STRING_NAME_H + +#include "core/os/mutex.h" +#include "core/safe_refcount.h" +#include "core/ustring.h" +/** + @author Juan Linietsky +*/ + +struct StaticCString { + + const char *ptr; + static StaticCString create(const char *p_ptr); +}; + +class StringName { + + enum { + + STRING_TABLE_BITS = 12, + STRING_TABLE_LEN = 1 << STRING_TABLE_BITS, + STRING_TABLE_MASK = STRING_TABLE_LEN - 1 + }; + + struct _Data { + SafeRefCount refcount; + const char *cname; + String name; + + String get_name() const { return cname ? String(cname) : name; } + int idx; + uint32_t hash; + _Data *prev; + _Data *next; + _Data() { + cname = NULL; + next = prev = NULL; + idx = 0; + hash = 0; + } + }; + + static _Data *_table[STRING_TABLE_LEN]; + + _Data *_data; + + union _HashUnion { + + _Data *ptr; + uint32_t hash; + }; + + void unref(); + friend void register_core_types(); + friend void unregister_core_types(); + + static Mutex *lock; + static void setup(); + static void cleanup(); + static bool configured; + + StringName(_Data *p_data) { _data = p_data; } + +public: + operator const void *() const { return (_data && (_data->cname || !_data->name.empty())) ? (void *)1 : 0; } + + bool operator==(const String &p_name) const; + bool operator==(const char *p_name) const; + bool operator!=(const String &p_name) const; + _FORCE_INLINE_ bool operator<(const StringName &p_name) const { + + return _data < p_name._data; + } + _FORCE_INLINE_ bool operator==(const StringName &p_name) const { + // the real magic of all this mess happens here. + // this is why path comparisons are very fast + return _data == p_name._data; + } + _FORCE_INLINE_ uint32_t hash() const { + + if (_data) + return _data->hash; + else + return 0; + } + _FORCE_INLINE_ const void *data_unique_pointer() const { + return (void *)_data; + } + bool operator!=(const StringName &p_name) const; + + _FORCE_INLINE_ operator String() const { + + if (_data) { + if (_data->cname) + return String(_data->cname); + else + return _data->name; + } + + return String(); + } + + static StringName search(const char *p_name); + static StringName search(const CharType *p_name); + static StringName search(const String &p_name); + + struct AlphCompare { + + _FORCE_INLINE_ bool operator()(const StringName &l, const StringName &r) const { + + const char *l_cname = l._data ? l._data->cname : ""; + const char *r_cname = r._data ? r._data->cname : ""; + + if (l_cname) { + + if (r_cname) + return is_str_less(l_cname, r_cname); + else + return is_str_less(l_cname, r._data->name.ptr()); + } else { + + if (r_cname) + return is_str_less(l._data->name.ptr(), r_cname); + else + return is_str_less(l._data->name.ptr(), r._data->name.ptr()); + } + } + }; + + void operator=(const StringName &p_name); + StringName(const char *p_name); + StringName(const StringName &p_name); + StringName(const String &p_name); + StringName(const StaticCString &p_static_string); + StringName(); + ~StringName(); +}; + +StringName _scs_create(const char *p_chr); + +#endif // STRING_NAME_H diff --git a/core/variant.h b/core/variant.h index 6ddaf17406..a819ba1f8c 100644 --- a/core/variant.h +++ b/core/variant.h @@ -38,7 +38,6 @@ #include "core/array.h" #include "core/color.h" #include "core/dictionary.h" -#include "core/dvector.h" #include "core/io/ip_address.h" #include "core/math/aabb.h" #include "core/math/basis.h" @@ -49,6 +48,7 @@ #include "core/math/transform_2d.h" #include "core/math/vector3.h" #include "core/node_path.h" +#include "core/pool_vector.h" #include "core/ref_ptr.h" #include "core/rid.h" #include "core/ustring.h" diff --git a/core/variant_construct_string.cpp b/core/variant_construct_string.cpp deleted file mode 100644 index 2cb7481634..0000000000 --- a/core/variant_construct_string.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/*************************************************************************/ -/* variant_construct_string.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "variant.h" - -class VariantConstruct { - - enum TokenType { - TK_CURLY_BRACKET_OPEN, - TK_CURLY_BRACKET_CLOSE, - TK_BRACKET_OPEN, - TK_BRACKET_CLOSE, - TK_IDENTIFIER, - TK_STRING, - TK_NUMBER, - TK_COLON, - TK_COMMA, - TK_EOF, - TK_MAX - }; - - enum Expecting { - - EXPECT_OBJECT, - EXPECT_OBJECT_KEY, - EXPECT_COLON, - EXPECT_OBJECT_VALUE, - }; - - struct Token { - - TokenType type; - Variant value; - }; - - static const char *tk_name[TK_MAX]; - - static String _print_var(const Variant &p_var); - - static Error _get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str); - static Error _parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud); - static Error _parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud); - static Error _parse_dict(Dictionary &dict, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud); - -public: - static Error parse(const String &p_string, Variant &r_ret, String &r_err_str, int &r_err_line, Variant::ObjectConstruct *p_construct, void *p_ud); -}; - -const char *VariantConstruct::tk_name[TK_MAX] = { - "'{'", - "'}'", - "'['", - "']'", - "identifier", - "string", - "number", - "':'", - "','", - "EOF", -}; - -Error VariantConstruct::_get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str) { - - while (true) { - switch (p_str[index]) { - - case '\n': { - - line++; - index++; - break; - }; - case 0: { - r_token.type = TK_EOF; - return OK; - } break; - case '{': { - - r_token.type = TK_CURLY_BRACKET_OPEN; - index++; - return OK; - }; - case '}': { - - r_token.type = TK_CURLY_BRACKET_CLOSE; - index++; - return OK; - }; - case '[': { - - r_token.type = TK_BRACKET_OPEN; - index++; - return OK; - }; - case ']': { - - r_token.type = TK_BRACKET_CLOSE; - index++; - return OK; - }; - case ':': { - - r_token.type = TK_COLON; - index++; - return OK; - }; - case ',': { - - r_token.type = TK_COMMA; - index++; - return OK; - }; - case '"': { - - index++; - String str; - while (true) { - if (p_str[index] == 0) { - r_err_str = "Unterminated String"; - return ERR_PARSE_ERROR; - } else if (p_str[index] == '"') { - index++; - break; - } else if (p_str[index] == '\\') { - //escaped characters... - index++; - CharType next = p_str[index]; - if (next == 0) { - r_err_str = "Unterminated String"; - return ERR_PARSE_ERROR; - } - CharType res = 0; - - switch (next) { - - case 'b': res = 8; break; - case 't': res = 9; break; - case 'n': res = 10; break; - case 'f': res = 12; break; - case 'r': res = 13; break; - case '\"': res = '\"'; break; - case '\\': res = '\\'; break; - case '/': res = '/'; break; - case 'u': { - //hexnumbarh - oct is deprecated - - for (int j = 0; j < 4; j++) { - CharType c = p_str[index + j + 1]; - if (c == 0) { - r_err_str = "Unterminated String"; - return ERR_PARSE_ERROR; - } - if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) { - - r_err_str = "Malformed hex constant in string"; - return ERR_PARSE_ERROR; - } - CharType v; - if (c >= '0' && c <= '9') { - v = c - '0'; - } else if (c >= 'a' && c <= 'f') { - v = c - 'a'; - v += 10; - } else if (c >= 'A' && c <= 'F') { - v = c - 'A'; - v += 10; - } else { - ERR_PRINT("BUG"); - v = 0; - } - - res <<= 4; - res |= v; - } - index += 4; //will add at the end anyway - - } break; - default: { - - r_err_str = "Invalid escape sequence"; - return ERR_PARSE_ERROR; - } break; - } - - str += res; - - } else { - if (p_str[index] == '\n') - line++; - str += p_str[index]; - } - index++; - } - - r_token.type = TK_STRING; - r_token.value = str; - return OK; - - } break; - default: { - - if (p_str[index] <= 32) { - index++; - break; - } - - if (p_str[index] == '-' || (p_str[index] >= '0' && p_str[index] <= '9')) { - //a number - const CharType *rptr; - double number = String::to_double(&p_str[index], &rptr); - index += (rptr - &p_str[index]); - r_token.type = TK_NUMBER; - r_token.value = number; - return OK; - - } else if ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) { - - String id; - - while ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) { - - id += p_str[index]; - index++; - } - - r_token.type = TK_IDENTIFIER; - r_token.value = id; - return OK; - } else { - r_err_str = "Unexpected character."; - return ERR_PARSE_ERROR; - } - } - } - } - - return ERR_PARSE_ERROR; -} - -Error VariantConstruct::_parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud) { - - if (token.type == TK_CURLY_BRACKET_OPEN) { - - Dictionary d; - Error err = _parse_dict(d, p_str, index, p_len, line, r_err_str, p_construct, p_ud); - if (err) - return err; - value = d; - return OK; - } else if (token.type == TK_BRACKET_OPEN) { - - Array a; - Error err = _parse_array(a, p_str, index, p_len, line, r_err_str, p_construct, p_ud); - if (err) - return err; - value = a; - return OK; - - } else if (token.type == TK_IDENTIFIER) { - - String id = token.value; - if (id == "true") - value = true; - else if (id == "false") - value = false; - else if (id == "null") - value = Variant(); - else { - r_err_str = "Expected 'true','false' or 'null', got '" + id + "'."; - return ERR_PARSE_ERROR; - } - return OK; - - } else if (token.type == TK_NUMBER) { - - value = token.value; - return OK; - } else if (token.type == TK_STRING) { - - value = token.value; - return OK; - } else { - r_err_str = "Expected value, got " + String(tk_name[token.type]) + "."; - return ERR_PARSE_ERROR; - } - - return ERR_PARSE_ERROR; -} - -Error VariantConstruct::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud) { - - Token token; - bool need_comma = false; - - while (index < p_len) { - - Error err = _get_token(p_str, index, p_len, token, line, r_err_str); - if (err != OK) - return err; - - if (token.type == TK_BRACKET_CLOSE) { - - return OK; - } - - if (need_comma) { - - if (token.type != TK_COMMA) { - - r_err_str = "Expected ','"; - return ERR_PARSE_ERROR; - } else { - need_comma = false; - continue; - } - } - - Variant v; - err = _parse_value(v, token, p_str, index, p_len, line, r_err_str, p_construct, p_ud); - if (err) - return err; - - array.push_back(v); - need_comma = true; - } - - return OK; -} - -Error VariantConstruct::_parse_dict(Dictionary &dict, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str, Variant::ObjectConstruct *p_construct, void *p_ud) { - - bool at_key = true; - Variant key; - Token token; - bool need_comma = false; - - while (index < p_len) { - - if (at_key) { - - Error err = _get_token(p_str, index, p_len, token, line, r_err_str); - if (err != OK) - return err; - - if (token.type == TK_CURLY_BRACKET_CLOSE) { - - return OK; - } - - if (need_comma) { - - if (token.type != TK_COMMA) { - - r_err_str = "Expected '}' or ','"; - return ERR_PARSE_ERROR; - } else { - need_comma = false; - continue; - } - } - - err = _parse_value(key, token, p_str, index, p_len, line, r_err_str, p_construct, p_ud); - - if (err != OK) - return err; - - err = _get_token(p_str, index, p_len, token, line, r_err_str); - - if (err != OK) - return err; - - if (token.type != TK_COLON) { - - r_err_str = "Expected ':'"; - return ERR_PARSE_ERROR; - } - at_key = false; - } else { - - Error err = _get_token(p_str, index, p_len, token, line, r_err_str); - if (err != OK) - return err; - - Variant v; - err = _parse_value(v, token, p_str, index, p_len, line, r_err_str, p_construct, p_ud); - if (err) - return err; - dict[key] = v; - need_comma = true; - at_key = true; - } - } - - return OK; -} - -Error VariantConstruct::parse(const String &p_string, Variant &r_ret, String &r_err_str, int &r_err_line, Variant::ObjectConstruct *p_construct, void *p_ud) { - - const CharType *str = p_string.ptr(); - int idx = 0; - int len = p_string.length(); - Token token; - r_err_line = 0; - String aux_key; - - Error err = _get_token(str, idx, len, token, r_err_line, r_err_str); - if (err) - return err; - - return _parse_value(r_ret, token, str, idx, len, r_err_line, r_err_str, p_construct, p_ud); -} diff --git a/core/vector.h b/core/vector.h index 90b3d90826..93ee003519 100644 --- a/core/vector.h +++ b/core/vector.h @@ -40,7 +40,7 @@ #include "core/cowdata.h" #include "core/error_macros.h" #include "core/os/memory.h" -#include "core/sort.h" +#include "core/sort_array.h" template class VectorWriteProxy { diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h index ba48ddd185..a0fa2aacc5 100644 --- a/drivers/gles2/rasterizer_storage_gles2.h +++ b/drivers/gles2/rasterizer_storage_gles2.h @@ -31,7 +31,7 @@ #ifndef RASTERIZERSTORAGEGLES2_H #define RASTERIZERSTORAGEGLES2_H -#include "core/dvector.h" +#include "core/pool_vector.h" #include "core/self_list.h" #include "servers/visual/rasterizer.h" #include "servers/visual/shader_language.h" diff --git a/drivers/windows/shell_windows.cpp b/drivers/windows/shell_windows.cpp deleted file mode 100644 index 731d16d18d..0000000000 --- a/drivers/windows/shell_windows.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************/ -/* shell_windows.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifdef WINDOWS_ENABLED - -#ifdef UWP_ENABLED - -// Use Launcher class on windows 8 - -#else - -// -// C++ Implementation: shell_windows -// -// Description: -// -// -// Author: Juan Linietsky , (C) 2008 -// -// Copyright: See COPYING file that comes with this distribution -// -// -#include "shell_windows.h" - -#include - -void ShellWindows::execute(String p_path) { - - ShellExecuteW(NULL, L"open", p_path.c_str(), NULL, NULL, SW_SHOWNORMAL); -} - -ShellWindows::ShellWindows() { -} - -ShellWindows::~ShellWindows() { -} - -#endif - -#endif diff --git a/drivers/windows/shell_windows.h b/drivers/windows/shell_windows.h deleted file mode 100644 index 9e9edd2f62..0000000000 --- a/drivers/windows/shell_windows.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************/ -/* shell_windows.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef SHELL_WINDOWS_H -#define SHELL_WINDOWS_H - -#include "core/os/shell.h" - -#ifdef WINDOWS_ENABLED - -/** - @author Juan Linietsky -*/ - -class ShellWindows : public Shell { -public: - virtual void execute(String p_path); - - ShellWindows(); - - ~ShellWindows(); -}; - -#endif -#endif diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index fe8d57d1a1..a262f1886c 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -30,7 +30,7 @@ #include "editor_file_system.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/os/file_access.h" diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h index 9e64fdb7c7..607d99e6e2 100644 --- a/editor/import/editor_import_plugin.h +++ b/editor/import/editor_import_plugin.h @@ -31,7 +31,7 @@ #ifndef EDITOR_IMPORT_PLUGIN_H #define EDITOR_IMPORT_PLUGIN_H -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" class EditorImportPlugin : public ResourceImporter { GDCLASS(EditorImportPlugin, Reference) diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h index b0168e2b53..7cfb0c4a98 100644 --- a/editor/import/resource_importer_bitmask.h +++ b/editor/import/resource_importer_bitmask.h @@ -32,7 +32,7 @@ #define RESOURCE_IMPORTER_BITMASK_H #include "core/image.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" class StreamBitMap; diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h index 3d74731e8c..cf16826535 100644 --- a/editor/import/resource_importer_csv_translation.h +++ b/editor/import/resource_importer_csv_translation.h @@ -31,7 +31,7 @@ #ifndef RESOURCEIMPORTERCSVTRANSLATION_H #define RESOURCEIMPORTERCSVTRANSLATION_H -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" class ResourceImporterCSVTranslation : public ResourceImporter { GDCLASS(ResourceImporterCSVTranslation, ResourceImporter) diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h index b38d833c5b..ffe05bdf58 100644 --- a/editor/import/resource_importer_image.h +++ b/editor/import/resource_importer_image.h @@ -32,7 +32,7 @@ #define RESOURCE_IMPORTER_IMAGE_H #include "core/image.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" class ResourceImporterImage : public ResourceImporter { GDCLASS(ResourceImporterImage, ResourceImporter) diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h index 599fdf12fa..6a616e09d6 100644 --- a/editor/import/resource_importer_layered_texture.h +++ b/editor/import/resource_importer_layered_texture.h @@ -32,7 +32,7 @@ #define RESOURCE_IMPORTER_LAYERED_TEXTURE_H #include "core/image.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" class StreamTexture; diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 9435b6599a..9d06b411d6 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -31,7 +31,7 @@ #ifndef RESOURCEIMPORTERSCENE_H #define RESOURCEIMPORTERSCENE_H -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" #include "scene/resources/animation.h" #include "scene/resources/mesh.h" #include "scene/resources/shape.h" diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h index 900654c114..408af1edcf 100644 --- a/editor/import/resource_importer_texture.h +++ b/editor/import/resource_importer_texture.h @@ -32,7 +32,7 @@ #define RESOURCEIMPORTTEXTURE_H #include "core/image.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" class StreamTexture; diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h index 68e677b977..755dea3d84 100644 --- a/editor/import/resource_importer_wav.h +++ b/editor/import/resource_importer_wav.h @@ -31,7 +31,7 @@ #ifndef RESOURCEIMPORTWAV_H #define RESOURCEIMPORTWAV_H -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" class ResourceImporterWAV : public ResourceImporter { GDCLASS(ResourceImporterWAV, ResourceImporter) diff --git a/editor/import_dock.h b/editor/import_dock.h index 1d43e00b63..77a34e80eb 100644 --- a/editor/import_dock.h +++ b/editor/import_dock.h @@ -32,7 +32,7 @@ #define IMPORTDOCK_H #include "core/io/config_file.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" #include "editor/editor_file_system.h" #include "editor/editor_inspector.h" #include "scene/gui/box_container.h" diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 9ece812c49..0704e57bb9 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -35,7 +35,7 @@ #include "core/os/keyboard.h" #include "core/print_string.h" #include "core/project_settings.h" -#include "core/sort.h" +#include "core/sort_array.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "editor/plugins/animation_player_editor_plugin.h" diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp index 12282b4730..a0be0138d3 100644 --- a/modules/csg/csg.cpp +++ b/modules/csg/csg.cpp @@ -32,7 +32,7 @@ #include "core/math/face3.h" #include "core/math/geometry.h" #include "core/os/os.h" -#include "core/sort.h" +#include "core/sort_array.h" #include "thirdparty/misc/triangulator.h" void CSGBrush::clear() { diff --git a/modules/csg/csg.h b/modules/csg/csg.h index ac16575e82..4fa1a945cc 100644 --- a/modules/csg/csg.h +++ b/modules/csg/csg.h @@ -31,7 +31,6 @@ #ifndef CSG_H #define CSG_H -#include "core/dvector.h" #include "core/map.h" #include "core/math/aabb.h" #include "core/math/plane.h" @@ -39,6 +38,7 @@ #include "core/math/transform.h" #include "core/math/vector3.h" #include "core/oa_hash_map.h" +#include "core/pool_vector.h" #include "scene/resources/material.h" struct CSGBrush { diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp index 18da9d811e..6849ff03d7 100644 --- a/modules/gdnative/gdnative/array.cpp +++ b/modules/gdnative/gdnative/array.cpp @@ -34,7 +34,7 @@ #include "core/os/memory.h" #include "core/color.h" -#include "core/dvector.h" +#include "core/pool_vector.h" #include "core/variant.h" diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/pool_arrays.cpp index 68e064d829..74c540ca14 100644 --- a/modules/gdnative/gdnative/pool_arrays.cpp +++ b/modules/gdnative/gdnative/pool_arrays.cpp @@ -31,7 +31,7 @@ #include "gdnative/pool_arrays.h" #include "core/array.h" -#include "core/dvector.h" +#include "core/pool_vector.h" #include "core/variant.h" #include "core/color.h" diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp index 4b8d79305c..913c57eb56 100644 --- a/modules/gdnative/gdnative/string.cpp +++ b/modules/gdnative/gdnative/string.cpp @@ -30,7 +30,7 @@ #include "gdnative/string.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/ustring.h" #include "core/variant.h" diff --git a/modules/gdnative/gdnative/string_name.cpp b/modules/gdnative/gdnative/string_name.cpp index d2862c5980..dcbb773c25 100644 --- a/modules/gdnative/gdnative/string_name.cpp +++ b/modules/gdnative/gdnative/string_name.cpp @@ -30,7 +30,7 @@ #include "gdnative/string_name.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/ustring.h" #include diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index a412b2950f..cefc28d77f 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -36,7 +36,7 @@ #include "core/reference.h" #include "core/script_language.h" #include "core/self_list.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/variant.h" class GDScriptInstance; diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h index abacdf0322..e4315f7969 100644 --- a/modules/gdscript/gdscript_tokenizer.h +++ b/modules/gdscript/gdscript_tokenizer.h @@ -32,7 +32,7 @@ #define GDSCRIPT_TOKENIZER_H #include "core/pair.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/ustring.h" #include "core/variant.h" #include "core/vmap.h" diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 2963619b79..fad02b01d3 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -33,7 +33,7 @@ #ifdef MONO_GLUE_ENABLED #include "core/reference.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "../csharp_script.h" #include "../mono_gd/gd_mono_internals.h" diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.h b/modules/stb_vorbis/resource_importer_ogg_vorbis.h index ca2d662e61..f61fc91cda 100644 --- a/modules/stb_vorbis/resource_importer_ogg_vorbis.h +++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.h @@ -32,7 +32,7 @@ #define RESOURCEIMPORTEROGGVORBIS_H #include "audio_stream_ogg_vorbis.h" -#include "core/io/resource_import.h" +#include "core/io/resource_importer.h" class ResourceImporterOGGVorbis : public ResourceImporter { GDCLASS(ResourceImporterOGGVorbis, ResourceImporter) diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h index 103b06dbc1..4d1a7f255c 100644 --- a/scene/scene_string_names.h +++ b/scene/scene_string_names.h @@ -32,7 +32,7 @@ #define SCENE_STRING_NAMES_H #include "core/node_path.h" -#include "core/string_db.h" +#include "core/string_name.h" class SceneStringNames { friend void register_scene_types(); diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp index fdc5eccc5a..d40de669fd 100644 --- a/servers/physics/shape_sw.cpp +++ b/servers/physics/shape_sw.cpp @@ -32,7 +32,7 @@ #include "core/math/geometry.h" #include "core/math/quick_hull.h" -#include "core/sort.h" +#include "core/sort_array.h" #define _POINT_SNAP 0.001953125 #define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.0002 diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index 558700f400..b622550ec9 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -31,7 +31,7 @@ #include "shape_2d_sw.h" #include "core/math/geometry.h" -#include "core/sort.h" +#include "core/sort_array.h" void Shape2DSW::configure(const Rect2 &p_aabb) { aabb = p_aabb; diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 185bad4222..acc3297bed 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -33,7 +33,7 @@ #include "core/list.h" #include "core/map.h" -#include "core/string_db.h" +#include "core/string_name.h" #include "core/typedefs.h" #include "core/ustring.h" #include "core/variant.h" diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 7be3bc562d..b18fabd467 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -33,7 +33,7 @@ #include "core/io/marshalls.h" #include "core/os/os.h" #include "core/project_settings.h" -#include "core/sort.h" +#include "core/sort_array.h" #include "visual_server_canvas.h" #include "visual_server_global.h" #include "visual_server_scene.h" diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index e6434189f9..ec6e50753e 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -31,7 +31,6 @@ #ifndef VISUAL_SERVER_RASTER_H #define VISUAL_SERVER_RASTER_H -#include "core/allocators.h" #include "core/math/octree.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h index 539855bdc4..7583acd88f 100644 --- a/servers/visual/visual_server_scene.h +++ b/servers/visual/visual_server_scene.h @@ -33,7 +33,6 @@ #include "servers/visual/rasterizer.h" -#include "core/allocators.h" #include "core/math/geometry.h" #include "core/math/octree.h" #include "core/os/semaphore.h" @@ -120,7 +119,6 @@ public: VS::ScenarioDebugMode debug; RID self; - // well wtf, balloon allocator is slower? Octree octree; -- cgit v1.2.3