diff --git a/SCsub b/SCsub index d1fdc8d..f0025c8 100644 --- a/SCsub +++ b/SCsub @@ -3,6 +3,7 @@ Import('env') env.add_source_files(env.modules_sources,"register_types.cpp") env.add_source_files(env.modules_sources,"containers/voxelman_queue.cpp") +env.add_source_files(env.modules_sources,"containers/voxelman_unbounded_queue.cpp") env.add_source_files(env.modules_sources,"library/voxelman_library.cpp") env.add_source_files(env.modules_sources,"library/voxelman_library_simple.cpp") diff --git a/containers/voxelman_queue.cpp b/containers/voxelman_queue.cpp index 26d4f73..221a148 100644 --- a/containers/voxelman_queue.cpp +++ b/containers/voxelman_queue.cpp @@ -1,5 +1,7 @@ #include "voxelman_queue.h" +/// VMQUeue + template void VMQueue::enqueue(T obj) { _lock->write_lock(); @@ -91,6 +93,12 @@ VMQueue::VMQueue(int initial_size) { _count = 0; _size = initial_size; + if (unlikely(initial_size <= 0)) { + _size = 10; + + print_error("initial_size <= 0"); + } + _lock = RWLock::create(); _items = memnew_arr(T, _size); @@ -116,6 +124,7 @@ VMQueue::~VMQueue() { memdelete(_lock); } +///VoxelmanQueue void VoxelmanQueue::enqueue(Variant obj) { _queue.enqueue(obj); @@ -142,4 +151,4 @@ void VoxelmanQueue::_bind_methods() { ClassDB::bind_method(D_METHOD("dequeue"), &VoxelmanQueue::dequeue); ClassDB::bind_method(D_METHOD("peek"), &VoxelmanQueue::peek); ClassDB::bind_method(D_METHOD("resize", "new_size"), &VoxelmanQueue::resize); -} \ No newline at end of file +} diff --git a/containers/voxelman_unbounded_queue.cpp b/containers/voxelman_unbounded_queue.cpp new file mode 100644 index 0000000..5513726 --- /dev/null +++ b/containers/voxelman_unbounded_queue.cpp @@ -0,0 +1,92 @@ +#include "voxelman_unbounded_queue.h" + +/// VMQUeue + +template +void VMUBQueue::enqueue(T obj) { + _enqueue_lock->write_lock(); + + UBQueueNode *n = memnew(UBQueueNode(obj)); + + _tail->next = n; + _tail = n; + + _enqueue_lock->write_unlock(); +} + +template +T VMUBQueue::dequeue() { + T result; + + _dequeue_lock->write_lock(); + + if (_head->next == NULL) { + return result; + } + + result = _head->next->data; + + UBQueueNode *h = _head; + + _head = _head->next; + + memdelete(h); + + _dequeue_lock->write_unlock(); + + return result; +} + +template +T VMUBQueue::peek() { + return _head->data; +} + +template +VMUBQueue::VMUBQueue() { + _head = memnew(UBQueueNode); + _tail = _head; + + _enqueue_lock = RWLock::create(); + _dequeue_lock = RWLock::create(); +} + +template +VMUBQueue::~VMUBQueue() { + memdelete(_enqueue_lock); + memdelete(_dequeue_lock); + + UBQueueNode *h = _head; + + while (h) { + UBQueueNode *n = h->next; + + memdelete(h); + + h = n; + } +} + +///VoxelmanUnboundedQueue + +void VoxelmanUnboundedQueue::enqueue(Variant obj) { + _queue.enqueue(obj); +} +Variant VoxelmanUnboundedQueue::dequeue() { + return _queue.dequeue(); +} +Variant VoxelmanUnboundedQueue::peek() { + return _queue.peek(); +} + +VoxelmanUnboundedQueue::VoxelmanUnboundedQueue() { +} + +VoxelmanUnboundedQueue::~VoxelmanUnboundedQueue() { +} + +void VoxelmanUnboundedQueue::_bind_methods() { + ClassDB::bind_method(D_METHOD("enqueue", "obj"), &VoxelmanUnboundedQueue::enqueue); + ClassDB::bind_method(D_METHOD("dequeue"), &VoxelmanUnboundedQueue::dequeue); + ClassDB::bind_method(D_METHOD("peek"), &VoxelmanUnboundedQueue::peek); +} diff --git a/containers/voxelman_unbounded_queue.h b/containers/voxelman_unbounded_queue.h new file mode 100644 index 0000000..8c5bd05 --- /dev/null +++ b/containers/voxelman_unbounded_queue.h @@ -0,0 +1,63 @@ +#ifndef VOXELMAN_UNBOUNDED_QUEUE_H +#define VOXELMAN_UNBOUNDED_QUEUE_H + +#include "core/reference.h" + +#include "core/os/copymem.h" +#include "core/os/memory.h" +#include "core/os/rw_lock.h" +#include "core/variant.h" + +template +struct UBQueueNode { + T data; + UBQueueNode *next; + + UBQueueNode() { + next = NULL; + } + + UBQueueNode(T value) { + data = value; + next = NULL; + } +}; + +template +class VMUBQueue { + +public: + void enqueue(T obj); + T dequeue(); + T peek(); + + VMUBQueue(); + ~VMUBQueue(); + +private: + RWLock *_enqueue_lock; + RWLock *_dequeue_lock; + + UBQueueNode *_head; + UBQueueNode *_tail; +}; + +class VoxelmanUnboundedQueue : public Reference { + GDCLASS(VoxelmanUnboundedQueue, Reference); + +public: + void enqueue(Variant obj); + Variant dequeue(); + Variant peek(); + + VoxelmanUnboundedQueue(); + ~VoxelmanUnboundedQueue(); + +protected: + static void _bind_methods(); + +private: + VMUBQueue _queue; +}; + +#endif \ No newline at end of file diff --git a/register_types.cpp b/register_types.cpp index cce77c4..6926d62 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -1,6 +1,7 @@ #include "register_types.h" #include "containers/voxelman_queue.h" +#include "containers/voxelman_unbounded_queue.h" #include "library/voxel_surface.h" #include "library/voxel_surface_simple.h" @@ -41,7 +42,8 @@ void register_voxelman_types() { - ClassDB::register_class(); + ClassDB::register_class();\ + ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class();