From bad78945ceba425f6a80e3b8dca2414d592970eb Mon Sep 17 00:00:00 2001 From: chai Date: Fri, 2 Aug 2019 20:51:00 +0800 Subject: =?UTF-8?q?*=E4=BF=AE=E6=94=B9=E6=96=87=E4=BB=B6=E5=90=8D=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/modules/asura-utils/Classes.h | 9 + .../modules/asura-utils/Exceptions/Exception.cpp | 40 +++ source/modules/asura-utils/Exceptions/Exception.h | 30 +++ source/modules/asura-utils/IO/Compressor.cpp | 11 + source/modules/asura-utils/IO/Compressor.h | 28 ++ source/modules/asura-utils/IO/DataBuffer.cpp | 156 +++++++++++ source/modules/asura-utils/IO/DataBuffer.h | 87 ++++++ source/modules/asura-utils/IO/DecodedData.h | 41 +++ source/modules/asura-utils/IO/File.cpp | 294 +++++++++++++++++++++ source/modules/asura-utils/IO/File.h | 146 ++++++++++ source/modules/asura-utils/IO/FileData.cpp | 59 +++++ source/modules/asura-utils/IO/FileData.h | 69 +++++ source/modules/asura-utils/IO/FileSystem.cpp | 198 ++++++++++++++ source/modules/asura-utils/IO/FileSystem.h | 112 ++++++++ source/modules/asura-utils/IO/IOBatchTask.cpp | 0 source/modules/asura-utils/IO/IOBatchTask.h | 31 +++ source/modules/asura-utils/IO/IOTask.cpp | 61 +++++ source/modules/asura-utils/IO/IOTask.h | 56 ++++ source/modules/asura-utils/IO/Renewable.h | 29 ++ .../modules/asura-utils/IO/binding/_compressor.cpp | 0 .../asura-utils/IO/binding/_data_buffer.cpp | 132 +++++++++ source/modules/asura-utils/IO/binding/_file.cpp | 223 ++++++++++++++++ .../modules/asura-utils/IO/binding/_file_data.cpp | 60 +++++ .../asura-utils/IO/binding/_file_system.cpp | 265 +++++++++++++++++++ source/modules/asura-utils/IO/binding/_io_task.cpp | 46 ++++ source/modules/asura-utils/Manager.hpp | 14 + source/modules/asura-utils/Math/Curve.cpp | 0 source/modules/asura-utils/Math/Curve.h | 0 source/modules/asura-utils/Math/Functions.cpp | 0 source/modules/asura-utils/Math/Functions.h | 0 source/modules/asura-utils/Math/Matrix44.cpp | 217 +++++++++++++++ source/modules/asura-utils/Math/Matrix44.h | 98 +++++++ source/modules/asura-utils/Math/Quaternion.cpp | 0 source/modules/asura-utils/Math/Quaternion.h | 0 source/modules/asura-utils/Math/Rand/Rand.h | 89 +++++++ source/modules/asura-utils/Math/Rand/Random.h | 9 + source/modules/asura-utils/Math/RangedValue.cpp | 0 source/modules/asura-utils/Math/RangedValue.h | 0 source/modules/asura-utils/Math/Rect.hpp | 50 ++++ source/modules/asura-utils/Math/Rect.inc | 28 ++ source/modules/asura-utils/Math/Transform.cpp | 0 source/modules/asura-utils/Math/Transform.h | 30 +++ source/modules/asura-utils/Math/Vector2.hpp | 72 +++++ source/modules/asura-utils/Math/Vector2.inc | 114 ++++++++ source/modules/asura-utils/Math/Vector3.hpp | 233 ++++++++++++++++ source/modules/asura-utils/Math/Vector3.inc | 145 ++++++++++ source/modules/asura-utils/Math/Vector4.h | 234 ++++++++++++++++ source/modules/asura-utils/Math/Vector4.inc | 152 +++++++++++ source/modules/asura-utils/Module.h | 32 +++ source/modules/asura-utils/Scripting/Portable.hpp | 31 +++ source/modules/asura-utils/Singleton.hpp | 59 +++++ source/modules/asura-utils/StringMap.cpp | 0 source/modules/asura-utils/StringMap.hpp | 29 ++ source/modules/asura-utils/Threads/Conditional.cpp | 84 ++++++ source/modules/asura-utils/Threads/Conditional.h | 41 +++ source/modules/asura-utils/Threads/Coroutine.cpp | 15 ++ source/modules/asura-utils/Threads/Coroutine.h | 40 +++ source/modules/asura-utils/Threads/Mutex.cpp | 105 ++++++++ source/modules/asura-utils/Threads/Mutex.h | 128 +++++++++ source/modules/asura-utils/Threads/Semaphore.cpp | 99 +++++++ source/modules/asura-utils/Threads/Semaphore.h | 68 +++++ source/modules/asura-utils/Threads/Task.cpp | 10 + source/modules/asura-utils/Threads/Task.h | 43 +++ source/modules/asura-utils/Threads/Thread.cpp | 287 ++++++++++++++++++++ source/modules/asura-utils/Threads/Thread.h | 222 ++++++++++++++++ .../asura-utils/Threads/ThreadImplPosix.cpp | 0 .../modules/asura-utils/Threads/ThreadImplPosix.h | 2 + .../modules/asura-utils/Threads/ThreadImplSDL.cpp | 0 source/modules/asura-utils/Threads/ThreadImplSDL.h | 0 .../modules/asura-utils/Threads/ThreadImplStd.cpp | 0 source/modules/asura-utils/Threads/ThreadImplStd.h | 41 +++ .../asura-utils/Threads/ThreadImplWin32.cpp | 77 ++++++ .../modules/asura-utils/Threads/ThreadImplWin32.h | 44 +++ source/modules/asura-utils/Threads/Threadable.h | 23 ++ .../asura-utils/Threads/binding/_coroutine.cpp | 38 +++ .../asura-utils/Threads/binding/_thread.cpp | 208 +++++++++++++++ source/modules/asura-utils/Type.h | 34 +++ source/modules/asura-utils/Utils.h | 6 + source/modules/asura-utils/UtilsConfig.h | 13 + source/modules/asura-utils/UtilsModule.cpp | 25 ++ source/modules/asura-utils/UtilsModule.h | 34 +++ source/modules/asura-utils/classes.h | 4 +- source/modules/asura-utils/exceptions/exception.h | 4 +- .../asura-utils/io/binding/_data_buffer.cpp | 2 +- .../modules/asura-utils/io/binding/_file_data.cpp | 2 +- .../asura-utils/io/binding/_file_system.cpp | 2 +- source/modules/asura-utils/io/binding/_io_task.cpp | 2 +- source/modules/asura-utils/io/compressor.cpp | 2 +- source/modules/asura-utils/io/compressor.h | 6 +- source/modules/asura-utils/io/data_buffer.cpp | 156 ----------- source/modules/asura-utils/io/data_buffer.h | 87 ------ source/modules/asura-utils/io/decoded_data.h | 41 --- source/modules/asura-utils/io/file.cpp | 4 +- source/modules/asura-utils/io/file.h | 10 +- source/modules/asura-utils/io/file_data.cpp | 59 ----- source/modules/asura-utils/io/file_data.h | 69 ----- source/modules/asura-utils/io/file_system.cpp | 198 -------------- source/modules/asura-utils/io/file_system.h | 112 -------- source/modules/asura-utils/io/io_batch_task.cpp | 0 source/modules/asura-utils/io/io_batch_task.h | 31 --- source/modules/asura-utils/io/io_task.cpp | 61 ----- source/modules/asura-utils/io/io_task.h | 56 ---- source/modules/asura-utils/io/renewable.h | 2 +- source/modules/asura-utils/manager.hpp | 4 +- source/modules/asura-utils/math/matrix44.cpp | 2 +- source/modules/asura-utils/math/matrix44.h | 6 +- source/modules/asura-utils/math/ranged_value.cpp | 0 source/modules/asura-utils/math/ranged_value.h | 0 source/modules/asura-utils/math/rect.hpp | 6 +- source/modules/asura-utils/math/rect.inl | 28 -- source/modules/asura-utils/math/transform.h | 6 +- source/modules/asura-utils/math/vector2.hpp | 6 +- source/modules/asura-utils/math/vector2.inl | 114 -------- source/modules/asura-utils/math/vector3.hpp | 6 +- source/modules/asura-utils/math/vector3.inl | 145 ---------- source/modules/asura-utils/math/vector4.h | 6 +- source/modules/asura-utils/math/vector4.inl | 152 ----------- source/modules/asura-utils/module.h | 8 +- source/modules/asura-utils/scripting/portable.hpp | 18 +- source/modules/asura-utils/singleton.hpp | 8 +- source/modules/asura-utils/stringmap.hpp | 4 +- .../asura-utils/threading/binding/_coroutine.cpp | 38 --- .../asura-utils/threading/binding/_thread.cpp | 208 --------------- .../modules/asura-utils/threading/conditional.cpp | 84 ------ source/modules/asura-utils/threading/conditional.h | 41 --- source/modules/asura-utils/threading/coroutine.cpp | 15 -- source/modules/asura-utils/threading/coroutine.h | 40 --- source/modules/asura-utils/threading/mutex.cpp | 105 -------- source/modules/asura-utils/threading/mutex.h | 128 --------- source/modules/asura-utils/threading/semaphore.cpp | 99 ------- source/modules/asura-utils/threading/semaphore.h | 68 ----- source/modules/asura-utils/threading/task.cpp | 10 - source/modules/asura-utils/threading/task.h | 43 --- source/modules/asura-utils/threading/thread.cpp | 287 -------------------- source/modules/asura-utils/threading/thread.h | 222 ---------------- .../asura-utils/threading/thread_impl_posix.cpp | 9 - .../asura-utils/threading/thread_impl_posix.h | 2 - .../asura-utils/threading/thread_impl_sdl.cpp | 0 .../asura-utils/threading/thread_impl_sdl.h | 0 .../asura-utils/threading/thread_impl_std.cpp | 0 .../asura-utils/threading/thread_impl_std.h | 41 --- .../asura-utils/threading/thread_impl_win32.cpp | 77 ------ .../asura-utils/threading/thread_impl_win32.h | 44 --- source/modules/asura-utils/threading/threadable.h | 23 -- source/modules/asura-utils/type.h | 8 +- source/modules/asura-utils/utils.h | 6 +- source/modules/asura-utils/utils_config.h | 13 - source/modules/asura-utils/utils_module.cpp | 25 -- source/modules/asura-utils/utils_module.h | 34 --- 149 files changed, 5573 insertions(+), 3032 deletions(-) create mode 100644 source/modules/asura-utils/Classes.h create mode 100644 source/modules/asura-utils/Exceptions/Exception.cpp create mode 100644 source/modules/asura-utils/Exceptions/Exception.h create mode 100644 source/modules/asura-utils/IO/Compressor.cpp create mode 100644 source/modules/asura-utils/IO/Compressor.h create mode 100644 source/modules/asura-utils/IO/DataBuffer.cpp create mode 100644 source/modules/asura-utils/IO/DataBuffer.h create mode 100644 source/modules/asura-utils/IO/DecodedData.h create mode 100644 source/modules/asura-utils/IO/File.cpp create mode 100644 source/modules/asura-utils/IO/File.h create mode 100644 source/modules/asura-utils/IO/FileData.cpp create mode 100644 source/modules/asura-utils/IO/FileData.h create mode 100644 source/modules/asura-utils/IO/FileSystem.cpp create mode 100644 source/modules/asura-utils/IO/FileSystem.h create mode 100644 source/modules/asura-utils/IO/IOBatchTask.cpp create mode 100644 source/modules/asura-utils/IO/IOBatchTask.h create mode 100644 source/modules/asura-utils/IO/IOTask.cpp create mode 100644 source/modules/asura-utils/IO/IOTask.h create mode 100644 source/modules/asura-utils/IO/Renewable.h create mode 100644 source/modules/asura-utils/IO/binding/_compressor.cpp create mode 100644 source/modules/asura-utils/IO/binding/_data_buffer.cpp create mode 100644 source/modules/asura-utils/IO/binding/_file.cpp create mode 100644 source/modules/asura-utils/IO/binding/_file_data.cpp create mode 100644 source/modules/asura-utils/IO/binding/_file_system.cpp create mode 100644 source/modules/asura-utils/IO/binding/_io_task.cpp create mode 100644 source/modules/asura-utils/Manager.hpp create mode 100644 source/modules/asura-utils/Math/Curve.cpp create mode 100644 source/modules/asura-utils/Math/Curve.h create mode 100644 source/modules/asura-utils/Math/Functions.cpp create mode 100644 source/modules/asura-utils/Math/Functions.h create mode 100644 source/modules/asura-utils/Math/Matrix44.cpp create mode 100644 source/modules/asura-utils/Math/Matrix44.h create mode 100644 source/modules/asura-utils/Math/Quaternion.cpp create mode 100644 source/modules/asura-utils/Math/Quaternion.h create mode 100644 source/modules/asura-utils/Math/Rand/Rand.h create mode 100644 source/modules/asura-utils/Math/Rand/Random.h create mode 100644 source/modules/asura-utils/Math/RangedValue.cpp create mode 100644 source/modules/asura-utils/Math/RangedValue.h create mode 100644 source/modules/asura-utils/Math/Rect.hpp create mode 100644 source/modules/asura-utils/Math/Rect.inc create mode 100644 source/modules/asura-utils/Math/Transform.cpp create mode 100644 source/modules/asura-utils/Math/Transform.h create mode 100644 source/modules/asura-utils/Math/Vector2.hpp create mode 100644 source/modules/asura-utils/Math/Vector2.inc create mode 100644 source/modules/asura-utils/Math/Vector3.hpp create mode 100644 source/modules/asura-utils/Math/Vector3.inc create mode 100644 source/modules/asura-utils/Math/Vector4.h create mode 100644 source/modules/asura-utils/Math/Vector4.inc create mode 100644 source/modules/asura-utils/Module.h create mode 100644 source/modules/asura-utils/Scripting/Portable.hpp create mode 100644 source/modules/asura-utils/Singleton.hpp create mode 100644 source/modules/asura-utils/StringMap.cpp create mode 100644 source/modules/asura-utils/StringMap.hpp create mode 100644 source/modules/asura-utils/Threads/Conditional.cpp create mode 100644 source/modules/asura-utils/Threads/Conditional.h create mode 100644 source/modules/asura-utils/Threads/Coroutine.cpp create mode 100644 source/modules/asura-utils/Threads/Coroutine.h create mode 100644 source/modules/asura-utils/Threads/Mutex.cpp create mode 100644 source/modules/asura-utils/Threads/Mutex.h create mode 100644 source/modules/asura-utils/Threads/Semaphore.cpp create mode 100644 source/modules/asura-utils/Threads/Semaphore.h create mode 100644 source/modules/asura-utils/Threads/Task.cpp create mode 100644 source/modules/asura-utils/Threads/Task.h create mode 100644 source/modules/asura-utils/Threads/Thread.cpp create mode 100644 source/modules/asura-utils/Threads/Thread.h create mode 100644 source/modules/asura-utils/Threads/ThreadImplPosix.cpp create mode 100644 source/modules/asura-utils/Threads/ThreadImplPosix.h create mode 100644 source/modules/asura-utils/Threads/ThreadImplSDL.cpp create mode 100644 source/modules/asura-utils/Threads/ThreadImplSDL.h create mode 100644 source/modules/asura-utils/Threads/ThreadImplStd.cpp create mode 100644 source/modules/asura-utils/Threads/ThreadImplStd.h create mode 100644 source/modules/asura-utils/Threads/ThreadImplWin32.cpp create mode 100644 source/modules/asura-utils/Threads/ThreadImplWin32.h create mode 100644 source/modules/asura-utils/Threads/Threadable.h create mode 100644 source/modules/asura-utils/Threads/binding/_coroutine.cpp create mode 100644 source/modules/asura-utils/Threads/binding/_thread.cpp create mode 100644 source/modules/asura-utils/Type.h create mode 100644 source/modules/asura-utils/Utils.h create mode 100644 source/modules/asura-utils/UtilsConfig.h create mode 100644 source/modules/asura-utils/UtilsModule.cpp create mode 100644 source/modules/asura-utils/UtilsModule.h delete mode 100644 source/modules/asura-utils/io/data_buffer.cpp delete mode 100644 source/modules/asura-utils/io/data_buffer.h delete mode 100644 source/modules/asura-utils/io/decoded_data.h delete mode 100644 source/modules/asura-utils/io/file_data.cpp delete mode 100644 source/modules/asura-utils/io/file_data.h delete mode 100644 source/modules/asura-utils/io/file_system.cpp delete mode 100644 source/modules/asura-utils/io/file_system.h delete mode 100644 source/modules/asura-utils/io/io_batch_task.cpp delete mode 100644 source/modules/asura-utils/io/io_batch_task.h delete mode 100644 source/modules/asura-utils/io/io_task.cpp delete mode 100644 source/modules/asura-utils/io/io_task.h delete mode 100644 source/modules/asura-utils/math/ranged_value.cpp delete mode 100644 source/modules/asura-utils/math/ranged_value.h delete mode 100644 source/modules/asura-utils/math/rect.inl delete mode 100644 source/modules/asura-utils/math/vector2.inl delete mode 100644 source/modules/asura-utils/math/vector3.inl delete mode 100644 source/modules/asura-utils/math/vector4.inl delete mode 100644 source/modules/asura-utils/threading/binding/_coroutine.cpp delete mode 100644 source/modules/asura-utils/threading/binding/_thread.cpp delete mode 100644 source/modules/asura-utils/threading/conditional.cpp delete mode 100644 source/modules/asura-utils/threading/conditional.h delete mode 100644 source/modules/asura-utils/threading/coroutine.cpp delete mode 100644 source/modules/asura-utils/threading/coroutine.h delete mode 100644 source/modules/asura-utils/threading/mutex.cpp delete mode 100644 source/modules/asura-utils/threading/mutex.h delete mode 100644 source/modules/asura-utils/threading/semaphore.cpp delete mode 100644 source/modules/asura-utils/threading/semaphore.h delete mode 100644 source/modules/asura-utils/threading/task.cpp delete mode 100644 source/modules/asura-utils/threading/task.h delete mode 100644 source/modules/asura-utils/threading/thread.cpp delete mode 100644 source/modules/asura-utils/threading/thread.h delete mode 100644 source/modules/asura-utils/threading/thread_impl_posix.cpp delete mode 100644 source/modules/asura-utils/threading/thread_impl_posix.h delete mode 100644 source/modules/asura-utils/threading/thread_impl_sdl.cpp delete mode 100644 source/modules/asura-utils/threading/thread_impl_sdl.h delete mode 100644 source/modules/asura-utils/threading/thread_impl_std.cpp delete mode 100644 source/modules/asura-utils/threading/thread_impl_std.h delete mode 100644 source/modules/asura-utils/threading/thread_impl_win32.cpp delete mode 100644 source/modules/asura-utils/threading/thread_impl_win32.h delete mode 100644 source/modules/asura-utils/threading/threadable.h delete mode 100644 source/modules/asura-utils/utils_config.h delete mode 100644 source/modules/asura-utils/utils_module.cpp delete mode 100644 source/modules/asura-utils/utils_module.h (limited to 'source/modules/asura-utils') diff --git a/source/modules/asura-utils/Classes.h b/source/modules/asura-utils/Classes.h new file mode 100644 index 0000000..d92c3d4 --- /dev/null +++ b/source/modules/asura-utils/Classes.h @@ -0,0 +1,9 @@ +#ifndef _ASURAENGINE_CLASSES_H_ +#define _ASURAENGINE_CLASSES_H_ + +#define GET_SET(TYPE,PROP_NAME,VAR_NAME) void Set##PROP_NAME (TYPE val) { VAR_NAME = val; } const TYPE Get##PROP_NAME () const {return (const TYPE)VAR_NAME; } + +#define namespace_begin(NAMESPACE) namespace NAMESPACE { +#define namespace_end } + +#endif diff --git a/source/modules/asura-utils/Exceptions/Exception.cpp b/source/modules/asura-utils/Exceptions/Exception.cpp new file mode 100644 index 0000000..5240c49 --- /dev/null +++ b/source/modules/asura-utils/Exceptions/Exception.cpp @@ -0,0 +1,40 @@ +#include "Exception.h" + +#include +#include + +namespace AsuraEngine +{ + + Exception::Exception(const char *fmt, ...) + { + va_list args; + int size_buffer = 256, size_out; + char *buffer; + while (true) + { + buffer = new char[size_buffer]; + memset(buffer, 0, size_buffer); + + va_start(args, fmt); + size_out = vsnprintf(buffer, size_buffer, fmt, args); + va_end(args); + + if (size_out == size_buffer || size_out == -1 || size_out == size_buffer - 1) + size_buffer *= 2; + else if (size_out > size_buffer) + size_buffer = size_out + 2; + else + break; + + delete[] buffer; + } + message = std::string(buffer); + delete[] buffer; + } + + Exception::~Exception() throw() + { + } + +} diff --git a/source/modules/asura-utils/Exceptions/Exception.h b/source/modules/asura-utils/Exceptions/Exception.h new file mode 100644 index 0000000..73c0861 --- /dev/null +++ b/source/modules/asura-utils/Exceptions/Exception.h @@ -0,0 +1,30 @@ +#ifndef _ASURA_ENGINE_EXCEPTION_H_ +#define _ASURA_ENGINE_EXCEPTION_H_ + +#include +#include + +namespace AsuraEngine +{ + +class Exception : public std::exception +{ +public: + + Exception(const char *fmt, ...); + virtual ~Exception() throw(); + + inline virtual const char *what() const throw() + { + return message.c_str(); + } + +private: + + std::string message; + +}; // Exception + +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/Compressor.cpp b/source/modules/asura-utils/IO/Compressor.cpp new file mode 100644 index 0000000..4202263 --- /dev/null +++ b/source/modules/asura-utils/IO/Compressor.cpp @@ -0,0 +1,11 @@ +#include "Compressor.h" + +namespace AsuraEngine +{ + namespace IO + { + + + + } +} \ No newline at end of file diff --git a/source/modules/asura-utils/IO/Compressor.h b/source/modules/asura-utils/IO/Compressor.h new file mode 100644 index 0000000..dc25e2a --- /dev/null +++ b/source/modules/asura-utils/IO/Compressor.h @@ -0,0 +1,28 @@ +#ifndef _ASURA_COMPRESSOR_H_ +#define _ASURA_COMPRESSOR_H_ + +#include "../Scripting/Portable.hpp" + +namespace AsuraEngine +{ + namespace IO + { + + class Compressor ASURA_FINAL + : public AEScripting::Portable + { + public: + + LUAX_DECL_SINGLETON(Compressor); + + private: + + LUAX_DECL_METHOD(_Compress); + LUAX_DECL_METHOD(_Decompress); + + }; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/DataBuffer.cpp b/source/modules/asura-utils/IO/DataBuffer.cpp new file mode 100644 index 0000000..6660a94 --- /dev/null +++ b/source/modules/asura-utils/IO/DataBuffer.cpp @@ -0,0 +1,156 @@ +#include +#include +#include "DataBuffer.h" + +using namespace AEThreading; + +namespace AsuraEngine +{ + namespace IO + { + + DataBuffer::DataBuffer(DataBuffer& src) + : m_Size(0) + , m_Capacity(0) + , m_Bytes(nullptr) + { + // 初始化容量 + lock(m_Mutex) + { + m_Capacity = src.m_Size; + m_Bytes = new byte[m_Capacity]; + Clear(); + + Load(src); + } + } + + DataBuffer::DataBuffer(std::size_t capacity) + : m_Size(0) + , m_Capacity(0) + , m_Bytes(nullptr) + { + lock(m_Mutex) + { + m_Capacity = capacity; + m_Bytes = new byte[m_Capacity]; + Clear(); + } + } + + DataBuffer::DataBuffer(const void* data, std::size_t size) + : m_Capacity(0) + , m_Size(0) + , m_Bytes(nullptr) + { + lock(m_Mutex) + { + m_Capacity = size; + m_Bytes = new byte[m_Capacity]; + Clear(); + + Load(data, size); + } + } + + DataBuffer::~DataBuffer() + { + lock(m_Mutex) + { + delete[] m_Bytes; + } + } + + void DataBuffer::Refactor(size_t capacity) + { + lock(m_Mutex) + { + if (!m_Bytes || m_Capacity != capacity) + { + if(m_Bytes) + delete[] m_Bytes; + m_Capacity = capacity; + m_Bytes = new byte[m_Capacity]; + m_Size = 0; + } + Clear(); + } + } + + void DataBuffer::Load(DataBuffer& db) + { + lock(m_Mutex) + { + Load(db.GetData(), db.GetSize()); + } + } + + void DataBuffer::Load(const void* data, std::size_t size) + { + lock(m_Mutex) + { + ASSERT(m_Capacity >= size); + memcpy(m_Bytes, data, size); + m_Size = size; + } + } + + void DataBuffer::Move(void* bytes, std::size_t size) + { + lock(m_Mutex) + { + if (m_Bytes == bytes) + { + // 如果是自身,代表更新size值,在读文件时会这样 + m_Size = size; + } + else + { + if (m_Bytes) + delete[] m_Bytes; + m_Bytes = (byte*)bytes; + m_Size = size; + m_Capacity = size; + } + } + } + + byte* DataBuffer::GetData() + { + return m_Bytes; + } + + void DataBuffer::Clear() + { + lock(m_Mutex) + { + if (m_Bytes) + { + memset(m_Bytes, 0, m_Size); + m_Size = 0; + } + } + } + + std::size_t DataBuffer::GetSize() + { + return m_Size; + } + + std::size_t DataBuffer::GetCapacity() + { + return m_Capacity; + } + + void DataBuffer::Lock() + { + m_Mutex.Lock(); + } + + void DataBuffer::Unlock() + { + m_Mutex.Unlock(); + } + + } +} \ No newline at end of file diff --git a/source/modules/asura-utils/IO/DataBuffer.h b/source/modules/asura-utils/IO/DataBuffer.h new file mode 100644 index 0000000..93fac6e --- /dev/null +++ b/source/modules/asura-utils/IO/DataBuffer.h @@ -0,0 +1,87 @@ +#ifndef _ASURA_ENGINE_DATABUFFER_H_ +#define _ASURA_ENGINE_DATABUFFER_H_ + +#include + +#include "../Scripting/Portable.hpp" +#include "../Threads/Mutex.h" + +namespace AsuraEngine +{ + namespace IO + { + + /// + /// 对内存数据的封装,所有的数据使用Data buffer包装,不直接使用const void*。通过resource manager读取。 + /// + class DataBuffer ASURA_FINAL + : public AEScripting::Portable + { + public: + + LUAX_DECL_FACTORY(DataBuffer); + + DataBuffer(DataBuffer& src); + DataBuffer(std::size_t capacity); + DataBuffer(const void* bytes, std::size_t size); + ~DataBuffer(); + + byte* GetData(); + size_t GetSize(); + size_t GetCapacity(); + + /// + /// 修改容量,并清空 + /// + void Refactor(size_t capacity); + + /// + /// 拷贝数据源到此缓冲 + /// + void Load(DataBuffer& db); + void Load(const void* bytes, std::size_t size); + + /// + /// 绑定bytes,并拥有所有权,capacity为size + /// + void Move(void* bytes, std::size_t size); + + /// + /// 清理缓冲 + /// + void Clear(); + + void Lock(); + void Unlock(); + + private: + + LUAX_DECL_METHOD(_New); + LUAX_DECL_METHOD(_GetData); + LUAX_DECL_METHOD(_GetSize); + LUAX_DECL_METHOD(_GetCapacity); + LUAX_DECL_METHOD(_Refactor); + LUAX_DECL_METHOD(_Load); + LUAX_DECL_METHOD(_Clear); + + /// + /// Buffer首地址和里面数据的长度 + /// + byte* m_Bytes; + size_t m_Size; + + /// + /// Buffer容量。 + /// + size_t m_Capacity; + + AEThreading::Mutex m_Mutex; + + }; + + } +} + +namespace AEIO = AsuraEngine::IO; + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/DecodedData.h b/source/modules/asura-utils/IO/DecodedData.h new file mode 100644 index 0000000..73a2f74 --- /dev/null +++ b/source/modules/asura-utils/IO/DecodedData.h @@ -0,0 +1,41 @@ +#ifndef _ASURA_ENGINE_DATA_H_ +#define _ASURA_ENGINE_DATA_H_ + +#include + +#include + +#include "../Scripting/Portable.hpp" + +#include "DataBuffer.h" + +namespace AsuraEngine +{ + namespace IO + { + + /// + /// 可以在另一个线程构建的data继承此类。如图片数据、音频数据等,可以在另一个线程中解析原 + /// 文件,生成内部数据格式,如像素等。 + /// + ASURA_ABSTRACT class DecodedData + { + public: + + /// + /// 从内存中构建data,可以放在另一个线程里面,从资源管理系统里面加载。 + /// + DecodedData() {}; + virtual ~DecodedData() {}; + + /// + /// 解码内存中的数据并以某种格式保存。 + /// + virtual void Decode(DataBuffer& buffer) = 0; + + }; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/File.cpp b/source/modules/asura-utils/IO/File.cpp new file mode 100644 index 0000000..6d5f4eb --- /dev/null +++ b/source/modules/asura-utils/IO/File.cpp @@ -0,0 +1,294 @@ +#include + +#include + +#include "File.h" + +namespace AsuraEngine +{ + namespace IO + { + + File::File(const std::string& filename) + : m_FileName(filename) + , m_FileHandle(nullptr) + , m_Mode(FILE_MODE_CLOSED) + , m_BufferMode(BUFFER_MODE_NONE) + , m_BufferSize(0) + { + size_t dot = filename.rfind('.'); + if (dot != std::string::npos) + { + m_Extension = filename.substr(dot + 1); + m_Name = filename.substr(0, dot); + } + else + m_Name = filename; + } + + File::~File() + { + if (m_Mode != FILE_MODE_CLOSED) + Close(); + } + + bool File::Open(FileMode mode) + { + if (!PHYSFS_isInit()) + throw Exception("Physfs is NOT initialized."); + + if (mode == FILE_MODE_CLOSED) + return false; + + if (mode == FILE_MODE_READ && !PHYSFS_exists(m_FileName.c_str())) + throw Exception("Could NOT open file %s. Does not exist.", m_FileName.c_str()); + + if (mode == FILE_MODE_APPEND || mode == FILE_MODE_WRITE) + { + if (!PHYSFS_getWriteDir()) + { + throw Exception("Could NOT set write directory."); + } + } + + // 已经在之前打开过,就不再创建新的handle了 + if (m_FileHandle != nullptr) + return true; + + PHYSFS_getLastErrorCode(); + + PHYSFS_File* handle = nullptr; + + switch (mode) + { + case FILE_MODE_READ: + handle = PHYSFS_openRead(m_FileName.c_str()); + break; + case FILE_MODE_APPEND: + handle = PHYSFS_openAppend(m_FileName.c_str()); + break; + case FILE_MODE_WRITE: + handle = PHYSFS_openWrite(m_FileName.c_str()); + break; + } + + if (handle == nullptr) + { + const char *err = PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()); + if (err == nullptr) + err = "unknown error"; + throw Exception("Could not open file %s (%s)", m_FileName.c_str(), err); + } + + m_FileHandle = handle; + m_Mode = mode; + + if (m_FileHandle && !SetBuffer(m_BufferMode,m_BufferSize)) + { + m_BufferMode = BUFFER_MODE_NONE; + m_BufferSize = 0; + } + + return m_FileHandle != nullptr; + } + + bool File::Close() + { + if (m_FileHandle == nullptr || !PHYSFS_close(m_FileHandle)) + return false; + m_Mode = FILE_MODE_CLOSED; + m_FileHandle = nullptr; + return true; + } + + bool File::IsOpen() + { + return m_Mode != FILE_MODE_CLOSED && m_FileHandle != nullptr; + } + + size_t File::GetSize() + { + if (m_FileHandle == nullptr) + { + Open(FILE_MODE_READ); + size_t size = PHYSFS_fileLength(m_FileHandle); + Close(); + return size; + } + return PHYSFS_fileLength(m_FileHandle); + } + + size_t File::Read(ASURA_OUT DataBuffer* dst, size_t length) + { + ASSERT(dst); + + if (dst->GetCapacity() < length) + throw Exception("Data buffer is too small compares to read length."); + + if (!m_FileHandle || m_Mode != FILE_MODE_READ) + throw Exception("File \"%s\" is not opened for reading", m_FileName); + + size_t max = PHYSFS_fileLength(m_FileHandle); + length = (length > max) ? max : length; + + if (length < 0) + throw Exception("Invalid read size."); + + dst->Lock(); + size_t size = PHYSFS_readBytes(m_FileHandle, dst->GetData(), length); + dst->Unlock(); + return size; + } + + size_t File::ReadAll(ASURA_OUT DataBuffer* dst) + { + ASSERT(dst); + + if (!m_FileHandle || m_Mode != FILE_MODE_READ) + throw Exception("File \"%s\" is not opened for reading", m_FileName); + + size_t length = PHYSFS_fileLength(m_FileHandle); + + if (dst->GetCapacity() < length) + throw Exception("Data buffer is too small compares to file length."); + + dst->Lock(); + byte* data = dst->GetData(); + size_t size = PHYSFS_readBytes(m_FileHandle, data, length); + dst->Move(data, length); + dst->Unlock(); + return size; + } + +#ifdef ASURA_WINDOWS + inline bool test_eof(File *that, PHYSFS_File *) + { + int64 pos = that->Tell(); + int64 size = that->GetSize(); + return pos == -1 || size == -1 || pos >= size; + } +#else + inline bool test_eof(File *, PHYSFS_File *file) + { + return PHYSFS_eof(file); + } +#endif + + bool File::IsEOF() + { + return m_FileHandle == nullptr || test_eof(this, m_FileHandle); + } + + size_t File::Tell() + { + if (!m_FileHandle) + return - 1; + + return PHYSFS_tell(m_FileHandle); + } + + bool File::Seek(size_t pos) + { + return m_FileHandle != nullptr && PHYSFS_seek(m_FileHandle, pos) != 0; + } + + bool File::Write(ASURA_REF DataBuffer* src) + { + if (!m_FileHandle || (m_Mode != FILE_MODE_APPEND && m_Mode != FILE_MODE_WRITE)) + throw Exception("File is not opened for writing."); + + byte* data = src->GetData(); + int size = src->GetSize(); + + if (size < 0) + throw Exception("Invalid write size."); + + size_t written = PHYSFS_writeBytes(m_FileHandle, data, size); + + if (written != src->GetSize()) + return false; + + // 处理行缓冲 + if (m_BufferSize == BUFFER_MODE_LINE && m_BufferSize > size) + { + if (memchr(data, '\n', size) != nullptr) + Flush(); + } + + return true; + } + + bool File::Flush() + { + if (!m_FileHandle || (m_Mode != FILE_MODE_WRITE && m_Mode != FILE_MODE_APPEND)) + throw Exception("File is not opened for writing."); + + return PHYSFS_flush(m_FileHandle) != 0; + } + + bool File::SetBuffer(BufferMode mode, size_t size) + { + if (size < 0) + return false; + + // If the file isn't open, we'll make sure the buffer values are set in + // File::open. + if (!IsOpen()) + { + m_BufferMode = mode; + m_BufferSize = size; + return true; + } + + int ret = 1; + + switch (mode) + { + case BUFFER_MODE_NONE: + default: + ret = PHYSFS_setBuffer(m_FileHandle, 0); + size = 0; + break; + case BUFFER_MODE_LINE: + case BUFFER_MODE_FULL: + ret = PHYSFS_setBuffer(m_FileHandle, size); + break; + } + + if (ret == 0) + return false; + + m_BufferMode = mode; + m_BufferSize = size; + + return true; + } + + File::BufferMode File::GetBuffer(ASURA_OUT size_t& size) + { + size = m_BufferSize; + return m_BufferMode; + } + + const std::string& File::GetFileName() + { + return m_FileName; + } + + const std::string& File::GetName() + { + return m_Name; + } + + const std::string& File::GetExtension() + { + return m_Extension; + } + + File::FileMode File::GetMode() + { + return m_Mode; + } + + } +} \ No newline at end of file diff --git a/source/modules/asura-utils/IO/File.h b/source/modules/asura-utils/IO/File.h new file mode 100644 index 0000000..d11fa4f --- /dev/null +++ b/source/modules/asura-utils/IO/File.h @@ -0,0 +1,146 @@ +#ifndef _ASURA_ENGINE_FILE_H_ +#define _ASURA_ENGINE_FILE_H_ + +#include "physfs/physfs.h" + +#include "../Scripting/Portable.hpp" +#include "../Threads/Thread.h" + +#include "FileData.h" + +namespace AsuraEngine +{ + namespace IO + { + + /// + /// 以流的形式打开文件,可以指定读写起点、大小。在期望使用流读取时使用本类,否则使用Filesystem.read()直接读取文件全部 + /// 内容,并返回一个FileData对象。 + /// + class File ASURA_FINAL + : public AEScripting::Portable + { + public: + + LUAX_DECL_FACTORY(File); + + /// + /// 文件读写模式 + /// + enum FileMode + { + FILE_MODE_CLOSED, + FILE_MODE_READ, + FILE_MODE_WRITE, + FILE_MODE_APPEND, + }; + + /// + /// 文件写入时缓冲区行为 + /// + enum BufferMode + { + BUFFER_MODE_NONE, ///< 不使用缓冲,立即写入文件 + BUFFER_MODE_LINE, ///< 行缓冲,遇到换行符或者达到缓冲区大小时写入文件 + BUFFER_MODE_FULL, ///< 完全缓冲,缓冲区满时写入文件 + }; + + File(const std::string& filename); + ~File(); + + bool Open(FileMode mode); + bool Close(); + bool IsOpen(); + FileMode GetMode(); + size_t GetSize(); + + /// + /// 读取到data buffer里,并返回读入的内容 + /// + size_t Read(ASURA_OUT DataBuffer* dst, size_t length); + size_t ReadAll(ASURA_OUT DataBuffer* dst); + size_t ReadAsync(ASURA_OUT DataBuffer* dst); + + /// + /// 是否读到了文件结尾 + /// + bool IsEOF(); + + /// + /// 将data buffer中的内容写入,并返回是否成功 + /// + bool Write(ASURA_REF DataBuffer* src); + + /// + /// 异步写文件,将写文件task加入thread的队列。 + /// + bool WriteAsync(ASURA_REF DataBuffer* src, AEThreading::Thread* thread); + + /// + /// 如果开启了缓冲,强制清空缓冲区,写入文件。 + /// + bool Flush(); + + /// + /// 返回当前读写位置 + /// + size_t Tell(); + + /// + /// 跳到对应位置 + /// + bool Seek(size_t pos); + + /// + /// 设置缓冲区大小和模式 + /// + bool SetBuffer(BufferMode mode, size_t size); + + /// + /// 获取缓冲区大小和模式 + /// + BufferMode GetBuffer(ASURA_OUT size_t& size); + + const std::string& GetFileName(); + const std::string& GetName(); + const std::string& GetExtension(); + + private: + + PHYSFS_File* m_FileHandle; ///< physfs 文件 + std::string m_FileName; ///< 文件名 + std::string m_Extension; ///< 不包含点的扩展名 + std::string m_Name; ///< 不包含点和扩展名的文件名 + FileMode m_Mode; ///< 文件打开模式 + BufferMode m_BufferMode; ///< 写入缓冲区模式 + size_t m_BufferSize; ///< 写入缓冲区大小 + + LUAX_DECL_ENUM(FileMode); + LUAX_DECL_ENUM(BufferMode); + + LUAX_DECL_METHOD(_New); + LUAX_DECL_METHOD(_Open); + LUAX_DECL_METHOD(_Close); + LUAX_DECL_METHOD(_IsOpen); + LUAX_DECL_METHOD(_GetMode); + LUAX_DECL_METHOD(_GetSize); + LUAX_DECL_METHOD(_Read); + LUAX_DECL_METHOD(_Write); + LUAX_DECL_METHOD(_ReadAsync); + LUAX_DECL_METHOD(_WriteAsync); + LUAX_DECL_METHOD(_IsEOF); + LUAX_DECL_METHOD(_Flush); + LUAX_DECL_METHOD(_Tell); + LUAX_DECL_METHOD(_Seek); + LUAX_DECL_METHOD(_SetBuffer); + LUAX_DECL_METHOD(_GetBuffer); + LUAX_DECL_METHOD(_GetFileName); + LUAX_DECL_METHOD(_GetExtension); + LUAX_DECL_METHOD(_GetName); + + }; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/FileData.cpp b/source/modules/asura-utils/IO/FileData.cpp new file mode 100644 index 0000000..ca1cce7 --- /dev/null +++ b/source/modules/asura-utils/IO/FileData.cpp @@ -0,0 +1,59 @@ +#include "FileData.h" + +namespace AsuraEngine +{ + namespace IO + { + + FileData::FileData(const std::string& filename) + : m_Data(nullptr) + , m_FileName(filename) + { + size_t dot = filename.rfind('.'); + if (dot != std::string::npos) + { + m_Extension = filename.substr(dot + 1); + m_Name = filename.substr(0, dot); + } + else + m_Name = filename; + } + + FileData::~FileData() + { + if (m_Data) + m_Data->Release(); + } + + const std::string& FileData::GetFileName() + { + return m_FileName; + } + + const std::string& FileData::GetExtension() + { + return m_Extension; + } + + const std::string& FileData::GetName() + { + return m_Name; + } + + void FileData::BindData(ASURA_MOVE DataBuffer* buffer) + { + if (!buffer) + return; + if (m_Data) + m_Data->Release(); + m_Data = buffer; + m_Data->Retain(); + } + + DataBuffer* FileData::GetDataBuffer() + { + return m_Data; + } + + } +} \ No newline at end of file diff --git a/source/modules/asura-utils/IO/FileData.h b/source/modules/asura-utils/IO/FileData.h new file mode 100644 index 0000000..f93040c --- /dev/null +++ b/source/modules/asura-utils/IO/FileData.h @@ -0,0 +1,69 @@ +#ifndef _ASURA_ENGINE_FILE_DATA_H_ +#define _ASURA_ENGINE_FILE_DATA_H_ + +#include + +#include + +#include "DataBuffer.h" + +namespace AsuraEngine +{ + namespace IO + { + + class Filesystem; + + /// + /// 当从filesystem直接读取整个文件时,返回FileData对象描述文件内容和其他信息。由Filesystem创建。 + /// + class FileData ASURA_FINAL + : public AEScripting::Portable + { + public: + + LUAX_DECL_FACTORY(FileData); + + ~FileData(); + + /// + /// 返回文件内容,可以通过Databuffer获得内容和大小。由于内部接口都是以Data buffer作为参数,所以这里也返回data buffer。 + /// + DataBuffer* GetDataBuffer(); + + const std::string& GetFileName(); + const std::string& GetExtension(); + const std::string& GetName(); + + private: + + friend class Filesystem; + + FileData(const std::string& name); + + /// + /// 绑定data buffer。 + /// + void BindData(ASURA_MOVE DataBuffer* buffer); + + /// + /// Data buffer不会再filedata析构时销毁,当lua引用计数为0时由lua调用GC销毁。创建mData时会添加一个成员引用。 + /// + ASURA_REF DataBuffer* m_Data; + Luax::LuaxMemberRef m_DataRef; + + std::string m_FileName; ///< 包含扩展名的文件名 + std::string m_Extension; ///< 不包含点的扩展名 + std::string m_Name; ///< 不包含点和后缀的文件名 + + LUAX_DECL_METHOD(_GetDataBuffer); + LUAX_DECL_METHOD(_GetFileName); + LUAX_DECL_METHOD(_GetExtension); + LUAX_DECL_METHOD(_GetName); + + }; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/FileSystem.cpp b/source/modules/asura-utils/IO/FileSystem.cpp new file mode 100644 index 0000000..9d0acf0 --- /dev/null +++ b/source/modules/asura-utils/IO/FileSystem.cpp @@ -0,0 +1,198 @@ +#include + +#include "../exceptions/exception.h" + +#include "File.h" +#include "FileData.h" +#include "FileSystem.h" + +using namespace std; + +namespace AsuraEngine +{ + namespace IO + { + +#ifdef ASURA_WINDOWS + #include + #include +#else + #include + #include +#endif + + Filesystem::~Filesystem() + { + if (m_Inited) //PHYSFS_isInit + PHYSFS_deinit(); + } + + void Filesystem::Init(const char* arg0) + { + if (!PHYSFS_init(arg0)) + throw Exception("Failed to initialize filesystem: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); + + m_Inited = true; + } + + bool Filesystem::Mount(const std::string& locpath, const std::string& montpoint/* = "/"*/, bool prepend /*= false*/) + { + if (!m_Inited) + return false; + + return PHYSFS_mount(locpath.c_str(), montpoint.c_str(), !prepend); + } + + bool Filesystem::Mount(DataBuffer* db, const std::string& archivename, const std::string& mountpoint /*= "/"*/, bool prepend /*= false*/) + { + if (!m_Inited) + return false; + if (PHYSFS_mountMemory(db->GetData(), db->GetSize(), nullptr, archivename.c_str(), mountpoint.c_str(), !prepend)) + { + m_MountData[archivename] = db; + return true; + } + return false; + } + + bool Filesystem::Unmount(const std::string& locpath) + { + if (!m_Inited) + return false; + + // 如果是归档,从映射中删除它 + auto datait = m_MountData.find(locpath); + if (datait != m_MountData.end() && PHYSFS_unmount(locpath.c_str()) != 0) + { + m_MountData.erase(datait); + return true; + } + + return PHYSFS_unmount(locpath.c_str()); + } + + bool Filesystem::Unmount(DataBuffer* db) + { + for (const auto& dp : m_MountData) + { + if (dp.second == db) + { + std::string archive = dp.first; + return Unmount(archive); + } + } + } + + bool Filesystem::GetMountPoint(const std::string& locpath, ASURA_OUT std::string& mountpoint) + { + if (!m_Inited) + return false; + const char* point = PHYSFS_getMountPoint(locpath.c_str()); + if (point != nullptr) + { + mountpoint = point; + return true; + } + return false; + } + + void Filesystem::SetWriteDirectory(const std::string locpath) + { + if (!m_Inited) + return; + if (!PHYSFS_setWriteDir(locpath.c_str())) + throw Exception("Failed to set write directory %s", locpath.c_str()); + } + + std::string Filesystem::GetWriteDirectory() + { + return PHYSFS_getWriteDir(); + } + + File* Filesystem::NewFile(const std::string& name) + { + return new File(name); + } + + bool Filesystem::NewDirectory(const std::string& path) + { + if (!m_Inited) + return false; + if (!PHYSFS_getWriteDir()) + return false; + if (!PHYSFS_mkdir(path.c_str())) + return false; + return true; + } + + bool Filesystem::Write(const std::string& name, ASURA_REF DataBuffer* buffer) + { + File file(name); + file.Open(File::FILE_MODE_WRITE); + if (!file.Write(buffer)) + throw Exception("Data could not be written."); + } + + bool Filesystem::Append(const std::string& name, ASURA_REF DataBuffer* buffer) + { + File file(name); + file.Open(File::FILE_MODE_APPEND); + if (!file.Write(buffer)) + throw Exception("Data could not be append."); + } + + FileData* Filesystem::Read(const std::string& name) + { + File file = File(name); + file.Open(File::FILE_MODE_READ); + int size = file.GetSize(); + DataBuffer* db = new DataBuffer(size); + if (db) + { + file.ReadAll(db); + FileData* fd = new FileData(name); + fd->BindData(db); + return fd; + } + return nullptr; + } + + bool Filesystem::Remove(const std::string& path) + { + if (!m_Inited) + return false; + if (PHYSFS_getWriteDir() == 0) + return false; + + if (!PHYSFS_delete(path.c_str())) + return false; + + return true; + } + + bool Filesystem::GetFileInfo(const std::string& filepath, ASURA_OUT FileInfo* info) + { + if (!m_Inited) + return false; + + PHYSFS_Stat stat = {}; + if (!PHYSFS_stat(filepath.c_str(), &stat)) + return false; + + info->size = (int64)stat.filesize; + info->modtime = (int64)stat.modtime; + + if (stat.filetype == PHYSFS_FILETYPE_REGULAR) + info->type = FILE_TYPE_FILE; + else if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY) + info->type = FILE_TYPE_DIRECTORY; + else if (stat.filetype == PHYSFS_FILETYPE_SYMLINK) + info->type = FILE_TYPE_SYMLINK; + else + info->type = FILE_TYPE_OTHER; + + return true; + } + + } +} \ No newline at end of file diff --git a/source/modules/asura-utils/IO/FileSystem.h b/source/modules/asura-utils/IO/FileSystem.h new file mode 100644 index 0000000..f0ac6ba --- /dev/null +++ b/source/modules/asura-utils/IO/FileSystem.h @@ -0,0 +1,112 @@ +#ifndef _ASURA_ENGINE_FILESYSTEM_H_ +#define _ASURA_ENGINE_FILESYSTEM_H_ + +#include +#include + +#include "../Scripting/Portable.hpp" +#include "../Singleton.hpp" +#include "../Type.h" + +#include "FileData.h" +#include "File.h" + +namespace AsuraEngine +{ + namespace IO + { + + enum FileType + { + FILE_TYPE_FILE, ///< 文件 + FILE_TYPE_DIRECTORY, ///< 文件夹 + FILE_TYPE_SYMLINK, ///< 链接 + FILE_TYPE_OTHER, ///< 其他 + }; + + struct FileInfo + { + int64 size; + int64 modtime; + FileType type; + }; + + /// + /// 资源管理,负责加载、存储资源,指定根目录等。无论编辑器还是运行时,都需要限制访问的机制,将用户的操作限制在游戏目录 + /// 下,file system就是做这件事的。Filesystem是运行时和编辑器共用的类,AssetDatabase是用来管理资源的类,在framework + /// 里实现,单纯是逻辑处理,读写还是用Filesystem实现,AssetDatabase提供根据文件内容创建对应资源的方法。 + /// + class Filesystem ASURA_FINAL + : public Singleton + , public AEScripting::Portable + { + public: + + LUAX_DECL_SINGLETON(Filesystem); + + ~Filesystem(); + + void Init(const char* arg0); + + /// + /// 当前可执行文件的所在文件夹 + /// + std::string GetWorkingDirectory(); + + bool Mount(const std::string& locpath, const std::string& montpoint = "/", bool prepend = false); + bool Mount(DataBuffer* db, const std::string& archivename, const std::string& mountpoint = "/", bool prepend = false); + + bool Unmount(const std::string& locpath); + bool Unmount(DataBuffer* db); + + bool GetMountPoint(const std::string& locpath, ASURA_OUT std::string& mountpoint); + + void SetWriteDirectory(const std::string locpath); + std::string GetWriteDirectory(); + File* NewFile(const std::string& name); + bool NewDirectory(const std::string& path); + bool Write(const std::string& path, ASURA_REF DataBuffer* buffer); + bool Append(const std::string& path, ASURA_REF DataBuffer* buffer); + bool Remove(const std::string& path); + + FileData* Read(const std::string& path); + bool GetFileInfo(const std::string& path, ASURA_OUT FileInfo* info); + + bool GetDirectoryItems(const std::string& path, ASURA_OUT std::vector& items) { return false; }; + + private: + + typedef std::map MountDataMap; + + bool m_Inited; ///< 是否初始化成功 + std::string m_Cwd; ///< 当前执行文件的工作目录 + MountDataMap m_MountData; ///< 从路径到压缩文档的映射 + + LUAX_DECL_METHOD(_Init); + LUAX_DECL_METHOD(_Mount); + LUAX_DECL_METHOD(_Unmount); + LUAX_DECL_METHOD(_GetMountPoint); + + LUAX_DECL_METHOD(_SetWriteDirectory); + LUAX_DECL_METHOD(_GetWriteDirectory); + LUAX_DECL_METHOD(_CreateFile); + LUAX_DECL_METHOD(_CreateDirectory); + + LUAX_DECL_METHOD(_Write); + LUAX_DECL_METHOD(_Append); + LUAX_DECL_METHOD(_Remove); + + LUAX_DECL_METHOD(_Read); + + LUAX_DECL_METHOD(_GetFileInfo); + + LUAX_DECL_METHOD(_GetDirectoryItems); + + }; + + } +} + +namespace AEIO = AsuraEngine::IO; + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/IOBatchTask.cpp b/source/modules/asura-utils/IO/IOBatchTask.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/IO/IOBatchTask.h b/source/modules/asura-utils/IO/IOBatchTask.h new file mode 100644 index 0000000..a9355d5 --- /dev/null +++ b/source/modules/asura-utils/IO/IOBatchTask.h @@ -0,0 +1,31 @@ +#ifndef _ASURA_IO_BATCH_TASK_H_ +#define _ASURA_IO_BATCH_TASK_H_ + +#include "IOTask.h" + +namespace AsuraEngine +{ + namespace IO + { + + /// + /// 批量处理读或者写。一次性提交一个table,依次处理后返回结果。 + /// + class IOBatchTask ASURA_FINAL : public AEThreading::Task + { + public: + + private: + + /// + /// 任务表,每一条的结构如下: + /// { path = "", } + /// + Luax::LuaxMemberRef m_Tasks; + + }; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/IOTask.cpp b/source/modules/asura-utils/IO/IOTask.cpp new file mode 100644 index 0000000..bfa6726 --- /dev/null +++ b/source/modules/asura-utils/IO/IOTask.cpp @@ -0,0 +1,61 @@ +#include "FileSystem.h" +#include "IOTask.h" + +#include + +using namespace AEScripting; +using namespace Luax; + +namespace AsuraEngine +{ + namespace IO + { + + IOTask::IOTask(const std::string& path, DataBuffer* buffer, IOTaskType type) + : m_Path(path) + , m_Buffer(buffer) + { + if (buffer) + buffer->Retain(); + } + + IOTask::~IOTask() + { + if (m_Buffer) + m_Buffer->Release(); + } + + bool IOTask::Execute() + { + File file(m_Path); + if (m_Type == IOTASK_TYPE_WRITE) + { + + } + // 从path读取内容保存在mBuffer中 + else if (m_Type == IOTASK_TYPE_READ) + { + if (!m_Buffer) + return false; + file.Open(File::FILE_MODE_READ); + file.ReadAll(m_Buffer); + file.Close(); + } + return true; + } + + void IOTask::Invoke(lua_State* invokeThreaad) + { + if (m_Callback) + { + LuaxScopedState state(invokeThreaad); + if (this->PushLuaxMemberRef(state, m_Callback)) + { + this->PushLuaxMemberRef(state, m_BufferRef); + state.Call(1, 0); + } + } + } + + } +} diff --git a/source/modules/asura-utils/IO/IOTask.h b/source/modules/asura-utils/IO/IOTask.h new file mode 100644 index 0000000..a35fc54 --- /dev/null +++ b/source/modules/asura-utils/IO/IOTask.h @@ -0,0 +1,56 @@ +#ifndef _ASURA_IO_TASK_H_ +#define _ASURA_IO_TASK_H_ + +#include + +#include "../Scripting/Portable.hpp" +#include "../Threads/Task.h" + +#include "DataBuffer.h" + +namespace AsuraEngine +{ + namespace IO + { + + enum IOTaskType + { + IOTASK_TYPE_READ, + IOTASK_TYPE_WRITE, + IOTASK_TYPE_APPEND, + }; + + /// + /// 读取文件任务。 + /// + class IOTask ASURA_FINAL + : public AEScripting::Portable + { + public: + + LUAX_DECL_FACTORY(IOTask); + + IOTask(const std::string& path, DataBuffer* buffer, IOTaskType type); + ~IOTask(); + + bool Execute() override ; + void Invoke(lua_State* invokeThreaad) override; + + private: + + LUAX_DECL_ENUM(IOTaskType); + + LUAX_DECL_METHOD(_New); + + std::string m_Path; + IOTaskType m_Type; + + DataBuffer* m_Buffer; + Luax::LuaxMemberRef m_BufferRef; + + }; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/Renewable.h b/source/modules/asura-utils/IO/Renewable.h new file mode 100644 index 0000000..90867f2 --- /dev/null +++ b/source/modules/asura-utils/IO/Renewable.h @@ -0,0 +1,29 @@ +#ifndef __ASURA_ENGINE_RENEWABLE_H__ +#define __ASURA_ENGINE_RENEWABLE_H__ + +#include "../scripting/portable.hpp" + +#include "DecodedData.h" + +namespace AsuraEngine +{ + namespace IO + { + + /// + /// 可以重新构建的数据结构。比如图片、音频这种,从解析后数据可以直接构建,可以在编辑器内重 + /// 新构建,不会修改handle值,改变不具备破坏性,适用于不改变handle的资源。 + /// + ASURA_ABSTRACT class Renewable + { + public: + Renewable() {}; + virtual ~Renewable() {}; + }; + + } +} + +namespace AEIO = AsuraEngine::IO; + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/IO/binding/_compressor.cpp b/source/modules/asura-utils/IO/binding/_compressor.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/IO/binding/_data_buffer.cpp b/source/modules/asura-utils/IO/binding/_data_buffer.cpp new file mode 100644 index 0000000..9d3f3a0 --- /dev/null +++ b/source/modules/asura-utils/IO/binding/_data_buffer.cpp @@ -0,0 +1,132 @@ +#include "../DataBuffer.h" + +using namespace Luax; + +namespace AsuraEngine +{ + namespace IO + { + + LUAX_REGISTRY(DataBuffer) + { + LUAX_REGISTER_METHODS(state, + { "New", _New }, + { "GetData", _GetData }, + { "GetSize", _GetSize }, + { "GetCapacity", _GetCapacity }, + { "Refactor", _Refactor }, + { "Load", _Load }, + { "Clear", _Clear } + ); + } + + LUAX_POSTPROCESS(DataBuffer) + { + } + + // databuffer = DataBuffer.New(lstring) + // databuffer = DataBuffer.New(capacity) + LUAX_IMPL_METHOD(DataBuffer, _New) + { + LUAX_STATE(L); + + if (state.IsType(1, LUA_TSTRING)) + { + size_t size; + const byte* bytes = lua_tolstring(L, 1, &size); + DataBuffer* buffer = new DataBuffer(bytes, size); + buffer->PushLuaxUserdata(state); + return 1; + } + else if (state.IsType(1, LUA_TNUMBER)) + { + size_t capacity = lua_tonumber(L, 1); + DataBuffer* buffer = new DataBuffer(capacity); + buffer->PushLuaxUserdata(state); + return 1; + } + else + { + return state.ErrorType(1, "number or string"); + } + } + + // lsting, len = databuffer:GetData() + LUAX_IMPL_METHOD(DataBuffer, _GetData) + { + LUAX_SETUP(L, "U"); + + DataBuffer* self = state.GetUserdata(1); + lua_pushlstring(L, self->GetData(), self->GetSize()); + return 1; + } + + // length = databuffer:GetSize() + LUAX_IMPL_METHOD(DataBuffer, _GetSize) + { + LUAX_SETUP(L, "U"); + + DataBuffer* self = state.GetUserdata(1); + lua_pushinteger(L, self->GetSize()); + return 1; + } + + // capacity = databuffer:GetCapacity() + LUAX_IMPL_METHOD(DataBuffer, _GetCapacity) + { + LUAX_SETUP(L, "U"); + + DataBuffer* self = state.GetUserdata(1); + lua_pushinteger(L, self->GetCapacity()); + return 1; + } + + // databuffer:Refactor(capacity) + LUAX_IMPL_METHOD(DataBuffer, _Refactor) + { + LUAX_PREPARE(L, DataBuffer); + + size_t capacity = state.CheckValue(2); + self->Refactor(capacity); + return 0; + } + + // size = databuffer:Load(lstring) + // size = databuffer:Load(src) + LUAX_IMPL_METHOD(DataBuffer, _Load) + { + LUAX_STATE(L); + + DataBuffer* buffer = state.GetUserdata(1); + const byte* data; + size_t size; + if (state.IsType(2, LUA_TSTRING)) + { + data = lua_tolstring(L, 2, &size); + buffer->Load(data, size); + return 0; + } + else if(state.IsType(2, LUA_TUSERDATA)) + { + DataBuffer* src = state.CheckUserdata(2); + buffer->Load(*src); + return 0; + } + else + { + return state.ErrorType(1, "lstring or DataBuffer"); + } + } + + // databuffer:Clear() + LUAX_IMPL_METHOD(DataBuffer, _Clear) + { + LUAX_SETUP(L, "U"); + + DataBuffer* self = state.GetUserdata(1); + self->Clear(); + return 0; + } + + } +} \ No newline at end of file diff --git a/source/modules/asura-utils/IO/binding/_file.cpp b/source/modules/asura-utils/IO/binding/_file.cpp new file mode 100644 index 0000000..c44bc90 --- /dev/null +++ b/source/modules/asura-utils/IO/binding/_file.cpp @@ -0,0 +1,223 @@ +#include "../file.h" + +namespace AsuraEngine +{ + namespace IO + { + + LUAX_REGISTRY(File) + { + LUAX_REGISTER_METHODS(state, + { "New", _New }, + { "Open", _Open }, + { "Close", _Close }, + { "IsOpen", _IsOpen }, + { "GetMode", _GetMode }, + { "GetSize", _GetSize }, + { "Read", _Read }, + { "IsEOF", _IsEOF }, + { "Write", _Write }, + { "Flush", _Flush }, + { "Tell", _Tell }, + { "Seek", _Seek }, + { "SetBuffer", _SetBuffer }, + { "GetBuffer", _GetBuffer }, + { "GetFileName", _GetFileName }, + { "GetExtension", _GetExtension }, + { "GetName", _GetName } + ); + } + + LUAX_POSTPROCESS(File) + { + LUAX_REGISTER_ENUM(state, "EFileMode", + { "CLOSED", FILE_MODE_CLOSED }, + { "READ", FILE_MODE_READ }, + { "WRITE", FILE_MODE_WRITE }, + { "APPEND", FILE_MODE_APPEND } + ); + + LUAX_REGISTER_ENUM(state, "EBufferMode", + { "NONE", BUFFER_MODE_NONE}, + { "LINE", BUFFER_MODE_LINE}, + { "FULL", BUFFER_MODE_FULL} + ); + } + + // file = File.New(name) + LUAX_IMPL_METHOD(File, _New) + { + LUAX_STATE(L); + + cc8* name = state.CheckValue(1); + File* file = new File(name); + file->PushLuaxUserdata(state); + return 1; + } + + // successsed = file:Open(mode) + LUAX_IMPL_METHOD(File, _Open) + { + LUAX_PREPARE(L, File); + + File::FileMode mode = (File::FileMode)state.CheckValue(2); + state.Push(self->Open(mode)); + return 1; + } + + // successed = file:Close() + LUAX_IMPL_METHOD(File, _Close) + { + LUAX_PREPARE(L, File); + + state.Push(self->Close()); + return 1; + } + + // opened = file:IsOpen() + LUAX_IMPL_METHOD(File, _IsOpen) + { + LUAX_PREPARE(L, File); + + state.Push(self->IsOpen()); + return 1; + } + + // mode = file:GetMode() + LUAX_IMPL_METHOD(File, _GetMode) + { + LUAX_PREPARE(L, File); + + File::FileMode mode = self->GetMode(); + state.Push((int)mode); + return 1; + } + + // size = file:GetSize() + LUAX_IMPL_METHOD(File, _GetSize) + { + LUAX_PREPARE(L, File); + + state.Push(self->GetSize()); + return 1; + } + + // size = file:Read(dst, len) + // returns: + // size 实际读入的大小 + // params: + // self 文件 + // dst 目标缓冲区 + // len 期望读入的大小 + LUAX_IMPL_METHOD(File, _Read) + { + LUAX_PREPARE(L, File); + + DataBuffer* db = state.CheckUserdata(2); + if (!db) return state.ErrorType(2, "DataBuffer"); + int len = state.CheckValue(3); + int size = self->Read(db, len); + state.Push(size); + return 1; + } + + // isEOF = file:IsEOF() + LUAX_IMPL_METHOD(File, _IsEOF) + { + LUAX_PREPARE(L, File); + + state.Push(self->IsEOF()); + return 1; + } + + // isWrite = file:Write(data buffer[, size]) + LUAX_IMPL_METHOD(File, _Write) + { + LUAX_PREPARE(L, File); + + DataBuffer* db = state.CheckUserdata(2); + if (!db) return state.ErrorType(2, "DataBuffer"); + state.Push(self->Write(db)); + return 1; + } + + // isFlushed = file:Flush() + LUAX_IMPL_METHOD(File, _Flush) + { + LUAX_PREPARE(L, File); + + state.Push(self->Flush()); + return 1; + } + + // pos = file:Tell() + LUAX_IMPL_METHOD(File, _Tell) + { + LUAX_PREPARE(L, File); + + state.Push(self->Tell()); + return 1; + } + + // isSeek = file:Seek(pos) + LUAX_IMPL_METHOD(File, _Seek) + { + LUAX_PREPARE(L, File); + + int pos = state.CheckValue(2); + state.Push(self->Seek(pos)); + return 1; + } + + // isSetted = file:SetBuffer(mode, size) + LUAX_IMPL_METHOD(File, _SetBuffer) + { + LUAX_PREPARE(L, File); + + BufferMode mode = (BufferMode)state.CheckValue(2); + int size = state.CheckValue(3); + state.Push(self->SetBuffer(mode, size)); + return 1; + } + + // size, mode = file:GetBuffer() + LUAX_IMPL_METHOD(File, _GetBuffer) + { + LUAX_PREPARE(L, File); + + size_t size = 0; + BufferMode mode = self->GetBuffer(ASURA_OUT size); + state.Push((int)size); + state.Push((int)mode); + return 2; + } + + // name = file:GetFileName() + LUAX_IMPL_METHOD(File, _GetFileName) + { + LUAX_PREPARE(L, File); + + state.Push(self->GetFileName()); + return 1; + } + + // name = file:GetExtension() + LUAX_IMPL_METHOD(File, _GetExtension) + { + LUAX_PREPARE(L, File); + + state.Push(self->GetExtension()); + return 1; + } + + // name = file:GetName() + LUAX_IMPL_METHOD(File, _GetName) + { + LUAX_PREPARE(L, File); + + state.Push(self->GetName()); + return 1; + } + + } +} \ No newline at end of file diff --git a/source/modules/asura-utils/IO/binding/_file_data.cpp b/source/modules/asura-utils/IO/binding/_file_data.cpp new file mode 100644 index 0000000..55cbc8b --- /dev/null +++ b/source/modules/asura-utils/IO/binding/_file_data.cpp @@ -0,0 +1,60 @@ +#include "../FileData.h" + +using namespace std; + +namespace AsuraEngine +{ + namespace IO + { + + LUAX_REGISTRY(FileData) + { + LUAX_REGISTER_METHODS(state, + { "GetFileName", _GetFileName }, + { "GetExtension", _GetExtension }, + { "GetName", _GetName }, + { "GetDataBuffer", _GetDataBuffer } + ); + } + + LUAX_POSTPROCESS(FileData) + { + } + + // filename = filedata:GetFileName() + LUAX_IMPL_METHOD(FileData, _GetFileName) + { + LUAX_PREPARE(L, FileData); + string filename = self->GetFileName(); + state.Push(filename); + return 1; + } + + // extension = filedata:GetExtension() + LUAX_IMPL_METHOD(FileData, _GetExtension) + { + LUAX_PREPARE(L, FileData); + string extension = self->GetExtension(); + state.Push(extension); + return 1; + } + + // name = filedata:GetName() + LUAX_IMPL_METHOD(FileData, _GetName) + { + LUAX_PREPARE(L, FileData); + string extension = self->GetName(); + state.Push(extension); + return 1; + } + + // databuffer = filedata:GetDataBuffer() + LUAX_IMPL_METHOD(FileData, _GetDataBuffer) + { + LUAX_PREPARE(L, FileData); + self->PushLuaxMemberRef(state, self->m_DataRef); + return 1; + } + + } +} \ No newline at end of file diff --git a/source/modules/asura-utils/IO/binding/_file_system.cpp b/source/modules/asura-utils/IO/binding/_file_system.cpp new file mode 100644 index 0000000..ace3c5f --- /dev/null +++ b/source/modules/asura-utils/IO/binding/_file_system.cpp @@ -0,0 +1,265 @@ +#include "../FileSystem.h" + +using namespace Luax; + +namespace AsuraEngine +{ + namespace IO + { + +#define PREPARE(l) \ + LUAX_STATE(l); \ + Filesystem* fs = Filesystem::Get(); + + LUAX_REGISTRY(Filesystem) + { + LUAX_REGISTER_METHODS(state, + { "Init", _Init }, + { "Mount", _Mount }, + { "Unmount", _Unmount }, + { "GetMountPoint", _GetMountPoint }, + { "SetWriteDirectory", _SetWriteDirectory }, + { "GetWriteDirectory", _GetWriteDirectory }, + { "CreateFile", _CreateFile }, + { "CreateDirectory", _CreateDirectory }, + { "Write", _Write }, + { "Append", _Append }, + { "Remove", _Remove }, + { "Read", _Read }, + { "GetFileInfo", _GetFileInfo }, + { "GetDirectoryItems", _GetDirectoryItems } + ); + } + + LUAX_POSTPROCESS(Filesystem) + { + LUAX_REGISTER_ENUM(state, "EFileType", + { "FILE", FILE_TYPE_FILE }, + { "DIRECTORY", FILE_TYPE_DIRECTORY }, + { "SYMLINK", FILE_TYPE_SYMLINK }, + { "OTHER", FILE_TYPE_OTHER } + ); + } + + // Filesystem.Init(arg0) + LUAX_IMPL_METHOD(Filesystem, _Init) + { + PREPARE(L); + + const char* arg0 = state.CheckValue(1); + fs->Init(arg0); + return 0; + } + + // successed = Filesystem.Mount(path, mountpoint[, prepend = false]) + // successed = Filesystem.Mount(data buffer, archievename, mountpoint[, prepend = false]) + LUAX_IMPL_METHOD(Filesystem, _Mount) + { + PREPARE(L); + bool mounted = false; + + if (state.IsType(1, LUA_TSTRING)) + { + cc8* path = state.GetValue(1, ""); + cc8* moutpoint = state.GetValue(2, "/"); + bool prepend = state.GetValue(3, false); + mounted = fs->Mount(path, moutpoint, prepend); + } + else if (state.IsType(1, LUA_TUSERDATA)) + { + DataBuffer* db = state.CheckUserdata(1); + if (!db) + return state.ErrorType(1, "Data Buffer"); + cc8* arcname = state.GetValue(2, ""); + cc8* mountpoint = state.GetValue(3, "/"); + bool prepend = state.GetValue(4, false); + mounted = fs->Mount(db, arcname, mountpoint, prepend); + // retain + fs->LuaxRetain(state, db); + } + state.Push(mounted); + return 1; + } + + // successed = Filesystem.Unmount(path) + // successed = Filesystem.Unmount(data buffer) + LUAX_IMPL_METHOD(Filesystem, _Unmount) + { + PREPARE(L); + bool unmounted = false; + + if (state.IsType(1, LUA_TSTRING)) + { + cc8* path = state.GetValue(1, ""); + unmounted = fs->Unmount(path); + } + else if (state.IsType(1, LUA_TUSERDATA)) + { + DataBuffer* db = state.CheckUserdata(1); + if (!db) + return state.ErrorType(1, "Data Buffer"); + unmounted = fs->Unmount(db); + if (unmounted) + fs->LuaxRelease(state, db); + } + state.Push(unmounted); + return 1; + } + + // moutpoint = Filesystem.GetMountPoint(path) + LUAX_IMPL_METHOD(Filesystem, _GetMountPoint) + { + PREPARE(L); + + cc8* path = state.CheckValue(1); + std::string mp; + if (fs->GetMountPoint(path, ASURA_OUT mp)) + state.Push(mp); + else + state.PushNil(); + + return 1; + } + + // Filesystem.SetWriteDirectory(dir) + LUAX_IMPL_METHOD(Filesystem, _SetWriteDirectory) + { + PREPARE(L); + + cc8* dir = state.CheckValue(1); + fs->SetWriteDirectory(dir); + return 0; + } + + // dir = Filesystem.GetWriteDirectory() + LUAX_IMPL_METHOD(Filesystem, _GetWriteDirectory) + { + PREPARE(L); + + std::string dir = fs->GetWriteDirectory(); + state.Push(dir); + return 1; + } + + // file = Filesystem.CreateFile(name) + LUAX_IMPL_METHOD(Filesystem, _CreateFile) + { + PREPARE(L); + + cc8* name = state.CheckValue(1); + File* file = fs->NewFile(name); + if (file) + file->PushLuaxUserdata(state); + else + state.PushNil(); + return 1; + } + + // successed = Filesystem.CreateDirectory(name) + LUAX_IMPL_METHOD(Filesystem, _CreateDirectory) + { + PREPARE(L); + + cc8* path = state.CheckValue(1); + state.Push(fs->NewDirectory(path)); + return 1; + } + + // successed = Filesystem.Write(path, data buffer) + LUAX_IMPL_METHOD(Filesystem, _Write) + { + PREPARE(L); + + cc8* path = state.CheckValue(1); + DataBuffer* db = state.CheckUserdata(2); + state.Push(fs->Write(path, db)); + return 1; + } + + // successed = Filesystem.Append(path, data buffer) + LUAX_IMPL_METHOD(Filesystem, _Append) + { + PREPARE(L); + + cc8* path = state.CheckValue(1); + DataBuffer* db = state.CheckUserdata(2); + state.Push(fs->Append(path, db)); + return 1; + } + + // successed = Filesystem.Remove(path) + LUAX_IMPL_METHOD(Filesystem, _Remove) + { + PREPARE(L); + + cc8* path = state.CheckValue(1); + state.Push(fs->Remove(path)); + return 1; + } + + // filedata = Filesystem.Read(path) + LUAX_IMPL_METHOD(Filesystem, _Read) + { + PREPARE(L); + + cc8* path = state.CheckValue(1); + FileData* fd = fs->Read(path); + if (fd) + { + fd->m_Data->PushLuaxUserdata(state); + fd->SetLuaxMemberRef(state, fd->m_DataRef, -1); // fd->m_DataRef = data buffer + state.Pop(1); // data buffer + fd->PushLuaxUserdata(state); + } + else + { + state.PushNil(); + } + return 1; + } + + // fileinfo = Filesystem.GetFileInfo(path) + LUAX_IMPL_METHOD(Filesystem, _GetFileInfo) + { + PREPARE(L); + + cc8* path = state.CheckValue(1); + FileInfo info; + if (fs->GetFileInfo(path, &info)) + { + lua_newtable(L); // info table + state.SetField(-1, "size", info.size); + state.SetField(-1, "modtime", info.modtime); + state.SetField(-1, "type", info.type); + } + else + { + state.PushNil(); + } + return 1; + } + + // items = Filesystem.GetDirectoryItems(path) + LUAX_IMPL_METHOD(Filesystem, _GetDirectoryItems) + { + PREPARE(L); + + cc8* path = state.CheckValue(1); + std::vector items; + if(fs->GetDirectoryItems(path, ASURA_OUT items)) + { + lua_newtable(L); // item list + for (int i = 0; i < items.size(); ++i) + { + state.SetFieldByIndex(-1, i + 1, items[i]); + } + } + else + { + state.PushNil(); + } + return 1; + } + + } +} \ No newline at end of file diff --git a/source/modules/asura-utils/IO/binding/_io_task.cpp b/source/modules/asura-utils/IO/binding/_io_task.cpp new file mode 100644 index 0000000..058f4fd --- /dev/null +++ b/source/modules/asura-utils/IO/binding/_io_task.cpp @@ -0,0 +1,46 @@ +#include "../IOTask.h" + +using namespace std; + +namespace AsuraEngine +{ + namespace IO + { + + LUAX_REGISTRY(IOTask) + { + LUAX_REGISTER_METHODS(state, + { "New", _New } + ); + } + + LUAX_POSTPROCESS(IOTask) + { + LUAX_REGISTER_ENUM(state, "EIOTaskType", + { "READ", IOTASK_TYPE_READ }, + { "WRITE", IOTASK_TYPE_WRITE }, + { "APPEND", IOTASK_TYPE_APPEND } + ); + + } + + // task = IOTask.New(path, buffer, type, callback) + LUAX_IMPL_METHOD(IOTask, _New) + { + LUAX_STATE(L); + + cc8* path = state.CheckValue(1); + DataBuffer* db = state.CheckUserdata(2); + IOTaskType type = (IOTaskType)state.CheckValue(3); + bool cbk = state.GetTop() >= 4 && state.IsType(4, LUA_TFUNCTION); + + IOTask* task = new IOTask(path, db, type); + task->SetLuaxMemberRef(state, task->m_BufferRef, 2); + if(cbk) + task->SetLuaxMemberRef(state, task->m_Callback, 4); + task->PushLuaxUserdata(state); + return 1; + } + + } +} diff --git a/source/modules/asura-utils/Manager.hpp b/source/modules/asura-utils/Manager.hpp new file mode 100644 index 0000000..c6817b1 --- /dev/null +++ b/source/modules/asura-utils/Manager.hpp @@ -0,0 +1,14 @@ +#ifndef _ASURA_ENGINE_MANAGER_H_ +#define _ASURA_ENGINE_MANAGER_H_ + +namespace AsuraEngine +{ + + class Manager + { + + }; + +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Math/Curve.cpp b/source/modules/asura-utils/Math/Curve.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Math/Curve.h b/source/modules/asura-utils/Math/Curve.h new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Math/Functions.cpp b/source/modules/asura-utils/Math/Functions.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Math/Functions.h b/source/modules/asura-utils/Math/Functions.h new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Math/Matrix44.cpp b/source/modules/asura-utils/Math/Matrix44.cpp new file mode 100644 index 0000000..9ecf448 --- /dev/null +++ b/source/modules/asura-utils/Math/Matrix44.cpp @@ -0,0 +1,217 @@ +#include "Matrix44.h" + +#include // memcpy +#include + +namespace AsuraEngine +{ + namespace Math + { + + const Matrix44 Matrix44::Identity; + + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + + Matrix44::Matrix44() + { + SetIdentity(); + } + + Matrix44::Matrix44(const Matrix44& m) + { + memcpy(&e, &m.e, 16 * sizeof(float)); + } + + Matrix44::~Matrix44() + { + } + + void Matrix44::operator = (const Matrix44& m) + { + memcpy(&e, &m.e, 16 * sizeof(float)); + } + + void Matrix44::SetOrtho(float l, float r, float b, float t, float n, float f) + { + SetIdentity(); + float w = r - l; + float h = t - b; + float z = f - n; + e[0] = 2 / w; + e[5] = 2 / h; + e[10] = -2 / z; + e[12] = -(r + l) / w; + e[13] = -(t + b) / h; + e[14] = -(f + n) / z; + e[15] = 1; + } + + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + + Matrix44 Matrix44::operator * (const Matrix44 & m) const + { + Matrix44 t; + + t.e[0] = (e[0] * m.e[0]) + (e[4] * m.e[1]) + (e[8] * m.e[2]) + (e[12] * m.e[3]); + t.e[4] = (e[0] * m.e[4]) + (e[4] * m.e[5]) + (e[8] * m.e[6]) + (e[12] * m.e[7]); + t.e[8] = (e[0] * m.e[8]) + (e[4] * m.e[9]) + (e[8] * m.e[10]) + (e[12] * m.e[11]); + t.e[12] = (e[0] * m.e[12]) + (e[4] * m.e[13]) + (e[8] * m.e[14]) + (e[12] * m.e[15]); + + t.e[1] = (e[1] * m.e[0]) + (e[5] * m.e[1]) + (e[9] * m.e[2]) + (e[13] * m.e[3]); + t.e[5] = (e[1] * m.e[4]) + (e[5] * m.e[5]) + (e[9] * m.e[6]) + (e[13] * m.e[7]); + t.e[9] = (e[1] * m.e[8]) + (e[5] * m.e[9]) + (e[9] * m.e[10]) + (e[13] * m.e[11]); + t.e[13] = (e[1] * m.e[12]) + (e[5] * m.e[13]) + (e[9] * m.e[14]) + (e[13] * m.e[15]); + + t.e[2] = (e[2] * m.e[0]) + (e[6] * m.e[1]) + (e[10] * m.e[2]) + (e[14] * m.e[3]); + t.e[6] = (e[2] * m.e[4]) + (e[6] * m.e[5]) + (e[10] * m.e[6]) + (e[14] * m.e[7]); + t.e[10] = (e[2] * m.e[8]) + (e[6] * m.e[9]) + (e[10] * m.e[10]) + (e[14] * m.e[11]); + t.e[14] = (e[2] * m.e[12]) + (e[6] * m.e[13]) + (e[10] * m.e[14]) + (e[14] * m.e[15]); + + t.e[3] = (e[3] * m.e[0]) + (e[7] * m.e[1]) + (e[11] * m.e[2]) + (e[15] * m.e[3]); + t.e[7] = (e[3] * m.e[4]) + (e[7] * m.e[5]) + (e[11] * m.e[6]) + (e[15] * m.e[7]); + t.e[11] = (e[3] * m.e[8]) + (e[7] * m.e[9]) + (e[11] * m.e[10]) + (e[15] * m.e[11]); + t.e[15] = (e[3] * m.e[12]) + (e[7] * m.e[13]) + (e[11] * m.e[14]) + (e[15] * m.e[15]); + + return t; + } + + void Matrix44::operator *= (const Matrix44 & m) + { + Matrix44 t = (*this) * m; + memcpy((void*)this->e, (void*)t.e, sizeof(float) * 16); + } + + const float * Matrix44::GetElements() const + { + return e; + } + + void Matrix44::SetIdentity() + { + memset(e, 0, sizeof(float) * 16); + e[0] = e[5] = e[10] = e[15] = 1; + } + + void Matrix44::SetTranslation(float x, float y) + { + SetIdentity(); + e[12] = x; + e[13] = y; + } + + void Matrix44::SetRotation(float rad) + { + SetIdentity(); + float c = cos(rad), s = sin(rad); + e[0] = c; e[4] = -s; + e[1] = s; e[5] = c; + } + + void Matrix44::SetScale(float sx, float sy) + { + SetIdentity(); + e[0] = sx; + e[5] = sy; + } + + void Matrix44::SetShear(float kx, float ky) + { + SetIdentity(); + e[1] = ky; + e[4] = kx; + } + + void Matrix44::SetTransformation(float x, float y, float angle, float sx, float sy, float ox, float oy) + { + memset(e, 0, sizeof(float) * 16); // zero out matrix + float c = cos(angle), s = sin(angle); + // matrix multiplication carried out on paper: + // |1 x| |c -s | |sx | |1 -ox| + // | 1 y| |s c | | sy | | 1 -oy| + // | 1 | | 1 | | 1 | | 1 | + // | 1| | 1| | 1| | 1 | + // move rotate scale origin + e[10] = e[15] = 1.0f; + e[0] = c * sx; // = a + e[1] = s * sx; // = b + e[4] = -s * sy; // = c + e[5] = c * sy; // = d + e[12] = x - ox * e[0] - oy * e[4]; + e[13] = y - ox * e[1] - oy * e[5]; + } + + void Matrix44::Translate(float x, float y) + { + Matrix44 t; + t.SetTranslation(x, y); + this->operator *=(t); + } + + void Matrix44::Rotate(float rad) + { + Matrix44 t; + t.SetRotation(rad); + this->operator *=(t); + } + + void Matrix44::Scale(float sx, float sy) + { + Matrix44 t; + t.SetScale(sx, sy); + this->operator *=(t); + } + + void Matrix44::Shear(float kx, float ky) + { + Matrix44 t; + t.SetShear(kx, ky); + this->operator *=(t); + } + + void Matrix44::Transform(float x, float y, float angle, float sx, float sy, float ox, float oy) + { + Matrix44 t; + t.SetTransformation(x, y, angle, sx, sy, ox, oy); + this->operator *=(t); + } + + void Matrix44::Ortho(float left, float right, float bottom, float top, float near, float far) + { + Matrix44 t; + t.SetOrtho(left, right, bottom, top, near, far); + this->operator *=(t); + } + + // | x | + // | y | + // | 0 | + // | 1 | + // | e0 e4 e8 e12 | + // | e1 e5 e9 e13 | + // | e2 e6 e10 e14 | + // | e3 e7 e11 e15 | + + //void Matrix44::transform(Graphics::Vertex* dst, const Graphics::Vertex* src, int size) const + //{ + // for (int i = 0; i> 19)) ^ (t ^ (t >> 8)); + } + + inline static float GetFloatFromInt(uint32 value) + { + // take 23 bits of integer, and divide by 2^23-1 + return float(value & 0x007FFFFF) * (1.0f / 8388607.0f); + } + + inline static uint8 GetByteFromInt(uint32 value) + { + // take the most significant byte from the 23-bit value + return uint8(value >> (23 - 8)); + } + + // random number between 0.0 and 1.0 + float GetFloat() + { + return GetFloatFromInt(Get()); + } + + // random number between -1.0 and 1.0 + float GetSignedFloat() + { + return GetFloat() * 2.0f - 1.0f; + } + + void SetSeed(uint32 seed) + { + x = seed; + y = x * 1812433253U + 1; + z = y * 1812433253U + 1; + w = z * 1812433253U + 1; + } + + uint32 GetSeed() const { return x; } + +private: + uint32 x, y, z, w; +}; + +namespace_end +namespace_end + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Math/Rand/Random.h b/source/modules/asura-utils/Math/Rand/Random.h new file mode 100644 index 0000000..cf2fc54 --- /dev/null +++ b/source/modules/asura-utils/Math/Rand/Random.h @@ -0,0 +1,9 @@ +#include "Rand.h" + +namespace_begin(AsuraEngine) +namespace_begin(Math) + + + +namespace_end +namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/Math/RangedValue.cpp b/source/modules/asura-utils/Math/RangedValue.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Math/RangedValue.h b/source/modules/asura-utils/Math/RangedValue.h new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Math/Rect.hpp b/source/modules/asura-utils/Math/Rect.hpp new file mode 100644 index 0000000..45bf1ba --- /dev/null +++ b/source/modules/asura-utils/Math/Rect.hpp @@ -0,0 +1,50 @@ +#ifndef _ASURA_ENGINE_RECT_H_ +#define _ASURA_ENGINE_RECT_H_ + +namespace AsuraEngine +{ + namespace Math + { + + template + struct Rect + { + public: + Rect(); + Rect(T x, T y, T w, T h); + ~Rect() {}; + + /// + /// x,y是否落在rect内。 + /// + bool Contain(T x, T y); + + /// + /// 两个矩形是否相交,并返回相交的矩形 + /// + bool Intersect(const Rect& src, Rect& intersection); + + /// + /// 两个矩形是否相交,并返回相交的矩形 + /// + static bool Intersect(const Rect& src1, const Rect& src2, Rect& intersection); + + void Set(T x, T y, T w, T h); + + T x, y, w, h; + }; + +#include "Rect.inc" + + // Define the most common types + typedef Rect Recti; + typedef Rect Rectu; + typedef Rect Rectf; + typedef Rect Reftl; + + } +} + +namespace AEMath = AsuraEngine::Math; + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Math/Rect.inc b/source/modules/asura-utils/Math/Rect.inc new file mode 100644 index 0000000..efafbf9 --- /dev/null +++ b/source/modules/asura-utils/Math/Rect.inc @@ -0,0 +1,28 @@ +template +inline Rect::Rect() + : x(0) + , y(0) + , w(0) + , h(0) +{ + +} + +template +inline Rect::Rect(T X, T Y, T W, T H) + : x(X) + , y(Y) + , w(W) + , h(H) +{ + +} + +template +void Rect::Set(T X, T Y, T W, T H) +{ + x = X; + y = Y; + w = W; + h = H; +} \ No newline at end of file diff --git a/source/modules/asura-utils/Math/Transform.cpp b/source/modules/asura-utils/Math/Transform.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Math/Transform.h b/source/modules/asura-utils/Math/Transform.h new file mode 100644 index 0000000..23d0709 --- /dev/null +++ b/source/modules/asura-utils/Math/Transform.h @@ -0,0 +1,30 @@ +#ifndef _ASURA_ENGINE_TRANSFORM_H_ +#define _ASURA_ENGINE_TRANSFORM_H_ + +#include "../scripting/Portable.hpp" + +namespace AsuraEngine +{ + namespace Math + { + + class Transform + { + public: + + void Set(float x, float y, float sx, float sy, float ox, float oy, float r); + + void LoadIdentity(); + + void Move(float dx = 0, float dy = 0); + void Rotate(float r); + void Scale(float sx, float sy); + + float m[16]; //4x4 matrix + + }; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Math/Vector2.hpp b/source/modules/asura-utils/Math/Vector2.hpp new file mode 100644 index 0000000..f2405eb --- /dev/null +++ b/source/modules/asura-utils/Math/Vector2.hpp @@ -0,0 +1,72 @@ +#ifndef _ASURA_ENGINE_VECTOR2_H__ +#define _ASURA_ENGINE_VECTOR2_H__ + +namespace AsuraEngine +{ + namespace Math + { + template + class Vector2 + { + public: + Vector2(); + Vector2(T X, T Y); + + template + explicit Vector2(const Vector2& vector); + + void Set(T X, T Y); + + T x; ///< X coordinate of the vector + T y; ///< Y coordinate of the vector + }; + + template + Vector2 operator -(const Vector2& right); + + template + Vector2& operator +=(Vector2& left, const Vector2& right); + + template + Vector2& operator -=(Vector2& left, const Vector2& right); + + template + Vector2 operator +(const Vector2& left, const Vector2& right); + + template + Vector2 operator -(const Vector2& left, const Vector2& right); + + template + Vector2 operator *(const Vector2& left, T right); + + template + Vector2 operator *(T left, const Vector2& right); + + template + Vector2& operator *=(Vector2& left, T right); + + template + Vector2 operator /(const Vector2& left, T right); + + template + Vector2& operator /=(Vector2& left, T right); + + template + bool operator ==(const Vector2& left, const Vector2& right); + + template + bool operator !=(const Vector2& left, const Vector2& right); + +#include "Vector2.inc" + + // Define the most common types + typedef Vector2 Vector2i; + typedef Vector2 Vector2u; + typedef Vector2 Vector2f; + + } +} + +namespace AEMath = AsuraEngine::Math; + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Math/Vector2.inc b/source/modules/asura-utils/Math/Vector2.inc new file mode 100644 index 0000000..155432a --- /dev/null +++ b/source/modules/asura-utils/Math/Vector2.inc @@ -0,0 +1,114 @@ +template +inline Vector2::Vector2() : + x(0), + y(0) +{ + +} + +template +inline Vector2::Vector2(T X, T Y) : + x(X), + y(Y) +{ + +} + +template +template +inline Vector2::Vector2(const Vector2& vector) : + x(static_cast(vector.x)), + y(static_cast(vector.y)) +{ +} + +template +inline void Vector2::Set(T X, T Y) +{ + x = X; + y = Y; +} + +template +inline Vector2 operator -(const Vector2& right) +{ + return Vector2(-right.x, -right.y); +} + +template +inline Vector2& operator +=(Vector2& left, const Vector2& right) +{ + left.x += right.x; + left.y += right.y; + + return left; +} + +template +inline Vector2& operator -=(Vector2& left, const Vector2& right) +{ + left.x -= right.x; + left.y -= right.y; + + return left; +} + +template +inline Vector2 operator +(const Vector2& left, const Vector2& right) +{ + return Vector2(left.x + right.x, left.y + right.y); +} + +template +inline Vector2 operator -(const Vector2& left, const Vector2& right) +{ + return Vector2(left.x - right.x, left.y - right.y); +} + +template +inline Vector2 operator *(const Vector2& left, T right) +{ + return Vector2(left.x * right, left.y * right); +} + +template +inline Vector2 operator *(T left, const Vector2& right) +{ + return Vector2(right.x * left, right.y * left); +} + +template +inline Vector2& operator *=(Vector2& left, T right) +{ + left.x *= right; + left.y *= right; + + return left; +} + +template +inline Vector2 operator /(const Vector2& left, T right) +{ + return Vector2(left.x / right, left.y / right); +} + +template +inline Vector2& operator /=(Vector2& left, T right) +{ + left.x /= right; + left.y /= right; + + return left; +} + +template +inline bool operator ==(const Vector2& left, const Vector2& right) +{ + return (left.x == right.x) && (left.y == right.y); +} + +template +inline bool operator !=(const Vector2& left, const Vector2& right) +{ + return (left.x != right.x) || (left.y != right.y); +} diff --git a/source/modules/asura-utils/Math/Vector3.hpp b/source/modules/asura-utils/Math/Vector3.hpp new file mode 100644 index 0000000..8da57cf --- /dev/null +++ b/source/modules/asura-utils/Math/Vector3.hpp @@ -0,0 +1,233 @@ +#ifndef _ASURA_ENGINE_VECTOR3_H__ +#define _ASURA_ENGINE_VECTOR3_H__ + +namespace AsuraEngine +{ + namespace Math + { + template + class Vector3 + { + public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Creates a Vector3(0, 0, 0). + /// + //////////////////////////////////////////////////////////// + Vector3(); + + //////////////////////////////////////////////////////////// + /// \brief Construct the vector from its coordinates + /// + /// \param X X coordinate + /// \param Y Y coordinate + /// \param Z Z coordinate + /// + //////////////////////////////////////////////////////////// + Vector3(T X, T Y, T Z); + + //////////////////////////////////////////////////////////// + /// \brief Construct the vector from another type of vector + /// + /// This constructor doesn't replace the copy constructor, + /// it's called only when U != T. + /// A call to this constructor will fail to compile if U + /// is not convertible to T. + /// + /// \param vector Vector to convert + /// + //////////////////////////////////////////////////////////// + template + explicit Vector3(const Vector3& vector); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + T x; ///< X coordinate of the vector + T y; ///< Y coordinate of the vector + T z; ///< Z coordinate of the vector + }; + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of unary operator - + /// + /// \param left Vector to negate + /// + /// \return Memberwise opposite of the vector + /// + //////////////////////////////////////////////////////////// + template + Vector3 operator -(const Vector3& left); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator += + /// + /// This operator performs a memberwise addition of both vectors, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector3& operator +=(Vector3& left, const Vector3& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator -= + /// + /// This operator performs a memberwise subtraction of both vectors, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector3& operator -=(Vector3& left, const Vector3& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator + + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Memberwise addition of both vectors + /// + //////////////////////////////////////////////////////////// + template + Vector3 operator +(const Vector3& left, const Vector3& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator - + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Memberwise subtraction of both vectors + /// + //////////////////////////////////////////////////////////// + template + Vector3 operator -(const Vector3& left, const Vector3& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator * + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Memberwise multiplication by \a right + /// + //////////////////////////////////////////////////////////// + template + Vector3 operator *(const Vector3& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator * + /// + /// \param left Left operand (a scalar value) + /// \param right Right operand (a vector) + /// + /// \return Memberwise multiplication by \a left + /// + //////////////////////////////////////////////////////////// + template + Vector3 operator *(T left, const Vector3& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator *= + /// + /// This operator performs a memberwise multiplication by \a right, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector3& operator *=(Vector3& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator / + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Memberwise division by \a right + /// + //////////////////////////////////////////////////////////// + template + Vector3 operator /(const Vector3& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator /= + /// + /// This operator performs a memberwise division by \a right, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector3& operator /=(Vector3& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator == + /// + /// This operator compares strict equality between two vectors. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return True if \a left is equal to \a right + /// + //////////////////////////////////////////////////////////// + template + bool operator ==(const Vector3& left, const Vector3& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector3 + /// \brief Overload of binary operator != + /// + /// This operator compares strict difference between two vectors. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return True if \a left is not equal to \a right + /// + //////////////////////////////////////////////////////////// + template + bool operator !=(const Vector3& left, const Vector3& right); + +#include "Vector3.inc" + + // Define the most common types + typedef Vector3 Vector3i; + typedef Vector3 Vector3f; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Math/Vector3.inc b/source/modules/asura-utils/Math/Vector3.inc new file mode 100644 index 0000000..3a2aa93 --- /dev/null +++ b/source/modules/asura-utils/Math/Vector3.inc @@ -0,0 +1,145 @@ + + +//////////////////////////////////////////////////////////// +template +inline Vector3::Vector3() : + x(0), + y(0), + z(0) +{ + +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3::Vector3(T X, T Y, T Z) : + x(X), + y(Y), + z(Z) +{ + +} + + +//////////////////////////////////////////////////////////// +template +template +inline Vector3::Vector3(const Vector3& vector) : + x(static_cast(vector.x)), + y(static_cast(vector.y)), + z(static_cast(vector.z)) +{ +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3 operator -(const Vector3& left) +{ + return Vector3(-left.x, -left.y, -left.z); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3& operator +=(Vector3& left, const Vector3& right) +{ + left.x += right.x; + left.y += right.y; + left.z += right.z; + + return left; +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3& operator -=(Vector3& left, const Vector3& right) +{ + left.x -= right.x; + left.y -= right.y; + left.z -= right.z; + + return left; +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3 operator +(const Vector3& left, const Vector3& right) +{ + return Vector3(left.x + right.x, left.y + right.y, left.z + right.z); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3 operator -(const Vector3& left, const Vector3& right) +{ + return Vector3(left.x - right.x, left.y - right.y, left.z - right.z); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3 operator *(const Vector3& left, T right) +{ + return Vector3(left.x * right, left.y * right, left.z * right); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3 operator *(T left, const Vector3& right) +{ + return Vector3(right.x * left, right.y * left, right.z * left); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3& operator *=(Vector3& left, T right) +{ + left.x *= right; + left.y *= right; + left.z *= right; + + return left; +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3 operator /(const Vector3& left, T right) +{ + return Vector3(left.x / right, left.y / right, left.z / right); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector3& operator /=(Vector3& left, T right) +{ + left.x /= right; + left.y /= right; + left.z /= right; + + return left; +} + + +//////////////////////////////////////////////////////////// +template +inline bool operator ==(const Vector3& left, const Vector3& right) +{ + return (left.x == right.x) && (left.y == right.y) && (left.z == right.z); +} + + +//////////////////////////////////////////////////////////// +template +inline bool operator !=(const Vector3& left, const Vector3& right) +{ + return (left.x != right.x) || (left.y != right.y) || (left.z != right.z); +} diff --git a/source/modules/asura-utils/Math/Vector4.h b/source/modules/asura-utils/Math/Vector4.h new file mode 100644 index 0000000..a5bf549 --- /dev/null +++ b/source/modules/asura-utils/Math/Vector4.h @@ -0,0 +1,234 @@ +#ifndef _ASURA_ENGINE_VECTOR4_H__ +#define _ASURA_ENGINE_VECTOR4_H__ + +namespace AsuraEngine +{ + namespace Math + { + template + class Vector4 + { + public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Creates a Vector4(0, 0, 0). + /// + //////////////////////////////////////////////////////////// + Vector4(); + + //////////////////////////////////////////////////////////// + /// \brief Construct the vector from its coordinates + /// + /// \param X X coordinate + /// \param Y Y coordinate + /// \param Z Z coordinate + /// + //////////////////////////////////////////////////////////// + Vector4(T X, T Y, T Z, T W); + + //////////////////////////////////////////////////////////// + /// \brief Construct the vector from another type of vector + /// + /// This constructor doesn't replace the copy constructor, + /// it's called only when U != T. + /// A call to this constructor will fail to compile if U + /// is not convertible to T. + /// + /// \param vector Vector to convert + /// + //////////////////////////////////////////////////////////// + template + explicit Vector4(const Vector4& vector); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + T x; ///< X coordinate of the vector + T y; ///< Y coordinate of the vector + T z; ///< Z coordinate of the vector + T w; ///< W coordinate of the vector + }; + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of unary operator - + /// + /// \param left Vector to negate + /// + /// \return Memberwise opposite of the vector + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator -(const Vector4& left); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator += + /// + /// This operator performs a memberwise addition of both vectors, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4& operator +=(Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator -= + /// + /// This operator performs a memberwise subtraction of both vectors, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4& operator -=(Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator + + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Memberwise addition of both vectors + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator +(const Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator - + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Memberwise subtraction of both vectors + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator -(const Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator * + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Memberwise multiplication by \a right + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator *(const Vector4& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator * + /// + /// \param left Left operand (a scalar value) + /// \param right Right operand (a vector) + /// + /// \return Memberwise multiplication by \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator *(T left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator *= + /// + /// This operator performs a memberwise multiplication by \a right, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4& operator *=(Vector4& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator / + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Memberwise division by \a right + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator /(const Vector4& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator /= + /// + /// This operator performs a memberwise division by \a right, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4& operator /=(Vector4& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator == + /// + /// This operator compares strict equality between two vectors. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return True if \a left is equal to \a right + /// + //////////////////////////////////////////////////////////// + template + bool operator ==(const Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator != + /// + /// This operator compares strict difference between two vectors. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return True if \a left is not equal to \a right + /// + //////////////////////////////////////////////////////////// + template + bool operator !=(const Vector4& left, const Vector4& right); + +#include "Vector4.inc" + + // Define the most common types + typedef Vector4 Vector4i; + typedef Vector4 Vector4f; + + } +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Math/Vector4.inc b/source/modules/asura-utils/Math/Vector4.inc new file mode 100644 index 0000000..4b043a1 --- /dev/null +++ b/source/modules/asura-utils/Math/Vector4.inc @@ -0,0 +1,152 @@ + + +//////////////////////////////////////////////////////////// +template +inline Vector4::Vector4() : + x(0), + y(0), + z(0), + w(0) +{ + +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4::Vector4(T X, T Y, T Z, T W) : + x(X), + y(Y), + z(Z), + w(W) +{ + +} + + +//////////////////////////////////////////////////////////// +template +template +inline Vector4::Vector4(const Vector4& vector) : + x(static_cast(vector.x)), + y(static_cast(vector.y)), + z(static_cast(vector.z)), + w(static_cast(vector.w)) +{ +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4 operator -(const Vector4& left) +{ + return Vector4(-left.x, -left.y, -left.z, -left.w); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4& operator +=(Vector4& left, const Vector4& right) +{ + left.x += right.x; + left.y += right.y; + left.z += right.z; + left.w += right.w; + + return left; +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4& operator -=(Vector4& left, const Vector4& right) +{ + left.x -= right.x; + left.y -= right.y; + left.z -= right.z; + left.w -= right.w; + + return left; +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4 operator +(const Vector4& left, const Vector4& right) +{ + return Vector4(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4 operator -(const Vector4& left, const Vector4& right) +{ + return Vector4(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4 operator *(const Vector4& left, T right) +{ + return Vector4(left.x * right, left.y * right, left.z * right, left.w * right); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4 operator *(T left, const Vector4& right) +{ + return Vector4(right.x * left, right.y * left, right.z * left, right.w * left); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4& operator *=(Vector4& left, T right) +{ + left.x *= right; + left.y *= right; + left.z *= right; + left.w *= right; + + return left; +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4 operator /(const Vector4& left, T right) +{ + return Vector4(left.x / right, left.y / right, left.z / right, left.w / right); +} + + +//////////////////////////////////////////////////////////// +template +inline Vector4& operator /=(Vector4& left, T right) +{ + left.x /= right; + left.y /= right; + left.z /= right; + left.w /= right; + + return left; +} + + +//////////////////////////////////////////////////////////// +template +inline bool operator ==(const Vector4& left, const Vector4& right) +{ + return (left.x == right.x) && (left.y == right.y) && (left.z == right.z) && (left.w == right.w); +} + + +//////////////////////////////////////////////////////////// +template +inline bool operator !=(const Vector4& left, const Vector4& right) +{ + return (left.x != right.x) || (left.y != right.y) || (left.z != right.z) || (left.w != right.w); +} diff --git a/source/modules/asura-utils/Module.h b/source/modules/asura-utils/Module.h new file mode 100644 index 0000000..2cc91d6 --- /dev/null +++ b/source/modules/asura-utils/Module.h @@ -0,0 +1,32 @@ +#ifndef _ASURA_MODULE_H_ +#define _ASURA_MODULE_H_ + +#include "Type.h" +#include "Scripting/Portable.hpp" + +namespace AsuraEngine +{ + + /// + /// Asura libs 需要继承此类,以开启注册。在模块队列中按顺序添加这些模块,然后顺序调用Initialize和Finalize方法来初始化和 + /// 关闭这些模块。 + /// + ASURA_ABSTRACT class Module + { + public: + + /// + /// 初始化模块。 + /// + virtual void Initialize(Luax::LuaxState& state) = 0; + + /// + /// 关闭模块。 + /// + virtual void Finalize(Luax::LuaxState& state) = 0; + + }; + +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Scripting/Portable.hpp b/source/modules/asura-utils/Scripting/Portable.hpp new file mode 100644 index 0000000..1eee123 --- /dev/null +++ b/source/modules/asura-utils/Scripting/Portable.hpp @@ -0,0 +1,31 @@ +#ifndef _ASURA_ENGINE_PORTABLE_H_ +#define _ASURA_ENGINE_PORTABLE_H_ + +extern "C" { +#include +#include +#include +} + +#include + +#include "../Type.h" +#include "../Classes.h" + +namespace_begin(AsuraEngine) +namespace_begin(Scripting) + + +/// 需要作为基类,访问userdata和member ref的类继承此类,注意必须是虚继承。 +using Object = Luax::LuaxObject; + +/// 要注册给lua的native类需要继承此模板。BASE指定基类,默认是LuaxObject,如果指定基类必须是LuaxObject的派生类、 +template +using Portable = Luax::LuaxNativeClass; + +namespace_end +namespace_end + +namespace AEScripting = AsuraEngine::Scripting; + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Singleton.hpp b/source/modules/asura-utils/Singleton.hpp new file mode 100644 index 0000000..9bb7336 --- /dev/null +++ b/source/modules/asura-utils/Singleton.hpp @@ -0,0 +1,59 @@ +#ifndef _ASURA_SINGLETON_H_ +#define _ASURA_SINGLETON_H_ + +#include "UtilsConfig.h" + +namespace AsuraEngine +{ + + /// + /// 继承Singleton的类在第一次实例化时保存实例,之后如果再次实例化会报错。 + /// + template + class Singleton + { + public: + + static T* Get() + { + // 如果之前没有创建,在这里立即创建一个并保存 + if (!instance) instance = new T; + // 返回实例 + return instance; + } + + static void Destroy() + { + delete instance; + instance = nullptr; + } + + protected: + + Singleton() + { + // 如果有instance,意味着又创建了一个实例,这是错误的。 + ASSERT(!instance); + // 否则,将本实体作为实例 + instance = static_cast(this); + }; + + virtual ~Singleton() {}; + + static T* instance; + + private: + + Singleton(const Singleton& singleton); + + Singleton& operator = (const Singleton& singleton); + + }; + + // 实例初始化为空 + template + T* Singleton::instance = nullptr; + +} + +#endif // _ASURA_SINGLETON_H_ \ No newline at end of file diff --git a/source/modules/asura-utils/StringMap.cpp b/source/modules/asura-utils/StringMap.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/StringMap.hpp b/source/modules/asura-utils/StringMap.hpp new file mode 100644 index 0000000..15d28ee --- /dev/null +++ b/source/modules/asura-utils/StringMap.hpp @@ -0,0 +1,29 @@ +#ifndef _ASURA_ENGINE_STRINGMAP_H_ +#define _ASURA_ENGINE_STRINGMAP_H_ + +#include + +namespace AsuraEngine +{ + + /// + /// 一个双向一一对应的映射,用来储存shader uniforms、statemathine state parameter的ID。 + /// + template + class StringMap + { + public: + + bool ContainsKey(const key_type& key); + + bool ContainsString(const std::string& str); + + std::string GetStringByKey(const key_type& key); + + key_type GetKeyByString(const std::string& str); + + }; + +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Conditional.cpp b/source/modules/asura-utils/Threads/Conditional.cpp new file mode 100644 index 0000000..f86a81e --- /dev/null +++ b/source/modules/asura-utils/Threads/Conditional.cpp @@ -0,0 +1,84 @@ +#include "Conditional.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +Conditional::Conditional() + : m_Waiting(0) + , m_Signals(0) +{ +} + +Conditional::~Conditional() +{ +} + +void Conditional::Signal() +{ + m_Mutex.Lock(); + if (m_Waiting > m_Signals) + { + ++m_Signals; + signal(m_WaitSem); + m_Mutex.Unlock(); + wait(m_DoneSem); + } + else + { + m_Mutex.Unlock(); + } +} + +void Conditional::Broadcast() +{ + m_Mutex.Lock(); + if (m_Waiting> m_Signals) { + int i, num_waiting; + + num_waiting = (m_Waiting - m_Signals); + m_Signals = m_Waiting; + for (i = 0; i < num_waiting; ++i) { + signal(m_WaitSem); + } + m_Mutex.Unlock(); + for (i = 0; i < num_waiting; ++i) { + wait(m_DoneSem); + } + } + else { + m_Mutex.Unlock(); + } + +} + +bool Conditional::Wait(Mutex* mutex, int timeout /*= ASURA_MUTEX_MAXWAIT*/) +{ + bool retval; + + m_Mutex.Lock(); + ++m_Waiting; + m_Mutex.Unlock(); + + mutex->Unlock(); + + retval = wait(m_WaitSem, timeout); + + m_Mutex.Lock(); + if (m_Signals > 0) { + if (!retval) { + wait(m_WaitSem); + } + signal(m_DoneSem); + + --m_Signals; + } + --m_Waiting; + m_Mutex.Unlock(); + + m_Mutex.Lock(); + + return retval; +} + +namespace_end +namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Conditional.h b/source/modules/asura-utils/Threads/Conditional.h new file mode 100644 index 0000000..7a99ea1 --- /dev/null +++ b/source/modules/asura-utils/Threads/Conditional.h @@ -0,0 +1,41 @@ +#ifndef _ASURA_CONDITIONAL_H_ +#define _ASURA_CONDITIONAL_H_ + +#include + +#include "Mutex.h" +#include "Semaphore.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +/// +/// 条件变量 +/// +class Conditional +{ +public: + + Conditional(); + ~Conditional(); + + void Signal(); + void Broadcast(); + bool Wait(Mutex* mutex, int timeout = ASURA_MUTEX_MAXWAIT); + +private: + + Mutex m_Mutex; + + Semaphore m_WaitSem; + Semaphore m_DoneSem; + + int m_Waiting; + int m_Signals; + +}; + +namespace_end +namespace_end + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Coroutine.cpp b/source/modules/asura-utils/Threads/Coroutine.cpp new file mode 100644 index 0000000..5c4ab68 --- /dev/null +++ b/source/modules/asura-utils/Threads/Coroutine.cpp @@ -0,0 +1,15 @@ +#include "coroutine.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +/* +Coroutine::Coroutine() +{ + +} +*/ + + +namespace_end +namespace_end diff --git a/source/modules/asura-utils/Threads/Coroutine.h b/source/modules/asura-utils/Threads/Coroutine.h new file mode 100644 index 0000000..cdb21f8 --- /dev/null +++ b/source/modules/asura-utils/Threads/Coroutine.h @@ -0,0 +1,40 @@ +#ifndef _ASURA_COROUTINE_H_ +#define _ASURA_COROUTINE_H_ + +#include + +#include "../Scripting/Portable.hpp" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +/// +/// lua协程,用来做一些逻辑并发操作。 +/// +class Coroutine ASURA_FINAL + : public AEScripting::Portable +{ +public: + + LUAX_DECL_FACTORY(Coroutine); + + + +private: + + /// + /// 当前协程的state + /// + lua_State* m_ThreadState; + + LUAX_DECL_METHOD(_New); + LUAX_DECL_METHOD(_Run); + +}; + +namespace_end +namespace_end + +namespace AEThreading = AsuraEngine::Threads; + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Mutex.cpp b/source/modules/asura-utils/Threads/Mutex.cpp new file mode 100644 index 0000000..501a0ed --- /dev/null +++ b/source/modules/asura-utils/Threads/Mutex.cpp @@ -0,0 +1,105 @@ +#include + +#include "Mutex.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +#define try_create_mutex(impl)\ +if (!m_Impl) \ +{ \ +try \ +{ \ + m_Impl = new impl(); \ +} \ +catch (Exception& e) \ +{ \ + m_Impl = nullptr; \ +} \ +} + +Mutex::Mutex() + : m_Impl(nullptr) +{ +#if ASURA_MUTEX_WIN32_CRITICLE_SECTION + try_create_mutex(MutexImplWin32_CS); +#endif +#if ASURA_MUTEX_WIN32_KERNAL_MUTEX + try_create_mutex(MutexImplWin32_KM); +#endif + ASSERT(m_Impl); +} + +Mutex::~Mutex() +{ + if(m_Impl) + delete m_Impl; +} + +void Mutex::Lock() +{ + ASSERT(m_Impl); + + m_Impl->Lock(); +} + +void Mutex::Unlock() +{ + ASSERT(m_Impl); + + m_Impl->Unlock(); +} + +#if ASURA_MUTEX_WIN32_CRITICLE_SECTION + +MutexImplWin32_CS::MutexImplWin32_CS() +{ + ::InitializeCriticalSection(&m_Mutex); +} + +MutexImplWin32_CS::~MutexImplWin32_CS() +{ + ::DeleteCriticalSection(&m_Mutex); +} + +void MutexImplWin32_CS::Lock() +{ + ::EnterCriticalSection(&m_Mutex); +} + +void MutexImplWin32_CS::Unlock() +{ + ::LeaveCriticalSection(&m_Mutex); +} + +#endif // ASURA_MUTEX_WIN32_CRITICLE_SECTION + +#if ASURA_MUTEX_WIN32_KERNAL_MUTEX + +MutexImplWin32_KM::MutexImplWin32_KM() +{ + m_Handle = ::CreateMutex(NULL, FALSE, NULL); + if (!m_Handle) + throw Exception("Cant use win32 mutex."); +} + +MutexImplWin32_KM::~MutexImplWin32_KM() +{ + ::CloseHandle(m_Handle); + m_Handle = NULL; +} + +void MutexImplWin32_KM::Lock() +{ + ::WaitForSingleObject(m_Handle, ASURA_MUTEX_MAXWAIT); +} + +void MutexImplWin32_KM::Unlock() +{ + ::ReleaseMutex(m_Handle); +} + +#endif // ASURA_MUTEX_WIN32_KERNAL_MUTEX + +namespace_end +namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Mutex.h b/source/modules/asura-utils/Threads/Mutex.h new file mode 100644 index 0000000..4269c05 --- /dev/null +++ b/source/modules/asura-utils/Threads/Mutex.h @@ -0,0 +1,128 @@ +#ifndef _ASURA_MUTEX_H_ +#define _ASURA_MUTEX_H_ + +#include +#include + +#include "../UtilsConfig.h" + +#if ASURA_THREAD_WIN32 +#include +#endif + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +#define ASURA_MUTEX_MAXWAIT (~(uint32)0) + +class MutexImpl; + +class Mutex +{ +public: + + Mutex(); + ~Mutex(); + + void Lock(); + void Unlock(); + +private: + + // 禁止复制 + Mutex(const Mutex&); + Mutex& operator=(const Mutex&); + + MutexImpl* m_Impl; + +}; + +class _mutex_locker +{ +public: + _mutex_locker(Mutex& mutex) + : m(mutex) + { + m.Lock(); + }; + ~_mutex_locker() + { + m.Unlock(); + } + operator bool() { return false; }; +private: + void* operator new(size_t); + Mutex& m; +}; + +#define lock(m) \ +if(_mutex_locker _asura_mutex_locker = m){} else + +ASURA_ABSTRACT class MutexImpl +{ +public: + + MutexImpl() {}; + virtual ~MutexImpl() {}; + + virtual void Lock() = 0; + virtual void Unlock() = 0; + +}; + +#if ASURA_MUTEX_WIN32_CRITICLE_SECTION + +//https://blog.csdn.net/l799623787/article/details/18259949 +class MutexImplWin32_CS ASURA_FINAL : public MutexImpl +{ +public: + + MutexImplWin32_CS(); + ~MutexImplWin32_CS(); + + void Lock() override; + void Unlock() override; + +private: + + //HANDLE m_Handle; + CRITICAL_SECTION m_Mutex; + +}; + +#endif // ASURA_MUTEX_WIN32_CRITICLE_SECTION + +#if ASURA_MUTEX_WIN32_KERNAL_MUTEX + +class MutexImplWin32_KM ASURA_FINAL : public MutexImpl +{ +public: + + MutexImplWin32_KM(); + ~MutexImplWin32_KM(); + + void Lock() override; + void Unlock() override; + +private: + + HANDLE m_Handle; + +}; + +#endif // ASURA_MUTEX_WIN32_KERNAL_MUTEX + +#if ASURA_THREAD_STD + +class MutexImplSTD ASURA_FINAL : public MutexImpl +{ +}; + +#endif // ASURA_THREAD_STD + +namespace_end +namespace_end + +namespace AEThreading = AsuraEngine::Threads; + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Semaphore.cpp b/source/modules/asura-utils/Threads/Semaphore.cpp new file mode 100644 index 0000000..a222f3d --- /dev/null +++ b/source/modules/asura-utils/Threads/Semaphore.cpp @@ -0,0 +1,99 @@ +#include "../Exceptions/Exception.h" +#include "../Type.h" + +#include "Mutex.h" +#include "Semaphore.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +#define try_create_semaphore(impl) \ +if (!m_Impl) \ +{ \ + try \ + { \ + m_Impl = new impl(init_count); \ + } \ + catch (Exception& e) \ + { \ + m_Impl = nullptr; \ + } \ +} + +Semaphore::Semaphore(unsigned int init_count) + : m_Impl(nullptr) +{ +#ifdef ASURA_THREAD_WIN32 + try_create_semaphore(SemaphoreWin32); +#endif + //ASSERT(m_Impl); +} + +Semaphore::~Semaphore() +{ + if (m_Impl) delete m_Impl; +} + +void Semaphore::Signal() +{ + ASSERT(m_Impl); + m_Impl->Signal(); +} + +bool Semaphore::Wait(int timeout /*= ASURA_MUTEX_MAXWAIT*/) +{ + ASSERT(m_Impl); + return m_Impl->Wait(timeout); +} + +#if ASURA_THREAD_WIN32 + +SemaphoreWin32::SemaphoreWin32(unsigned int init_value) + : SemaphoreImpl(init_value) +{ + // UINT_MAX get error. + m_Sem = CreateSemaphore(NULL, init_value, INT_MAX, NULL); + if (!m_Sem) + { + int errorCode = GetLastError(); + throw Exception("Cant use win32 semaphore. Error code: %d.", errorCode); + } +} + +SemaphoreWin32::~SemaphoreWin32() +{ + CloseHandle(m_Sem); +} + +void SemaphoreWin32::Signal() +{ + InterlockedIncrement(&m_Count); + if (ReleaseSemaphore(m_Sem, 1, NULL) == FALSE) + InterlockedDecrement(&m_Count); +} + +bool SemaphoreWin32::Wait(int timeout) +{ + int result; + result = WaitForSingleObject(m_Sem, timeout); + if (result == WAIT_OBJECT_0) + { + InterlockedDecrement(&m_Count); + return true; + } + else if(result == WAIT_TIMEOUT) + { + // 超时 + return false; + } + else + { + // 未知错误 + throw Exception("WaitForSingleObject() failed"); + } +} + +#endif // ASURA_THREAD_WIN32 + +namespace_end +namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Semaphore.h b/source/modules/asura-utils/Threads/Semaphore.h new file mode 100644 index 0000000..41b1fd2 --- /dev/null +++ b/source/modules/asura-utils/Threads/Semaphore.h @@ -0,0 +1,68 @@ +#ifndef _ASURA_SEMAPHORE_H_ +#define _ASURA_SEMAPHORE_H_ + +#include "../UtilsConfig.h" + +#if ASURA_THREAD_WIN32 +#include +#endif + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +class SemaphoreImpl; + +/// +/// 信号量 +/// +class Semaphore +{ +public: + + Semaphore(unsigned int init_count = 1); + ~Semaphore(); + + void Signal(); + bool Wait(int timeout = ASURA_MUTEX_MAXWAIT); + +private: + SemaphoreImpl* m_Impl; +}; + +class SemaphoreImpl +{ +public: + SemaphoreImpl(unsigned int init_value) + : m_Count(init_value) + { + }; + virtual ~SemaphoreImpl() {}; + virtual void Signal() = 0; + virtual bool Wait(int timeout) = 0; + inline int Current() { return m_Count; } +protected: + unsigned int m_Count; +}; + +#define wait(sem, ...) sem.Wait(__VA_ARGS__) +#define signal(sem) sem.Signal() + +#if ASURA_THREAD_WIN32 + +class SemaphoreWin32 : public SemaphoreImpl +{ +public: + SemaphoreWin32(unsigned int init_value); + ~SemaphoreWin32(); + void Signal() override; + bool Wait(int timeout) override; +private: + HANDLE m_Sem; +}; + +#endif // ASURA_THREAD_WIN32 + +namespace_end +namespace_end + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Task.cpp b/source/modules/asura-utils/Threads/Task.cpp new file mode 100644 index 0000000..9666cc6 --- /dev/null +++ b/source/modules/asura-utils/Threads/Task.cpp @@ -0,0 +1,10 @@ +#include "task.h" +#include "../scripting/Portable.hpp" + +using namespace AEScripting; + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +namespace_end +namespace_end diff --git a/source/modules/asura-utils/Threads/Task.h b/source/modules/asura-utils/Threads/Task.h new file mode 100644 index 0000000..b871303 --- /dev/null +++ b/source/modules/asura-utils/Threads/Task.h @@ -0,0 +1,43 @@ +#ifndef _ASURA_THRAD_TASK_H_ +#define _ASURA_THRAD_TASK_H_ + +#include +#include +#include + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +/// +/// 希望放在另一个线程处理的任务,继承Task并重写Execute方法。 +/// +ASURA_ABSTRACT class Task : public AEScripting::Object +{ +public: + + Task() {}; + virtual ~Task() {}; + + /// + /// 执行任务,完成后返回true,调用回调函数。 + /// + virtual bool Execute() = 0; + + /// + /// 调用回调。在invoke thread里面回调。 + /// + virtual void Invoke(lua_State* invokeThreaad) = 0; + +protected: + + // 取回调函数 + Luax::LuaxMemberRef m_Callback; + +}; + +namespace_end +namespace_end + +namespace AEThreading = AsuraEngine::Threads; + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Thread.cpp b/source/modules/asura-utils/Threads/Thread.cpp new file mode 100644 index 0000000..1153912 --- /dev/null +++ b/source/modules/asura-utils/Threads/Thread.cpp @@ -0,0 +1,287 @@ +#include "Thread.h" + +#include "ThreadImplWin32.h" +#include "ThreadImplPosix.h" +#include "ThreadImplSdl.h" +#include "ThreadImplStd.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +Thread::Thread(lua_State* luaThread, ThreadType type /*= THREAD_TYPE_DEFERRED*/, uint sleepTime /*= 0*/, const std::string& name /*= ""*/) + : m_Name(name) + , m_State(THREAD_STATE_IDLE) + , m_Type(type) + , m_LuaThread(luaThread) + , m_CallbackThread(nullptr) + , m_SleepTime(sleepTime) +{ + LUAX_STATE(luaThread); + if (type == THREAD_TYPE_IMMEDIATE) + { + Luax::LuaxVM* vm = state.GetVM(); + ASSERT(vm); + m_CallbackThread = vm->CreateThread(); + ASSERT(m_CallbackThread); + SetLuaxMemberRef(state, m_CallbackThreadRef, -1); + state.Pop(); // callback thread + } +} + +Thread::~Thread() +{ + if (m_Impl) + { + delete m_Impl; + m_Impl = nullptr; + } +} + +bool Thread::AddTask(Task* task) +{ + lock(m_TaskQueueMutex) + { + task->Retain(); + m_TaskQueue.push(task); + } + return true; +} + +uint Thread::GetTaskCount() +{ + return m_TaskQueue.size(); +} + +void Thread::Idle() +{ + m_State = THREAD_STATE_IDLE; +} + +#define try_start_thread(impl)\ +if (!m_Impl) \ +{ \ +m_Impl = new impl(); \ +if (!m_Impl->Start(this, stacksize)) \ +{ \ + delete m_Impl; \ + m_Impl = nullptr; \ +} \ +} + +bool Thread::Start(bool isDaemon /*= true*/, uint32 stacksize /*= 0*/) +{ + if (m_State != THREAD_STATE_IDLE) + return false; + + // 如果已经存在一个之前创建的,关闭它。 + if (m_Impl) + { + delete m_Impl; + m_Impl = nullptr; + } + +#if ASURA_THREAD_WIN32 + try_start_thread(ThreadImplWin32); +#endif + + if (!m_Impl) + return false; + + m_IsDaemon = isDaemon; + m_StateMutex.Lock(); + m_State = THREAD_STATE_RUNNING; + m_StateMutex.Unlock(); +} + +void Thread::Pause() +{ + ASSERT(m_Impl); + + lock(m_StateMutex) + { + m_State = THREAD_STATE_PAUSED; + } +} + +void Thread::Resume() +{ + ASSERT(m_Impl); + + lock(m_StateMutex) + { + if (m_State == THREAD_STATE_PAUSED) + m_State = THREAD_STATE_RUNNING; + } +} + +void Thread::Stop() +{ + ASSERT(m_Impl); + + lock(m_StateMutex) + { + m_State = THREAD_STATE_STOPPED; + } +} + +void Thread::PauseSync() +{ + Pause(); + wait(m_SemPause); +} + +void Thread::ResumeSync() +{ + Resume(); + wait(m_SemResume); +} + +void Thread::StopSync() +{ + Stop(); + wait(m_SemStop); +} + +void Thread::Join() +{ + ASSERT(m_Impl); + m_Impl->Join(); +} + +ThreadState Thread::GetState() +{ + ThreadState state; + lock(m_StateMutex) + { + state = m_State; + } + return state; +} + +bool Thread::IsRunning() +{ + ASSERT(m_Impl); + + return GetState() == THREAD_STATE_RUNNING; +} + +bool Thread::IsPaused() +{ + ASSERT(m_Impl); + + return GetState() == THREAD_STATE_PAUSED; +} + +bool Thread::IsStopped() +{ + ASSERT(m_Impl); + + return GetState() == THREAD_STATE_STOPPED; +} + +bool Thread::IsCurrent() +{ + ASSERT(m_Impl); + + return m_Impl->IsCurrent(); +} + +const std::string& Thread::GetName() +{ + return m_Name; +} + +int Thread::Process() +{ + LUAX_STATE(m_LuaThread); + + do{ + if (IsRunning()) + { + while (!m_TaskQueue.empty()) + { + Task* task = m_TaskQueue.front(); + if (task && task->Execute()) + { + if (m_Type == THREAD_TYPE_DEFERRED) + { + m_FinishedMutex.Lock(); + task->Retain(); + m_FinishedTasks.push(task); + m_FinishedMutex.Unlock(); + } + else if (m_Type == THREAD_TYPE_IMMEDIATE) + { + // unsafe + task->Invoke(m_CallbackThread); + this->LuaxRelease(state, task); + } + m_TaskQueueMutex.Lock(); + m_TaskQueue.pop(); + task->Release(); + m_TaskQueueMutex.Unlock(); + } + } + } + + // 退出循环 + if (IsStopped()) + break; + + // 降低CPU使用率 + Sleep(m_SleepTime); + + } while (m_IsDaemon); + + // 非守护线程,先切到stop状态 + if (!m_IsDaemon) + Stop(); + + signal(m_SemStop); + + // 重置状态为Idle + Idle(); + + return 0; +} + +/// +/// 延迟模式主动发布回调、 +/// +void Thread::Dispatch() +{ + if (m_Type != THREAD_TYPE_DEFERRED) + return; + + LUAX_STATE(m_LuaThread); + while (!m_FinishedTasks.empty()) + { + Task* task = m_FinishedTasks.front(); + if (task) + { + task->Invoke(m_LuaThread); + this->LuaxRelease(state, task); + m_FinishedMutex.Lock(); + m_FinishedTasks.pop(); + task->Release(); + m_FinishedMutex.Unlock(); + } + } +} + +void Thread::Sleep(uint ms) +{ + ASSERT(m_Impl); + if (m_Impl) + { + m_Impl->Sleep(ms); + } +} + +void Thread::SetSleepTime(uint ms) +{ + m_SleepTime = ms; +} + +namespace_end +namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Thread.h b/source/modules/asura-utils/Threads/Thread.h new file mode 100644 index 0000000..bc6f14e --- /dev/null +++ b/source/modules/asura-utils/Threads/Thread.h @@ -0,0 +1,222 @@ +#ifndef _ASURA_THREAD_H_ +#define _ASURA_THREAD_H_ + +#include +#include + +#include + +#include "Task.h" +#include "Mutex.h" +#include "Semaphore.h" +#include "Threadable.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +class ThreadImpl; + +/// +/// 线程的几种不同的实现: +/// 1: Deferred(延迟模式),线程上的任务完成后,需要手动在主线程调用Dispatch方法, +/// 在主线程调回调函数,将发布从异步改为同步操作,解决主lua_State冲突的问题。 +/// 2: Immediate(立即模式),每一个线程维护一个lua_newthread创建出来的lua_State。 +/// 回调函数在不同的lua_State中调用,避免不同的线程访问同一个lua_State。 +/// +enum ThreadType +{ + THREAD_TYPE_DEFERRED, + THREAD_TYPE_IMMEDIATE, // unsafe +}; + +enum ThreadState +{ + THREAD_STATE_IDLE, ///< 闲置,还未创建内核对象 + THREAD_STATE_RUNNING, ///< 正在运行循环 + THREAD_STATE_PAUSED, ///< 在循环中暂停 + THREAD_STATE_STOPPED, ///< 退出循环 +}; + +/// +/// 线程主体,每个线程维护一个task queue。 +/// +class Thread ASURA_FINAL + : public AEScripting::Portable + , public Threadable +{ +public: + + LUAX_DECL_FACTORY(Thread); + + Thread(lua_State* luaThread, ThreadType type = THREAD_TYPE_DEFERRED, uint sleepTime = 1, const std::string& name = ""); + ~Thread(); + + bool AddTask(Task* task); + /// + /// 获得等待处理的任务数 + /// + uint GetTaskCount(); + + void Idle(); + + /// + /// 创建内核对象,并运行。如果是daemon,会等待手动stop。否则会在某时刻队列完成后自动stop。 + /// + bool Start(bool daemon = true, uint32 stacksize = 0); + + /// + /// 非同步线程控制,不是实时的。可能需要在主线程里使用Is函数确认到达指定状态。 + /// + void Pause(); + void Resume(); + void Stop(); + + /// + /// 同步线程控制,会等返回来信号后继续向下执行。会造成主线程等待。 + /// + void PauseSync(); + void ResumeSync(); + void StopSync(); + + /// + /// 父线程等待本线程结束后才继续执行。 + /// + void Join(); + + ThreadState GetState(); + + /// + /// 逻辑层面的线程状态: + /// 1: Idle(空闲),线程创建后的默认状态,可以随时加任务并且Start。 + /// 2: Running(运行),内核对象呗创建,已经处于内核调度中,并处理具体Task。 + /// 3: Paused(暂停),依然存在于内核中,但是跳过了对任务的处理,逻辑上暂停。 + /// 4: Stopped(停止),依然存在于内核中,但是已经无法继续处理任务。 + /// + bool IsIdle(); + bool IsRunning(); + bool IsPaused(); + bool IsStopped(); + + bool IsCurrent(); + + /// + /// 执行任务队列。 + /// + int Process() override; + + const std::string& GetName(); + + /// + /// 回调。 + /// + void Dispatch(); + + /// + /// 休眠函数 + /// + void Sleep(uint ms); + + /// + /// 设置休眠时间 + /// + void SetSleepTime(uint ms); + +private: + + //----------------------------------------------------------------------------// + + LUAX_DECL_ENUM(ThreadType); + LUAX_DECL_ENUM(ThreadState); + + LUAX_DECL_METHOD(_New); + LUAX_DECL_METHOD(_AddTask); + LUAX_DECL_METHOD(_Start); + LUAX_DECL_METHOD(_Idle); + LUAX_DECL_METHOD(_Pause); + LUAX_DECL_METHOD(_Resume); + LUAX_DECL_METHOD(_Stop); + LUAX_DECL_METHOD(_Join); + LUAX_DECL_METHOD(_IsRunning); + LUAX_DECL_METHOD(_IsPaused); + LUAX_DECL_METHOD(_IsStopped); + LUAX_DECL_METHOD(_IsCurrent); + LUAX_DECL_METHOD(_Sleep); + LUAX_DECL_METHOD(_Dispatch); + LUAX_DECL_METHOD(_GetName); + LUAX_DECL_METHOD(_GetType); + LUAX_DECL_METHOD(_GetState); + LUAX_DECL_METHOD(_SetSleepTime); + + //----------------------------------------------------------------------------// + + ThreadImpl* m_Impl; + + lua_State* m_LuaThread; + + /// + /// 此次运行是否是守护模式。 + /// + bool m_IsDaemon; + + std::string m_Name; + ThreadType m_Type; + uint m_SleepTime; + + ThreadState m_State; + Mutex m_StateMutex; + + /// + /// 同步控制相关的信号量 + /// + Semaphore m_SemPause; + Semaphore m_SemResume; + Semaphore m_SemStop; + + /// + /// 待处理的任务队列。 + /// + std::queue m_TaskQueue; + Mutex m_TaskQueueMutex; + + /// + /// 延迟模式使用 + /// + std::queue m_FinishedTasks; + Mutex m_FinishedMutex; + + /// + /// 立即模式使用,回调使用的lua线程 + /// + lua_State* m_CallbackThread; + Luax::LuaxMemberRef m_CallbackThreadRef; + +}; + +/// +/// 线程的具体实现,对用户是透明的,一共准备了四种策略: +/// 1: win32 +/// 2: posix +/// 3: SDL +/// 4: std::thread +/// +ASURA_ABSTRACT class ThreadImpl +{ +public: + ThreadImpl() {}; + virtual ~ThreadImpl() {}; + + virtual bool Start(Threadable* thread, uint32 stacksize = 0) = 0; + virtual void Join() = 0; + virtual void Kill() = 0; + + virtual void Sleep(uint ms) = 0; + + virtual bool IsRunning() = 0; + virtual bool IsCurrent() = 0; + +}; + +namespace_end +namespace_end + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/ThreadImplPosix.cpp b/source/modules/asura-utils/Threads/ThreadImplPosix.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Threads/ThreadImplPosix.h b/source/modules/asura-utils/Threads/ThreadImplPosix.h new file mode 100644 index 0000000..3089f0a --- /dev/null +++ b/source/modules/asura-utils/Threads/ThreadImplPosix.h @@ -0,0 +1,2 @@ +#include + diff --git a/source/modules/asura-utils/Threads/ThreadImplSDL.cpp b/source/modules/asura-utils/Threads/ThreadImplSDL.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Threads/ThreadImplSDL.h b/source/modules/asura-utils/Threads/ThreadImplSDL.h new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Threads/ThreadImplStd.cpp b/source/modules/asura-utils/Threads/ThreadImplStd.cpp new file mode 100644 index 0000000..e69de29 diff --git a/source/modules/asura-utils/Threads/ThreadImplStd.h b/source/modules/asura-utils/Threads/ThreadImplStd.h new file mode 100644 index 0000000..452f569 --- /dev/null +++ b/source/modules/asura-utils/Threads/ThreadImplStd.h @@ -0,0 +1,41 @@ +#ifndef _ASURA_THREAD_STD_H_ +#define _ASURA_THREAD_STD_H_ + +#include "../UtilsConfig.h" + +#if ASURA_THREAD_STD + +#include + +#include "Thread.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +/// +/// Thread的std::thread实现。 +/// +class ThreadImplSTD : public ThreadImpl +{ +public: + + ThreadImplSTD(); + ~ThreadImplSTD(); + + bool Start(Threadable* thread, uint32 stacksize) override; + void Join() override; + void Kill() override; + + bool IsRunning() override; + bool IsCurrent() override; + +private: + +}; + +namespace_end +namespace_end + +#endif // #if ASURA_THREAD_STD + +#endif // _ASURA_THREAD_STD_H_ \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/ThreadImplWin32.cpp b/source/modules/asura-utils/Threads/ThreadImplWin32.cpp new file mode 100644 index 0000000..2467f87 --- /dev/null +++ b/source/modules/asura-utils/Threads/ThreadImplWin32.cpp @@ -0,0 +1,77 @@ +#include "ThreadImplWin32.h" +#include "Thread.h" + +#include + +#if ASURA_THREAD_WIN32 + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +static DWORD WINAPI _thread_win32_runner(LPVOID param) +{ + Threadable* thread = (Threadable*)param; + return thread->Process(); // 尾调用 +} + +ThreadImplWin32::ThreadImplWin32() +{ +} + +ThreadImplWin32::~ThreadImplWin32() +{ + if (!m_Handle) return; + ::CloseHandle(m_Handle); + m_Handle = 0; +} + +bool ThreadImplWin32::Start(Threadable* thread, uint32 stacksize/*=0*/) +{ + assert(!IsRunning()); + m_Handle = ::CreateThread( + NULL + , stacksize + , _thread_win32_runner + , thread + , 0 /*创建后立即进行调度*/ + , NULL); + + return m_Handle; +} + +void ThreadImplWin32::Join() +{ + // 父线程等待此线程返回 + ::WaitForSingleObject(m_Handle, INFINITE); +} + +void ThreadImplWin32::Kill() +{ + ::TerminateThread(m_Handle, FALSE); +} + +void ThreadImplWin32::Sleep(uint ms) +{ + ::Sleep(ms); +} + +bool ThreadImplWin32::IsRunning() +{ + if (m_Handle) { + DWORD exitCode = 0; + // https://blog.csdn.net/yuanmeng567/article/details/19485719 + ::GetExitCodeThread(m_Handle, &exitCode); + return exitCode == STILL_ACTIVE; + } + return false; +} + +bool ThreadImplWin32::IsCurrent() +{ + return m_Handle == ::GetCurrentThread(); +} + +namespace_end +namespace_end + +#endif // ASURA_THREAD_WIN32 \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/ThreadImplWin32.h b/source/modules/asura-utils/Threads/ThreadImplWin32.h new file mode 100644 index 0000000..93ca477 --- /dev/null +++ b/source/modules/asura-utils/Threads/ThreadImplWin32.h @@ -0,0 +1,44 @@ +#ifndef _ASURA_THREAD_WIN32_H__ +#define _ASURA_THREAD_WIN32_H__ + +#include "../UtilsConfig.h" + +#if ASURA_THREAD_WIN32 + +#include + +#include "thread.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +/// +/// Thread的win32实现。 +/// +class ThreadImplWin32 : public ThreadImpl +{ +public: + + ThreadImplWin32(); + ~ThreadImplWin32(); + + bool Start(Threadable* thread, uint32 stacksize) override; + void Join() override; + void Kill() override; + + void Sleep(uint ms) override; + + bool IsRunning() override; + bool IsCurrent() override; + +private: + + HANDLE m_Handle; + +}; + +namespace_end +namespace_end + +#endif // #if ASURA_THREAD_WIN32 +#endif // _ASURA_THREAD_WIN32_H__ \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/Threadable.h b/source/modules/asura-utils/Threads/Threadable.h new file mode 100644 index 0000000..fce7350 --- /dev/null +++ b/source/modules/asura-utils/Threads/Threadable.h @@ -0,0 +1,23 @@ +#ifndef _ASURA_THREADABLE_H_ +#define _ASURA_THREADABLE_H_ + +#include "../Type.h" + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + +ASURA_ABSTRACT class Threadable +{ +public: + + Threadable() {}; + virtual ~Threadable() {}; + + virtual int Process() = 0; + +}; + +namespace_end +namespace_end + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/Threads/binding/_coroutine.cpp b/source/modules/asura-utils/Threads/binding/_coroutine.cpp new file mode 100644 index 0000000..0656079 --- /dev/null +++ b/source/modules/asura-utils/Threads/binding/_coroutine.cpp @@ -0,0 +1,38 @@ +#include "../Coroutine.h" + +using namespace std; + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + + LUAX_REGISTRY(Coroutine) + { + LUAX_REGISTER_METHODS(state, + { "New", _New }, + { "Run", _Run } + ); + } + + LUAX_POSTPROCESS(Coroutine) + { + + } + + // Coroutine.New() + LUAX_IMPL_METHOD(Coroutine, _New) + { + LUAX_STATE(L); + + return 0; + } + + // coroutine:Run() + LUAX_IMPL_METHOD(Coroutine, _Run) + { + LUAX_PREPARE(L, Coroutine); + + return 0; + } + + } +} diff --git a/source/modules/asura-utils/Threads/binding/_thread.cpp b/source/modules/asura-utils/Threads/binding/_thread.cpp new file mode 100644 index 0000000..aaa9e8d --- /dev/null +++ b/source/modules/asura-utils/Threads/binding/_thread.cpp @@ -0,0 +1,208 @@ +#include "../Thread.h" + +using namespace std; + +namespace_begin(AsuraEngine) +namespace_begin(Threads) + + LUAX_REGISTRY(Thread) + { + LUAX_REGISTER_METHODS(state, + { "New", _New }, + { "AddTask", _AddTask }, + { "Start", _Start }, + { "Idle", _Idle }, + { "Pause", _Pause }, + { "Resume", _Resume }, + { "Stop", _Stop }, + { "Join", _Join }, + { "IsRunning", _IsRunning }, + { "IsPaused", _IsPaused }, + { "IsStopped", _IsStopped }, + { "IsCurrent", _IsCurrent }, + { "Sleep", _Sleep }, + { "Dispatch", _Dispatch }, + { "GetName", _GetName }, + { "GetType", _GetType }, + { "GetState", _GetState } + ); + } + + LUAX_POSTPROCESS(Thread) + { + LUAX_REGISTER_ENUM(state, "EThreadType", + { "DEFERRED", THREAD_TYPE_DEFERRED }, + { "IMMEDIATE", THREAD_TYPE_IMMEDIATE } + ); + LUAX_REGISTER_ENUM(state, "EThreadState", + { "IDLE", THREAD_STATE_IDLE }, + { "RUNNING", THREAD_STATE_RUNNING }, + { "PAUSED", THREAD_STATE_PAUSED }, + { "STOPPED", THREAD_STATE_STOPPED } + ); + } + + // thread = Thread.New(thread_type, sleepTime, name) + LUAX_IMPL_METHOD(Thread, _New) + { + LUAX_STATE(L); + + ThreadType type = (ThreadType)state.GetValue(1, THREAD_TYPE_DEFERRED); + uint sleepTime = state.GetValue(2,1); + cc8* name = state.GetValue(3, ""); + + Thread* thread = new Thread(state, type, sleepTime, name); + thread->PushLuaxUserdata(state); + + return 1; + } + + // thread:AddTask(task) + LUAX_IMPL_METHOD(Thread, _AddTask) + { + LUAX_PREPARE(L, Thread); + + Task* task = state.GetUserdata(2); + self->AddTask(task); + self->LuaxRetain(state, task); + return 0; + } + + // successed = thread:Start(isDeamon, stackSize) + LUAX_IMPL_METHOD(Thread, _Start) + { + LUAX_PREPARE(L, Thread); + + bool isDaemon = state.GetValue(2, true); + uint stackSize = state.GetValue(3, 0); + + state.Push(self->Start(isDaemon, stackSize)); + return 1; + } + + // thread:Idle() + LUAX_IMPL_METHOD(Thread, _Idle) + { + LUAX_PREPARE(L, Thread); + self->Idle(); + return 0; + } + + // thread:Pause() + LUAX_IMPL_METHOD(Thread, _Pause) + { + LUAX_PREPARE(L, Thread); + self->Pause(); + return 0; + } + + // thread:Resume() + LUAX_IMPL_METHOD(Thread, _Resume) + { + LUAX_PREPARE(L, Thread); + self->Resume(); + return 0; + } + + // thread:Stop() + LUAX_IMPL_METHOD(Thread, _Stop) + { + LUAX_PREPARE(L, Thread); + self->Stop(); + return 0; + } + + // thread:Join() + LUAX_IMPL_METHOD(Thread, _Join) + { + LUAX_PREPARE(L, Thread); + self->Join(); + return 0; + } + + // thread:IsRunning() + LUAX_IMPL_METHOD(Thread, _IsRunning) + { + LUAX_PREPARE(L, Thread); + state.Push(self->IsRunning()); + return 1; + } + + // thread:IsPaused() + LUAX_IMPL_METHOD(Thread, _IsPaused) + { + LUAX_PREPARE(L, Thread); + state.Push(self->IsPaused()); + return 1; + } + + // thread:IsStopped() + LUAX_IMPL_METHOD(Thread, _IsStopped) + { + LUAX_PREPARE(L, Thread); + state.Push(self->IsStopped()); + return 1; + } + + // thread:IsCurrent() + LUAX_IMPL_METHOD(Thread, _IsCurrent) + { + LUAX_PREPARE(L, Thread); + state.Push(self->IsCurrent()); + return 1; + } + + // Thread.Sleep(ms) + LUAX_IMPL_METHOD(Thread, _Sleep) + { + LUAX_STATE(L); + uint ms = state.GetValue(1, 0); +#ifdef _WIN32 + ::Sleep(ms); +#endif + return 0; + } + + // thread:Dispatch() + LUAX_IMPL_METHOD(Thread, _Dispatch) + { + LUAX_PREPARE(L, Thread); + self->Dispatch(); + return 0; + } + + // thread:GetName() + LUAX_IMPL_METHOD(Thread, _GetName) + { + LUAX_PREPARE(L, Thread); + state.Push(self->GetName()); + return 1; + } + + // thread:GetType() + LUAX_IMPL_METHOD(Thread, _GetType) + { + LUAX_PREPARE(L, Thread); + state.Push(self->m_Type); + return 1; + } + + // thread:GetState() + LUAX_IMPL_METHOD(Thread, _GetState) + { + LUAX_PREPARE(L, Thread); + state.Push(self->m_State); + return 1; + } + + // thread:SetSleepTime(sleepTime) + LUAX_IMPL_METHOD(Thread, _SetSleepTime) + { + LUAX_PREPARE(L, Thread); + uint time = state.CheckValue(2); + self->SetSleepTime(time); + return 0; + } + + } +} diff --git a/source/modules/asura-utils/Type.h b/source/modules/asura-utils/Type.h new file mode 100644 index 0000000..f7e54c6 --- /dev/null +++ b/source/modules/asura-utils/Type.h @@ -0,0 +1,34 @@ +#ifndef _ASURA_UTILS_TYPE_H_ +#define _ASURA_UTILS_TYPE_H_ + +#include +#include + +#include "asura-base/Config.h" + +namespace AsuraEngine +{ + + //--------------------------------------------------------------------------------// + + typedef int8_t int8; + typedef uint8_t uint8; + //typedef uint8 byte; + typedef char byte; + typedef int16_t int16; + typedef uint16_t uint16; + typedef int32_t int32; + typedef uint32_t uint32; + typedef int64_t int64; + typedef uint64_t uint64; + + typedef uint32_t uint; + typedef int32_t sint; + + typedef std::size_t size_t; + + typedef const char cc8; + +} // namespace AsuraEngine + +#endif // _ASURA_CONFIG_H_ \ No newline at end of file diff --git a/source/modules/asura-utils/Utils.h b/source/modules/asura-utils/Utils.h new file mode 100644 index 0000000..dfcd2a6 --- /dev/null +++ b/source/modules/asura-utils/Utils.h @@ -0,0 +1,6 @@ +#ifndef _ASURA_UTILS_H_ +#define _ASURA_UTILS_H_ + +#include "UtilsModule.h" + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/UtilsConfig.h b/source/modules/asura-utils/UtilsConfig.h new file mode 100644 index 0000000..89a605d --- /dev/null +++ b/source/modules/asura-utils/UtilsConfig.h @@ -0,0 +1,13 @@ +#ifndef _ASURA_UTILS_CONFIG_H_ +#define _ASURA_UTILS_CONFIG_H_ + +// 基本的编译配置 +#include "asura-base/Config.h" + +#define ASURA_THREAD_WIN32 1 +#define ASURA_THREAD_STD 1 + +#define ASURA_MUTEX_WIN32_CRITICLE_SECTION 1 +#define ASURA_MUTEX_WIN32_KERNAL_MUTEX 1 + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/UtilsModule.cpp b/source/modules/asura-utils/UtilsModule.cpp new file mode 100644 index 0000000..5735270 --- /dev/null +++ b/source/modules/asura-utils/UtilsModule.cpp @@ -0,0 +1,25 @@ +#include "UtilsModule.h" + +using namespace AsuraEngine::IO; +using namespace AsuraEngine::Threads; + +namespace AsuraEngine +{ + + void UtilsModule::Initialize(Luax::LuaxState& state) + { + // IO + LUAX_REGISTER_SINGLETON(state, Filesystem); + LUAX_REGISTER_FACTORY(state, IOTask); + LUAX_REGISTER_FACTORY(state, DataBuffer); + LUAX_REGISTER_FACTORY(state, FileData); + LUAX_REGISTER_FACTORY(state, File); + // Threads + LUAX_REGISTER_FACTORY(state, Thread); + } + + void UtilsModule::Finalize(Luax::LuaxState& state) + { + } + +} \ No newline at end of file diff --git a/source/modules/asura-utils/UtilsModule.h b/source/modules/asura-utils/UtilsModule.h new file mode 100644 index 0000000..b61dca9 --- /dev/null +++ b/source/modules/asura-utils/UtilsModule.h @@ -0,0 +1,34 @@ +#ifndef _ASURA_LIBS_UTIL_MODULE_H_ +#define _ASURA_LIBS_UTIL_MODULE_H_ + +#include "IO/FileSystem.h" +#include "IO/DataBuffer.h" +#include "IO/FileData.h" +#include "IO/file.h" +#include "IO/IOTask.h" + +#include "Threads/Thread.h" + +#include "Module.h" + +#include "Classes.h" + +namespace AsuraEngine +{ + + /// + /// Asura公用模块 + /// + class UtilsModule ASURA_FINAL : public Module + { + public: + + void Initialize(Luax::LuaxState& state) override; + + void Finalize(Luax::LuaxState& state) override; + + }; + +} + +#endif \ No newline at end of file diff --git a/source/modules/asura-utils/classes.h b/source/modules/asura-utils/classes.h index 8c89b6a..d92c3d4 100644 --- a/source/modules/asura-utils/classes.h +++ b/source/modules/asura-utils/classes.h @@ -1,5 +1,5 @@ -#ifndef __ASURAENGINE_CLASSES_H__ -#define __ASURAENGINE_CLASSES_H__ +#ifndef _ASURAENGINE_CLASSES_H_ +#define _ASURAENGINE_CLASSES_H_ #define GET_SET(TYPE,PROP_NAME,VAR_NAME) void Set##PROP_NAME (TYPE val) { VAR_NAME = val; } const TYPE Get##PROP_NAME () const {return (const TYPE)VAR_NAME; } diff --git a/source/modules/asura-utils/exceptions/exception.h b/source/modules/asura-utils/exceptions/exception.h index 4acbc1e..73c0861 100644 --- a/source/modules/asura-utils/exceptions/exception.h +++ b/source/modules/asura-utils/exceptions/exception.h @@ -1,5 +1,5 @@ -#ifndef __ASURA_ENGINE_EXCEPTION_H__ -#define __ASURA_ENGINE_EXCEPTION_H__ +#ifndef _ASURA_ENGINE_EXCEPTION_H_ +#define _ASURA_ENGINE_EXCEPTION_H_ #include #include diff --git a/source/modules/asura-utils/io/binding/_data_buffer.cpp b/source/modules/asura-utils/io/binding/_data_buffer.cpp index ac240e5..9d3f3a0 100644 --- a/source/modules/asura-utils/io/binding/_data_buffer.cpp +++ b/source/modules/asura-utils/io/binding/_data_buffer.cpp @@ -1,4 +1,4 @@ -#include "../data_buffer.h" +#include "../DataBuffer.h" using namespace Luax; diff --git a/source/modules/asura-utils/io/binding/_file_data.cpp b/source/modules/asura-utils/io/binding/_file_data.cpp index f4f6584..55cbc8b 100644 --- a/source/modules/asura-utils/io/binding/_file_data.cpp +++ b/source/modules/asura-utils/io/binding/_file_data.cpp @@ -1,4 +1,4 @@ -#include "../file_data.h" +#include "../FileData.h" using namespace std; diff --git a/source/modules/asura-utils/io/binding/_file_system.cpp b/source/modules/asura-utils/io/binding/_file_system.cpp index 0dc24d0..ace3c5f 100644 --- a/source/modules/asura-utils/io/binding/_file_system.cpp +++ b/source/modules/asura-utils/io/binding/_file_system.cpp @@ -1,4 +1,4 @@ -#include "../file_system.h" +#include "../FileSystem.h" using namespace Luax; diff --git a/source/modules/asura-utils/io/binding/_io_task.cpp b/source/modules/asura-utils/io/binding/_io_task.cpp index 4da8dc3..058f4fd 100644 --- a/source/modules/asura-utils/io/binding/_io_task.cpp +++ b/source/modules/asura-utils/io/binding/_io_task.cpp @@ -1,4 +1,4 @@ -#include "../io_task.h" +#include "../IOTask.h" using namespace std; diff --git a/source/modules/asura-utils/io/compressor.cpp b/source/modules/asura-utils/io/compressor.cpp index 095eff4..4202263 100644 --- a/source/modules/asura-utils/io/compressor.cpp +++ b/source/modules/asura-utils/io/compressor.cpp @@ -1,4 +1,4 @@ -#include "compressor.h" +#include "Compressor.h" namespace AsuraEngine { diff --git a/source/modules/asura-utils/io/compressor.h b/source/modules/asura-utils/io/compressor.h index 65fd88a..dc25e2a 100644 --- a/source/modules/asura-utils/io/compressor.h +++ b/source/modules/asura-utils/io/compressor.h @@ -1,7 +1,7 @@ -#ifndef __ASURA_COMPRESSOR_H__ -#define __ASURA_COMPRESSOR_H__ +#ifndef _ASURA_COMPRESSOR_H_ +#define _ASURA_COMPRESSOR_H_ -#include "../scripting/portable.hpp" +#include "../Scripting/Portable.hpp" namespace AsuraEngine { diff --git a/source/modules/asura-utils/io/data_buffer.cpp b/source/modules/asura-utils/io/data_buffer.cpp deleted file mode 100644 index 37f749c..0000000 --- a/source/modules/asura-utils/io/data_buffer.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include "data_buffer.h" - -using namespace AEThreading; - -namespace AsuraEngine -{ - namespace IO - { - - DataBuffer::DataBuffer(DataBuffer& src) - : m_Size(0) - , m_Capacity(0) - , m_Bytes(nullptr) - { - // 初始化容量 - lock(m_Mutex) - { - m_Capacity = src.m_Size; - m_Bytes = new byte[m_Capacity]; - Clear(); - - Load(src); - } - } - - DataBuffer::DataBuffer(std::size_t capacity) - : m_Size(0) - , m_Capacity(0) - , m_Bytes(nullptr) - { - lock(m_Mutex) - { - m_Capacity = capacity; - m_Bytes = new byte[m_Capacity]; - Clear(); - } - } - - DataBuffer::DataBuffer(const void* data, std::size_t size) - : m_Capacity(0) - , m_Size(0) - , m_Bytes(nullptr) - { - lock(m_Mutex) - { - m_Capacity = size; - m_Bytes = new byte[m_Capacity]; - Clear(); - - Load(data, size); - } - } - - DataBuffer::~DataBuffer() - { - lock(m_Mutex) - { - delete[] m_Bytes; - } - } - - void DataBuffer::Refactor(size_t capacity) - { - lock(m_Mutex) - { - if (!m_Bytes || m_Capacity != capacity) - { - if(m_Bytes) - delete[] m_Bytes; - m_Capacity = capacity; - m_Bytes = new byte[m_Capacity]; - m_Size = 0; - } - Clear(); - } - } - - void DataBuffer::Load(DataBuffer& db) - { - lock(m_Mutex) - { - Load(db.GetData(), db.GetSize()); - } - } - - void DataBuffer::Load(const void* data, std::size_t size) - { - lock(m_Mutex) - { - ASSERT(m_Capacity >= size); - memcpy(m_Bytes, data, size); - m_Size = size; - } - } - - void DataBuffer::Move(void* bytes, std::size_t size) - { - lock(m_Mutex) - { - if (m_Bytes == bytes) - { - // 如果是自身,代表更新size值,在读文件时会这样 - m_Size = size; - } - else - { - if (m_Bytes) - delete[] m_Bytes; - m_Bytes = (byte*)bytes; - m_Size = size; - m_Capacity = size; - } - } - } - - byte* DataBuffer::GetData() - { - return m_Bytes; - } - - void DataBuffer::Clear() - { - lock(m_Mutex) - { - if (m_Bytes) - { - memset(m_Bytes, 0, m_Size); - m_Size = 0; - } - } - } - - std::size_t DataBuffer::GetSize() - { - return m_Size; - } - - std::size_t DataBuffer::GetCapacity() - { - return m_Capacity; - } - - void DataBuffer::Lock() - { - m_Mutex.Lock(); - } - - void DataBuffer::Unlock() - { - m_Mutex.Unlock(); - } - - } -} \ No newline at end of file diff --git a/source/modules/asura-utils/io/data_buffer.h b/source/modules/asura-utils/io/data_buffer.h deleted file mode 100644 index 53ed603..0000000 --- a/source/modules/asura-utils/io/data_buffer.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef __ASURA_ENGINE_DATABUFFER_H__ -#define __ASURA_ENGINE_DATABUFFER_H__ - -#include - -#include "../scripting/portable.hpp" -#include "../threading/mutex.h" - -namespace AsuraEngine -{ - namespace IO - { - - /// - /// 对内存数据的封装,所有的数据使用Data buffer包装,不直接使用const void*。通过resource manager读取。 - /// - class DataBuffer ASURA_FINAL - : public AEScripting::Portable - { - public: - - LUAX_DECL_FACTORY(DataBuffer); - - DataBuffer(DataBuffer& src); - DataBuffer(std::size_t capacity); - DataBuffer(const void* bytes, std::size_t size); - ~DataBuffer(); - - byte* GetData(); - size_t GetSize(); - size_t GetCapacity(); - - /// - /// 修改容量,并清空 - /// - void Refactor(size_t capacity); - - /// - /// 拷贝数据源到此缓冲 - /// - void Load(DataBuffer& db); - void Load(const void* bytes, std::size_t size); - - /// - /// 绑定bytes,并拥有所有权,capacity为size - /// - void Move(void* bytes, std::size_t size); - - /// - /// 清理缓冲 - /// - void Clear(); - - void Lock(); - void Unlock(); - - private: - - LUAX_DECL_METHOD(_New); - LUAX_DECL_METHOD(_GetData); - LUAX_DECL_METHOD(_GetSize); - LUAX_DECL_METHOD(_GetCapacity); - LUAX_DECL_METHOD(_Refactor); - LUAX_DECL_METHOD(_Load); - LUAX_DECL_METHOD(_Clear); - - /// - /// Buffer首地址和里面数据的长度 - /// - byte* m_Bytes; - size_t m_Size; - - /// - /// Buffer容量。 - /// - size_t m_Capacity; - - AEThreading::Mutex m_Mutex; - - }; - - } -} - -namespace AEIO = AsuraEngine::IO; - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/io/decoded_data.h b/source/modules/asura-utils/io/decoded_data.h deleted file mode 100644 index 882556c..0000000 --- a/source/modules/asura-utils/io/decoded_data.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __ASURA_ENGINE_DATA_H__ -#define __ASURA_ENGINE_DATA_H__ - -#include - -#include - -#include "../scripting/portable.hpp" - -#include "data_buffer.h" - -namespace AsuraEngine -{ - namespace IO - { - - /// - /// 可以在另一个线程构建的data继承此类。如图片数据、音频数据等,可以在另一个线程中解析原 - /// 文件,生成内部数据格式,如像素等。 - /// - ASURA_ABSTRACT class DecodedData - { - public: - - /// - /// 从内存中构建data,可以放在另一个线程里面,从资源管理系统里面加载。 - /// - DecodedData() {}; - virtual ~DecodedData() {}; - - /// - /// 解码内存中的数据并以某种格式保存。 - /// - virtual void Decode(DataBuffer& buffer) = 0; - - }; - - } -} - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/io/file.cpp b/source/modules/asura-utils/io/file.cpp index a2f7403..6d5f4eb 100644 --- a/source/modules/asura-utils/io/file.cpp +++ b/source/modules/asura-utils/io/file.cpp @@ -1,8 +1,8 @@ #include -#include +#include -#include "file.h" +#include "File.h" namespace AsuraEngine { diff --git a/source/modules/asura-utils/io/file.h b/source/modules/asura-utils/io/file.h index 16de42b..d11fa4f 100644 --- a/source/modules/asura-utils/io/file.h +++ b/source/modules/asura-utils/io/file.h @@ -1,12 +1,12 @@ -#ifndef __ASURA_ENGINE_FILE_H__ -#define __ASURA_ENGINE_FILE_H__ +#ifndef _ASURA_ENGINE_FILE_H_ +#define _ASURA_ENGINE_FILE_H_ #include "physfs/physfs.h" -#include "../scripting/portable.hpp" -#include "../threading/thread.h" +#include "../Scripting/Portable.hpp" +#include "../Threads/Thread.h" -#include "file_data.h" +#include "FileData.h" namespace AsuraEngine { diff --git a/source/modules/asura-utils/io/file_data.cpp b/source/modules/asura-utils/io/file_data.cpp deleted file mode 100644 index 30fa5bf..0000000 --- a/source/modules/asura-utils/io/file_data.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "file_data.h" - -namespace AsuraEngine -{ - namespace IO - { - - FileData::FileData(const std::string& filename) - : m_Data(nullptr) - , m_FileName(filename) - { - size_t dot = filename.rfind('.'); - if (dot != std::string::npos) - { - m_Extension = filename.substr(dot + 1); - m_Name = filename.substr(0, dot); - } - else - m_Name = filename; - } - - FileData::~FileData() - { - if (m_Data) - m_Data->Release(); - } - - const std::string& FileData::GetFileName() - { - return m_FileName; - } - - const std::string& FileData::GetExtension() - { - return m_Extension; - } - - const std::string& FileData::GetName() - { - return m_Name; - } - - void FileData::BindData(ASURA_MOVE DataBuffer* buffer) - { - if (!buffer) - return; - if (m_Data) - m_Data->Release(); - m_Data = buffer; - m_Data->Retain(); - } - - DataBuffer* FileData::GetDataBuffer() - { - return m_Data; - } - - } -} \ No newline at end of file diff --git a/source/modules/asura-utils/io/file_data.h b/source/modules/asura-utils/io/file_data.h deleted file mode 100644 index ecc072b..0000000 --- a/source/modules/asura-utils/io/file_data.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef __ASURA_ENGINE_FILE_DATA_H__ -#define __ASURA_ENGINE_FILE_DATA_H__ - -#include - -#include - -#include "data_buffer.h" - -namespace AsuraEngine -{ - namespace IO - { - - class Filesystem; - - /// - /// 当从filesystem直接读取整个文件时,返回FileData对象描述文件内容和其他信息。由Filesystem创建。 - /// - class FileData ASURA_FINAL - : public AEScripting::Portable - { - public: - - LUAX_DECL_FACTORY(FileData); - - ~FileData(); - - /// - /// 返回文件内容,可以通过Databuffer获得内容和大小。由于内部接口都是以Data buffer作为参数,所以这里也返回data buffer。 - /// - DataBuffer* GetDataBuffer(); - - const std::string& GetFileName(); - const std::string& GetExtension(); - const std::string& GetName(); - - private: - - friend class Filesystem; - - FileData(const std::string& name); - - /// - /// 绑定data buffer。 - /// - void BindData(ASURA_MOVE DataBuffer* buffer); - - /// - /// Data buffer不会再filedata析构时销毁,当lua引用计数为0时由lua调用GC销毁。创建mData时会添加一个成员引用。 - /// - ASURA_REF DataBuffer* m_Data; - Luax::LuaxMemberRef m_DataRef; - - std::string m_FileName; ///< 包含扩展名的文件名 - std::string m_Extension; ///< 不包含点的扩展名 - std::string m_Name; ///< 不包含点和后缀的文件名 - - LUAX_DECL_METHOD(_GetDataBuffer); - LUAX_DECL_METHOD(_GetFileName); - LUAX_DECL_METHOD(_GetExtension); - LUAX_DECL_METHOD(_GetName); - - }; - - } -} - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/io/file_system.cpp b/source/modules/asura-utils/io/file_system.cpp deleted file mode 100644 index f68bad6..0000000 --- a/source/modules/asura-utils/io/file_system.cpp +++ /dev/null @@ -1,198 +0,0 @@ -#include - -#include "../exceptions/exception.h" - -#include "file.h" -#include "file_data.h" -#include "file_system.h" - -using namespace std; - -namespace AsuraEngine -{ - namespace IO - { - -#ifdef ASURA_WINDOWS - #include - #include -#else - #include - #include -#endif - - Filesystem::~Filesystem() - { - if (m_Inited) //PHYSFS_isInit - PHYSFS_deinit(); - } - - void Filesystem::Init(const char* arg0) - { - if (!PHYSFS_init(arg0)) - throw Exception("Failed to initialize filesystem: %s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())); - - m_Inited = true; - } - - bool Filesystem::Mount(const std::string& locpath, const std::string& montpoint/* = "/"*/, bool prepend /*= false*/) - { - if (!m_Inited) - return false; - - return PHYSFS_mount(locpath.c_str(), montpoint.c_str(), !prepend); - } - - bool Filesystem::Mount(DataBuffer* db, const std::string& archivename, const std::string& mountpoint /*= "/"*/, bool prepend /*= false*/) - { - if (!m_Inited) - return false; - if (PHYSFS_mountMemory(db->GetData(), db->GetSize(), nullptr, archivename.c_str(), mountpoint.c_str(), !prepend)) - { - m_MountData[archivename] = db; - return true; - } - return false; - } - - bool Filesystem::Unmount(const std::string& locpath) - { - if (!m_Inited) - return false; - - // 如果是归档,从映射中删除它 - auto datait = m_MountData.find(locpath); - if (datait != m_MountData.end() && PHYSFS_unmount(locpath.c_str()) != 0) - { - m_MountData.erase(datait); - return true; - } - - return PHYSFS_unmount(locpath.c_str()); - } - - bool Filesystem::Unmount(DataBuffer* db) - { - for (const auto& dp : m_MountData) - { - if (dp.second == db) - { - std::string archive = dp.first; - return Unmount(archive); - } - } - } - - bool Filesystem::GetMountPoint(const std::string& locpath, ASURA_OUT std::string& mountpoint) - { - if (!m_Inited) - return false; - const char* point = PHYSFS_getMountPoint(locpath.c_str()); - if (point != nullptr) - { - mountpoint = point; - return true; - } - return false; - } - - void Filesystem::SetWriteDirectory(const std::string locpath) - { - if (!m_Inited) - return; - if (!PHYSFS_setWriteDir(locpath.c_str())) - throw Exception("Failed to set write directory %s", locpath.c_str()); - } - - std::string Filesystem::GetWriteDirectory() - { - return PHYSFS_getWriteDir(); - } - - File* Filesystem::NewFile(const std::string& name) - { - return new File(name); - } - - bool Filesystem::NewDirectory(const std::string& path) - { - if (!m_Inited) - return false; - if (!PHYSFS_getWriteDir()) - return false; - if (!PHYSFS_mkdir(path.c_str())) - return false; - return true; - } - - bool Filesystem::Write(const std::string& name, ASURA_REF DataBuffer* buffer) - { - File file(name); - file.Open(File::FILE_MODE_WRITE); - if (!file.Write(buffer)) - throw Exception("Data could not be written."); - } - - bool Filesystem::Append(const std::string& name, ASURA_REF DataBuffer* buffer) - { - File file(name); - file.Open(File::FILE_MODE_APPEND); - if (!file.Write(buffer)) - throw Exception("Data could not be append."); - } - - FileData* Filesystem::Read(const std::string& name) - { - File file = File(name); - file.Open(File::FILE_MODE_READ); - int size = file.GetSize(); - DataBuffer* db = new DataBuffer(size); - if (db) - { - file.ReadAll(db); - FileData* fd = new FileData(name); - fd->BindData(db); - return fd; - } - return nullptr; - } - - bool Filesystem::Remove(const std::string& path) - { - if (!m_Inited) - return false; - if (PHYSFS_getWriteDir() == 0) - return false; - - if (!PHYSFS_delete(path.c_str())) - return false; - - return true; - } - - bool Filesystem::GetFileInfo(const std::string& filepath, ASURA_OUT FileInfo* info) - { - if (!m_Inited) - return false; - - PHYSFS_Stat stat = {}; - if (!PHYSFS_stat(filepath.c_str(), &stat)) - return false; - - info->size = (int64)stat.filesize; - info->modtime = (int64)stat.modtime; - - if (stat.filetype == PHYSFS_FILETYPE_REGULAR) - info->type = FILE_TYPE_FILE; - else if (stat.filetype == PHYSFS_FILETYPE_DIRECTORY) - info->type = FILE_TYPE_DIRECTORY; - else if (stat.filetype == PHYSFS_FILETYPE_SYMLINK) - info->type = FILE_TYPE_SYMLINK; - else - info->type = FILE_TYPE_OTHER; - - return true; - } - - } -} \ No newline at end of file diff --git a/source/modules/asura-utils/io/file_system.h b/source/modules/asura-utils/io/file_system.h deleted file mode 100644 index 9b4c4be..0000000 --- a/source/modules/asura-utils/io/file_system.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef __ASURA_ENGINE_FILESYSTEM_H__ -#define __ASURA_ENGINE_FILESYSTEM_H__ - -#include -#include - -#include "../scripting/portable.hpp" -#include "../singleton.hpp" -#include "../type.h" - -#include "file_data.h" -#include "file.h" - -namespace AsuraEngine -{ - namespace IO - { - - enum FileType - { - FILE_TYPE_FILE, ///< 文件 - FILE_TYPE_DIRECTORY, ///< 文件夹 - FILE_TYPE_SYMLINK, ///< 链接 - FILE_TYPE_OTHER, ///< 其他 - }; - - struct FileInfo - { - int64 size; - int64 modtime; - FileType type; - }; - - /// - /// 资源管理,负责加载、存储资源,指定根目录等。无论编辑器还是运行时,都需要限制访问的机制,将用户的操作限制在游戏目录 - /// 下,file system就是做这件事的。Filesystem是运行时和编辑器共用的类,AssetDatabase是用来管理资源的类,在framework - /// 里实现,单纯是逻辑处理,读写还是用Filesystem实现,AssetDatabase提供根据文件内容创建对应资源的方法。 - /// - class Filesystem ASURA_FINAL - : public Singleton - , public AEScripting::Portable - { - public: - - LUAX_DECL_SINGLETON(Filesystem); - - ~Filesystem(); - - void Init(const char* arg0); - - /// - /// 当前可执行文件的所在文件夹 - /// - std::string GetWorkingDirectory(); - - bool Mount(const std::string& locpath, const std::string& montpoint = "/", bool prepend = false); - bool Mount(DataBuffer* db, const std::string& archivename, const std::string& mountpoint = "/", bool prepend = false); - - bool Unmount(const std::string& locpath); - bool Unmount(DataBuffer* db); - - bool GetMountPoint(const std::string& locpath, ASURA_OUT std::string& mountpoint); - - void SetWriteDirectory(const std::string locpath); - std::string GetWriteDirectory(); - File* NewFile(const std::string& name); - bool NewDirectory(const std::string& path); - bool Write(const std::string& path, ASURA_REF DataBuffer* buffer); - bool Append(const std::string& path, ASURA_REF DataBuffer* buffer); - bool Remove(const std::string& path); - - FileData* Read(const std::string& path); - bool GetFileInfo(const std::string& path, ASURA_OUT FileInfo* info); - - bool GetDirectoryItems(const std::string& path, ASURA_OUT std::vector& items) { return false; }; - - private: - - typedef std::map MountDataMap; - - bool m_Inited; ///< 是否初始化成功 - std::string m_Cwd; ///< 当前执行文件的工作目录 - MountDataMap m_MountData; ///< 从路径到压缩文档的映射 - - LUAX_DECL_METHOD(_Init); - LUAX_DECL_METHOD(_Mount); - LUAX_DECL_METHOD(_Unmount); - LUAX_DECL_METHOD(_GetMountPoint); - - LUAX_DECL_METHOD(_SetWriteDirectory); - LUAX_DECL_METHOD(_GetWriteDirectory); - LUAX_DECL_METHOD(_CreateFile); - LUAX_DECL_METHOD(_CreateDirectory); - - LUAX_DECL_METHOD(_Write); - LUAX_DECL_METHOD(_Append); - LUAX_DECL_METHOD(_Remove); - - LUAX_DECL_METHOD(_Read); - - LUAX_DECL_METHOD(_GetFileInfo); - - LUAX_DECL_METHOD(_GetDirectoryItems); - - }; - - } -} - -namespace AEIO = AsuraEngine::IO; - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/io/io_batch_task.cpp b/source/modules/asura-utils/io/io_batch_task.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/source/modules/asura-utils/io/io_batch_task.h b/source/modules/asura-utils/io/io_batch_task.h deleted file mode 100644 index 0a551e8..0000000 --- a/source/modules/asura-utils/io/io_batch_task.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __ASURA_IO_BATCH_TASK_H__ -#define __ASURA_IO_BATCH_TASK_H__ - -#include "io_task.h" - -namespace AsuraEngine -{ - namespace IO - { - - /// - /// 批量处理读或者写。一次性提交一个table,依次处理后返回结果。 - /// - class IOBatchTask ASURA_FINAL : public AEThreading::Task - { - public: - - private: - - /// - /// 任务表,每一条的结构如下: - /// { path = "", } - /// - Luax::LuaxMemberRef m_Tasks; - - }; - - } -} - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/io/io_task.cpp b/source/modules/asura-utils/io/io_task.cpp deleted file mode 100644 index 6c323de..0000000 --- a/source/modules/asura-utils/io/io_task.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "file_system.h" -#include "io_task.h" - -#include - -using namespace AEScripting; -using namespace Luax; - -namespace AsuraEngine -{ - namespace IO - { - - IOTask::IOTask(const std::string& path, DataBuffer* buffer, IOTaskType type) - : m_Path(path) - , m_Buffer(buffer) - { - if (buffer) - buffer->Retain(); - } - - IOTask::~IOTask() - { - if (m_Buffer) - m_Buffer->Release(); - } - - bool IOTask::Execute() - { - File file(m_Path); - if (m_Type == IOTASK_TYPE_WRITE) - { - - } - // 从path读取内容保存在mBuffer中 - else if (m_Type == IOTASK_TYPE_READ) - { - if (!m_Buffer) - return false; - file.Open(File::FILE_MODE_READ); - file.ReadAll(m_Buffer); - file.Close(); - } - return true; - } - - void IOTask::Invoke(lua_State* invokeThreaad) - { - if (m_Callback) - { - LuaxScopedState state(invokeThreaad); - if (this->PushLuaxMemberRef(state, m_Callback)) - { - this->PushLuaxMemberRef(state, m_BufferRef); - state.Call(1, 0); - } - } - } - - } -} diff --git a/source/modules/asura-utils/io/io_task.h b/source/modules/asura-utils/io/io_task.h deleted file mode 100644 index 8026a24..0000000 --- a/source/modules/asura-utils/io/io_task.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef __ASURA_IO_TASK_H__ -#define __ASURA_IO_TASK_H__ - -#include - -#include "../scripting/portable.hpp" -#include "../threading/task.h" - -#include "data_buffer.h" - -namespace AsuraEngine -{ - namespace IO - { - - enum IOTaskType - { - IOTASK_TYPE_READ, - IOTASK_TYPE_WRITE, - IOTASK_TYPE_APPEND, - }; - - /// - /// 读取文件任务。 - /// - class IOTask ASURA_FINAL - : public AEScripting::Portable - { - public: - - LUAX_DECL_FACTORY(IOTask); - - IOTask(const std::string& path, DataBuffer* buffer, IOTaskType type); - ~IOTask(); - - bool Execute() override ; - void Invoke(lua_State* invokeThreaad) override; - - private: - - LUAX_DECL_ENUM(IOTaskType); - - LUAX_DECL_METHOD(_New); - - std::string m_Path; - IOTaskType m_Type; - - DataBuffer* m_Buffer; - Luax::LuaxMemberRef m_BufferRef; - - }; - - } -} - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/io/renewable.h b/source/modules/asura-utils/io/renewable.h index fd6c638..90867f2 100644 --- a/source/modules/asura-utils/io/renewable.h +++ b/source/modules/asura-utils/io/renewable.h @@ -3,7 +3,7 @@ #include "../scripting/portable.hpp" -#include "decoded_data.h" +#include "DecodedData.h" namespace AsuraEngine { diff --git a/source/modules/asura-utils/manager.hpp b/source/modules/asura-utils/manager.hpp index 7b4e272..c6817b1 100644 --- a/source/modules/asura-utils/manager.hpp +++ b/source/modules/asura-utils/manager.hpp @@ -1,5 +1,5 @@ -#ifndef __ASURA_ENGINE_MANAGER_H__ -#define __ASURA_ENGINE_MANAGER_H__ +#ifndef _ASURA_ENGINE_MANAGER_H_ +#define _ASURA_ENGINE_MANAGER_H_ namespace AsuraEngine { diff --git a/source/modules/asura-utils/math/matrix44.cpp b/source/modules/asura-utils/math/matrix44.cpp index 4472cd8..9ecf448 100644 --- a/source/modules/asura-utils/math/matrix44.cpp +++ b/source/modules/asura-utils/math/matrix44.cpp @@ -1,4 +1,4 @@ -#include "matrix44.h" +#include "Matrix44.h" #include // memcpy #include diff --git a/source/modules/asura-utils/math/matrix44.h b/source/modules/asura-utils/math/matrix44.h index 30033c5..7b66920 100644 --- a/source/modules/asura-utils/math/matrix44.h +++ b/source/modules/asura-utils/math/matrix44.h @@ -1,7 +1,7 @@ -#ifndef __ASURA_MATRIX_H__ -#define __ASURA_MATRIX_H__ +#ifndef _ASURA_MATRIX_H_ +#define _ASURA_MATRIX_H_ -#include "../scripting/portable.hpp" +#include "../Scripting/Portable.hpp" namespace AsuraEngine { diff --git a/source/modules/asura-utils/math/ranged_value.cpp b/source/modules/asura-utils/math/ranged_value.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/source/modules/asura-utils/math/ranged_value.h b/source/modules/asura-utils/math/ranged_value.h deleted file mode 100644 index e69de29..0000000 diff --git a/source/modules/asura-utils/math/rect.hpp b/source/modules/asura-utils/math/rect.hpp index 010a5db..45bf1ba 100644 --- a/source/modules/asura-utils/math/rect.hpp +++ b/source/modules/asura-utils/math/rect.hpp @@ -1,5 +1,5 @@ -#ifndef __ASURA_ENGINE_RECT_H__ -#define __ASURA_ENGINE_RECT_H__ +#ifndef _ASURA_ENGINE_RECT_H_ +#define _ASURA_ENGINE_RECT_H_ namespace AsuraEngine { @@ -34,7 +34,7 @@ namespace AsuraEngine T x, y, w, h; }; -#include "Rect.inl" +#include "Rect.inc" // Define the most common types typedef Rect Recti; diff --git a/source/modules/asura-utils/math/rect.inl b/source/modules/asura-utils/math/rect.inl deleted file mode 100644 index efafbf9..0000000 --- a/source/modules/asura-utils/math/rect.inl +++ /dev/null @@ -1,28 +0,0 @@ -template -inline Rect::Rect() - : x(0) - , y(0) - , w(0) - , h(0) -{ - -} - -template -inline Rect::Rect(T X, T Y, T W, T H) - : x(X) - , y(Y) - , w(W) - , h(H) -{ - -} - -template -void Rect::Set(T X, T Y, T W, T H) -{ - x = X; - y = Y; - w = W; - h = H; -} \ No newline at end of file diff --git a/source/modules/asura-utils/math/transform.h b/source/modules/asura-utils/math/transform.h index be4c850..23d0709 100644 --- a/source/modules/asura-utils/math/transform.h +++ b/source/modules/asura-utils/math/transform.h @@ -1,7 +1,7 @@ -#ifndef __ASURA_ENGINE_TRANSFORM_H__ -#define __ASURA_ENGINE_TRANSFORM_H__ +#ifndef _ASURA_ENGINE_TRANSFORM_H_ +#define _ASURA_ENGINE_TRANSFORM_H_ -#include "../scripting/portable.hpp" +#include "../scripting/Portable.hpp" namespace AsuraEngine { diff --git a/source/modules/asura-utils/math/vector2.hpp b/source/modules/asura-utils/math/vector2.hpp index e18bbdf..f2405eb 100644 --- a/source/modules/asura-utils/math/vector2.hpp +++ b/source/modules/asura-utils/math/vector2.hpp @@ -1,5 +1,5 @@ -#ifndef __ASURA_ENGINE_VECTOR2_H__ -#define __ASURA_ENGINE_VECTOR2_H__ +#ifndef _ASURA_ENGINE_VECTOR2_H__ +#define _ASURA_ENGINE_VECTOR2_H__ namespace AsuraEngine { @@ -57,7 +57,7 @@ namespace AsuraEngine template bool operator !=(const Vector2& left, const Vector2& right); -#include "Vector2.inl" +#include "Vector2.inc" // Define the most common types typedef Vector2 Vector2i; diff --git a/source/modules/asura-utils/math/vector2.inl b/source/modules/asura-utils/math/vector2.inl deleted file mode 100644 index 155432a..0000000 --- a/source/modules/asura-utils/math/vector2.inl +++ /dev/null @@ -1,114 +0,0 @@ -template -inline Vector2::Vector2() : - x(0), - y(0) -{ - -} - -template -inline Vector2::Vector2(T X, T Y) : - x(X), - y(Y) -{ - -} - -template -template -inline Vector2::Vector2(const Vector2& vector) : - x(static_cast(vector.x)), - y(static_cast(vector.y)) -{ -} - -template -inline void Vector2::Set(T X, T Y) -{ - x = X; - y = Y; -} - -template -inline Vector2 operator -(const Vector2& right) -{ - return Vector2(-right.x, -right.y); -} - -template -inline Vector2& operator +=(Vector2& left, const Vector2& right) -{ - left.x += right.x; - left.y += right.y; - - return left; -} - -template -inline Vector2& operator -=(Vector2& left, const Vector2& right) -{ - left.x -= right.x; - left.y -= right.y; - - return left; -} - -template -inline Vector2 operator +(const Vector2& left, const Vector2& right) -{ - return Vector2(left.x + right.x, left.y + right.y); -} - -template -inline Vector2 operator -(const Vector2& left, const Vector2& right) -{ - return Vector2(left.x - right.x, left.y - right.y); -} - -template -inline Vector2 operator *(const Vector2& left, T right) -{ - return Vector2(left.x * right, left.y * right); -} - -template -inline Vector2 operator *(T left, const Vector2& right) -{ - return Vector2(right.x * left, right.y * left); -} - -template -inline Vector2& operator *=(Vector2& left, T right) -{ - left.x *= right; - left.y *= right; - - return left; -} - -template -inline Vector2 operator /(const Vector2& left, T right) -{ - return Vector2(left.x / right, left.y / right); -} - -template -inline Vector2& operator /=(Vector2& left, T right) -{ - left.x /= right; - left.y /= right; - - return left; -} - -template -inline bool operator ==(const Vector2& left, const Vector2& right) -{ - return (left.x == right.x) && (left.y == right.y); -} - -template -inline bool operator !=(const Vector2& left, const Vector2& right) -{ - return (left.x != right.x) || (left.y != right.y); -} diff --git a/source/modules/asura-utils/math/vector3.hpp b/source/modules/asura-utils/math/vector3.hpp index 2b23406..8da57cf 100644 --- a/source/modules/asura-utils/math/vector3.hpp +++ b/source/modules/asura-utils/math/vector3.hpp @@ -1,5 +1,5 @@ -#ifndef __ASURA_ENGINE_VECTOR3_H__ -#define __ASURA_ENGINE_VECTOR3_H__ +#ifndef _ASURA_ENGINE_VECTOR3_H__ +#define _ASURA_ENGINE_VECTOR3_H__ namespace AsuraEngine { @@ -221,7 +221,7 @@ namespace AsuraEngine template bool operator !=(const Vector3& left, const Vector3& right); -#include "Vector3.inl" +#include "Vector3.inc" // Define the most common types typedef Vector3 Vector3i; diff --git a/source/modules/asura-utils/math/vector3.inl b/source/modules/asura-utils/math/vector3.inl deleted file mode 100644 index 3a2aa93..0000000 --- a/source/modules/asura-utils/math/vector3.inl +++ /dev/null @@ -1,145 +0,0 @@ - - -//////////////////////////////////////////////////////////// -template -inline Vector3::Vector3() : - x(0), - y(0), - z(0) -{ - -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3::Vector3(T X, T Y, T Z) : - x(X), - y(Y), - z(Z) -{ - -} - - -//////////////////////////////////////////////////////////// -template -template -inline Vector3::Vector3(const Vector3& vector) : - x(static_cast(vector.x)), - y(static_cast(vector.y)), - z(static_cast(vector.z)) -{ -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3 operator -(const Vector3& left) -{ - return Vector3(-left.x, -left.y, -left.z); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3& operator +=(Vector3& left, const Vector3& right) -{ - left.x += right.x; - left.y += right.y; - left.z += right.z; - - return left; -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3& operator -=(Vector3& left, const Vector3& right) -{ - left.x -= right.x; - left.y -= right.y; - left.z -= right.z; - - return left; -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3 operator +(const Vector3& left, const Vector3& right) -{ - return Vector3(left.x + right.x, left.y + right.y, left.z + right.z); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3 operator -(const Vector3& left, const Vector3& right) -{ - return Vector3(left.x - right.x, left.y - right.y, left.z - right.z); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3 operator *(const Vector3& left, T right) -{ - return Vector3(left.x * right, left.y * right, left.z * right); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3 operator *(T left, const Vector3& right) -{ - return Vector3(right.x * left, right.y * left, right.z * left); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3& operator *=(Vector3& left, T right) -{ - left.x *= right; - left.y *= right; - left.z *= right; - - return left; -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3 operator /(const Vector3& left, T right) -{ - return Vector3(left.x / right, left.y / right, left.z / right); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector3& operator /=(Vector3& left, T right) -{ - left.x /= right; - left.y /= right; - left.z /= right; - - return left; -} - - -//////////////////////////////////////////////////////////// -template -inline bool operator ==(const Vector3& left, const Vector3& right) -{ - return (left.x == right.x) && (left.y == right.y) && (left.z == right.z); -} - - -//////////////////////////////////////////////////////////// -template -inline bool operator !=(const Vector3& left, const Vector3& right) -{ - return (left.x != right.x) || (left.y != right.y) || (left.z != right.z); -} diff --git a/source/modules/asura-utils/math/vector4.h b/source/modules/asura-utils/math/vector4.h index 13a9d8a..a5bf549 100644 --- a/source/modules/asura-utils/math/vector4.h +++ b/source/modules/asura-utils/math/vector4.h @@ -1,5 +1,5 @@ -#ifndef __ASURA_ENGINE_VECTOR4_H__ -#define __ASURA_ENGINE_VECTOR4_H__ +#ifndef _ASURA_ENGINE_VECTOR4_H__ +#define _ASURA_ENGINE_VECTOR4_H__ namespace AsuraEngine { @@ -222,7 +222,7 @@ namespace AsuraEngine template bool operator !=(const Vector4& left, const Vector4& right); -#include "Vector4.inl" +#include "Vector4.inc" // Define the most common types typedef Vector4 Vector4i; diff --git a/source/modules/asura-utils/math/vector4.inl b/source/modules/asura-utils/math/vector4.inl deleted file mode 100644 index 4b043a1..0000000 --- a/source/modules/asura-utils/math/vector4.inl +++ /dev/null @@ -1,152 +0,0 @@ - - -//////////////////////////////////////////////////////////// -template -inline Vector4::Vector4() : - x(0), - y(0), - z(0), - w(0) -{ - -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4::Vector4(T X, T Y, T Z, T W) : - x(X), - y(Y), - z(Z), - w(W) -{ - -} - - -//////////////////////////////////////////////////////////// -template -template -inline Vector4::Vector4(const Vector4& vector) : - x(static_cast(vector.x)), - y(static_cast(vector.y)), - z(static_cast(vector.z)), - w(static_cast(vector.w)) -{ -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4 operator -(const Vector4& left) -{ - return Vector4(-left.x, -left.y, -left.z, -left.w); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4& operator +=(Vector4& left, const Vector4& right) -{ - left.x += right.x; - left.y += right.y; - left.z += right.z; - left.w += right.w; - - return left; -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4& operator -=(Vector4& left, const Vector4& right) -{ - left.x -= right.x; - left.y -= right.y; - left.z -= right.z; - left.w -= right.w; - - return left; -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4 operator +(const Vector4& left, const Vector4& right) -{ - return Vector4(left.x + right.x, left.y + right.y, left.z + right.z, left.w + right.w); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4 operator -(const Vector4& left, const Vector4& right) -{ - return Vector4(left.x - right.x, left.y - right.y, left.z - right.z, left.w - right.w); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4 operator *(const Vector4& left, T right) -{ - return Vector4(left.x * right, left.y * right, left.z * right, left.w * right); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4 operator *(T left, const Vector4& right) -{ - return Vector4(right.x * left, right.y * left, right.z * left, right.w * left); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4& operator *=(Vector4& left, T right) -{ - left.x *= right; - left.y *= right; - left.z *= right; - left.w *= right; - - return left; -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4 operator /(const Vector4& left, T right) -{ - return Vector4(left.x / right, left.y / right, left.z / right, left.w / right); -} - - -//////////////////////////////////////////////////////////// -template -inline Vector4& operator /=(Vector4& left, T right) -{ - left.x /= right; - left.y /= right; - left.z /= right; - left.w /= right; - - return left; -} - - -//////////////////////////////////////////////////////////// -template -inline bool operator ==(const Vector4& left, const Vector4& right) -{ - return (left.x == right.x) && (left.y == right.y) && (left.z == right.z) && (left.w == right.w); -} - - -//////////////////////////////////////////////////////////// -template -inline bool operator !=(const Vector4& left, const Vector4& right) -{ - return (left.x != right.x) || (left.y != right.y) || (left.z != right.z) || (left.w != right.w); -} diff --git a/source/modules/asura-utils/module.h b/source/modules/asura-utils/module.h index b22c68c..2cc91d6 100644 --- a/source/modules/asura-utils/module.h +++ b/source/modules/asura-utils/module.h @@ -1,8 +1,8 @@ -#ifndef __ASURA_MODULE_H__ -#define __ASURA_MODULE_H__ +#ifndef _ASURA_MODULE_H_ +#define _ASURA_MODULE_H_ -#include "type.h" -#include "scripting/portable.hpp" +#include "Type.h" +#include "Scripting/Portable.hpp" namespace AsuraEngine { diff --git a/source/modules/asura-utils/scripting/portable.hpp b/source/modules/asura-utils/scripting/portable.hpp index d691455..1eee123 100644 --- a/source/modules/asura-utils/scripting/portable.hpp +++ b/source/modules/asura-utils/scripting/portable.hpp @@ -1,5 +1,5 @@ -#ifndef __ASURA_ENGINE_PORTABLE_H__ -#define __ASURA_ENGINE_PORTABLE_H__ +#ifndef _ASURA_ENGINE_PORTABLE_H_ +#define _ASURA_ENGINE_PORTABLE_H_ extern "C" { #include @@ -8,12 +8,12 @@ extern "C" { } #include -#include "../type.h" -namespace AsuraEngine -{ -namespace Scripting -{ +#include "../Type.h" +#include "../Classes.h" + +namespace_begin(AsuraEngine) +namespace_begin(Scripting) /// 需要作为基类,访问userdata和member ref的类继承此类,注意必须是虚继承。 @@ -23,8 +23,8 @@ using Object = Luax::LuaxObject; template using Portable = Luax::LuaxNativeClass; -} -} +namespace_end +namespace_end namespace AEScripting = AsuraEngine::Scripting; diff --git a/source/modules/asura-utils/singleton.hpp b/source/modules/asura-utils/singleton.hpp index 0d2777e..9bb7336 100644 --- a/source/modules/asura-utils/singleton.hpp +++ b/source/modules/asura-utils/singleton.hpp @@ -1,7 +1,7 @@ -#ifndef __ASURA_SINGLETON_H__ -#define __ASURA_SINGLETON_H__ +#ifndef _ASURA_SINGLETON_H_ +#define _ASURA_SINGLETON_H_ -#include "utils_config.h" +#include "UtilsConfig.h" namespace AsuraEngine { @@ -56,4 +56,4 @@ namespace AsuraEngine } -#endif // __ASURA_SINGLETON_H__ \ No newline at end of file +#endif // _ASURA_SINGLETON_H_ \ No newline at end of file diff --git a/source/modules/asura-utils/stringmap.hpp b/source/modules/asura-utils/stringmap.hpp index 8d8f231..15d28ee 100644 --- a/source/modules/asura-utils/stringmap.hpp +++ b/source/modules/asura-utils/stringmap.hpp @@ -1,5 +1,5 @@ -#ifndef __ASURA_ENGINE_STRINGMAP_H__ -#define __ASURA_ENGINE_STRINGMAP_H__ +#ifndef _ASURA_ENGINE_STRINGMAP_H_ +#define _ASURA_ENGINE_STRINGMAP_H_ #include diff --git a/source/modules/asura-utils/threading/binding/_coroutine.cpp b/source/modules/asura-utils/threading/binding/_coroutine.cpp deleted file mode 100644 index a710623..0000000 --- a/source/modules/asura-utils/threading/binding/_coroutine.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "../coroutine.h" - -using namespace std; - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - - LUAX_REGISTRY(Coroutine) - { - LUAX_REGISTER_METHODS(state, - { "New", _New }, - { "Run", _Run } - ); - } - - LUAX_POSTPROCESS(Coroutine) - { - - } - - // Coroutine.New() - LUAX_IMPL_METHOD(Coroutine, _New) - { - LUAX_STATE(L); - - return 0; - } - - // coroutine:Run() - LUAX_IMPL_METHOD(Coroutine, _Run) - { - LUAX_PREPARE(L, Coroutine); - - return 0; - } - - } -} diff --git a/source/modules/asura-utils/threading/binding/_thread.cpp b/source/modules/asura-utils/threading/binding/_thread.cpp deleted file mode 100644 index b835453..0000000 --- a/source/modules/asura-utils/threading/binding/_thread.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#include "../thread.h" - -using namespace std; - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - - LUAX_REGISTRY(Thread) - { - LUAX_REGISTER_METHODS(state, - { "New", _New }, - { "AddTask", _AddTask }, - { "Start", _Start }, - { "Idle", _Idle }, - { "Pause", _Pause }, - { "Resume", _Resume }, - { "Stop", _Stop }, - { "Join", _Join }, - { "IsRunning", _IsRunning }, - { "IsPaused", _IsPaused }, - { "IsStopped", _IsStopped }, - { "IsCurrent", _IsCurrent }, - { "Sleep", _Sleep }, - { "Dispatch", _Dispatch }, - { "GetName", _GetName }, - { "GetType", _GetType }, - { "GetState", _GetState } - ); - } - - LUAX_POSTPROCESS(Thread) - { - LUAX_REGISTER_ENUM(state, "EThreadType", - { "DEFERRED", THREAD_TYPE_DEFERRED }, - { "IMMEDIATE", THREAD_TYPE_IMMEDIATE } - ); - LUAX_REGISTER_ENUM(state, "EThreadState", - { "IDLE", THREAD_STATE_IDLE }, - { "RUNNING", THREAD_STATE_RUNNING }, - { "PAUSED", THREAD_STATE_PAUSED }, - { "STOPPED", THREAD_STATE_STOPPED } - ); - } - - // thread = Thread.New(thread_type, sleepTime, name) - LUAX_IMPL_METHOD(Thread, _New) - { - LUAX_STATE(L); - - ThreadType type = (ThreadType)state.GetValue(1, THREAD_TYPE_DEFERRED); - uint sleepTime = state.GetValue(2,1); - cc8* name = state.GetValue(3, ""); - - Thread* thread = new Thread(state, type, sleepTime, name); - thread->PushLuaxUserdata(state); - - return 1; - } - - // thread:AddTask(task) - LUAX_IMPL_METHOD(Thread, _AddTask) - { - LUAX_PREPARE(L, Thread); - - Task* task = state.GetUserdata(2); - self->AddTask(task); - self->LuaxRetain(state, task); - return 0; - } - - // successed = thread:Start(isDeamon, stackSize) - LUAX_IMPL_METHOD(Thread, _Start) - { - LUAX_PREPARE(L, Thread); - - bool isDaemon = state.GetValue(2, true); - uint stackSize = state.GetValue(3, 0); - - state.Push(self->Start(isDaemon, stackSize)); - return 1; - } - - // thread:Idle() - LUAX_IMPL_METHOD(Thread, _Idle) - { - LUAX_PREPARE(L, Thread); - self->Idle(); - return 0; - } - - // thread:Pause() - LUAX_IMPL_METHOD(Thread, _Pause) - { - LUAX_PREPARE(L, Thread); - self->Pause(); - return 0; - } - - // thread:Resume() - LUAX_IMPL_METHOD(Thread, _Resume) - { - LUAX_PREPARE(L, Thread); - self->Resume(); - return 0; - } - - // thread:Stop() - LUAX_IMPL_METHOD(Thread, _Stop) - { - LUAX_PREPARE(L, Thread); - self->Stop(); - return 0; - } - - // thread:Join() - LUAX_IMPL_METHOD(Thread, _Join) - { - LUAX_PREPARE(L, Thread); - self->Join(); - return 0; - } - - // thread:IsRunning() - LUAX_IMPL_METHOD(Thread, _IsRunning) - { - LUAX_PREPARE(L, Thread); - state.Push(self->IsRunning()); - return 1; - } - - // thread:IsPaused() - LUAX_IMPL_METHOD(Thread, _IsPaused) - { - LUAX_PREPARE(L, Thread); - state.Push(self->IsPaused()); - return 1; - } - - // thread:IsStopped() - LUAX_IMPL_METHOD(Thread, _IsStopped) - { - LUAX_PREPARE(L, Thread); - state.Push(self->IsStopped()); - return 1; - } - - // thread:IsCurrent() - LUAX_IMPL_METHOD(Thread, _IsCurrent) - { - LUAX_PREPARE(L, Thread); - state.Push(self->IsCurrent()); - return 1; - } - - // Thread.Sleep(ms) - LUAX_IMPL_METHOD(Thread, _Sleep) - { - LUAX_STATE(L); - uint ms = state.GetValue(1, 0); -#ifdef _WIN32 - ::Sleep(ms); -#endif - return 0; - } - - // thread:Dispatch() - LUAX_IMPL_METHOD(Thread, _Dispatch) - { - LUAX_PREPARE(L, Thread); - self->Dispatch(); - return 0; - } - - // thread:GetName() - LUAX_IMPL_METHOD(Thread, _GetName) - { - LUAX_PREPARE(L, Thread); - state.Push(self->GetName()); - return 1; - } - - // thread:GetType() - LUAX_IMPL_METHOD(Thread, _GetType) - { - LUAX_PREPARE(L, Thread); - state.Push(self->m_Type); - return 1; - } - - // thread:GetState() - LUAX_IMPL_METHOD(Thread, _GetState) - { - LUAX_PREPARE(L, Thread); - state.Push(self->m_State); - return 1; - } - - // thread:SetSleepTime(sleepTime) - LUAX_IMPL_METHOD(Thread, _SetSleepTime) - { - LUAX_PREPARE(L, Thread); - uint time = state.CheckValue(2); - self->SetSleepTime(time); - return 0; - } - - } -} diff --git a/source/modules/asura-utils/threading/conditional.cpp b/source/modules/asura-utils/threading/conditional.cpp deleted file mode 100644 index c4d32d9..0000000 --- a/source/modules/asura-utils/threading/conditional.cpp +++ /dev/null @@ -1,84 +0,0 @@ -#include "conditional.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -Conditional::Conditional() - : m_Waiting(0) - , m_Signals(0) -{ -} - -Conditional::~Conditional() -{ -} - -void Conditional::Signal() -{ - m_Mutex.Lock(); - if (m_Waiting > m_Signals) - { - ++m_Signals; - signal(m_WaitSem); - m_Mutex.Unlock(); - wait(m_DoneSem); - } - else - { - m_Mutex.Unlock(); - } -} - -void Conditional::Broadcast() -{ - m_Mutex.Lock(); - if (m_Waiting> m_Signals) { - int i, num_waiting; - - num_waiting = (m_Waiting - m_Signals); - m_Signals = m_Waiting; - for (i = 0; i < num_waiting; ++i) { - signal(m_WaitSem); - } - m_Mutex.Unlock(); - for (i = 0; i < num_waiting; ++i) { - wait(m_DoneSem); - } - } - else { - m_Mutex.Unlock(); - } - -} - -bool Conditional::Wait(Mutex* mutex, int timeout /*= ASURA_MUTEX_MAXWAIT*/) -{ - bool retval; - - m_Mutex.Lock(); - ++m_Waiting; - m_Mutex.Unlock(); - - mutex->Unlock(); - - retval = wait(m_WaitSem, timeout); - - m_Mutex.Lock(); - if (m_Signals > 0) { - if (!retval) { - wait(m_WaitSem); - } - signal(m_DoneSem); - - --m_Signals; - } - --m_Waiting; - m_Mutex.Unlock(); - - m_Mutex.Lock(); - - return retval; -} - -namespace_end -namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/threading/conditional.h b/source/modules/asura-utils/threading/conditional.h deleted file mode 100644 index ff832ac..0000000 --- a/source/modules/asura-utils/threading/conditional.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __ASURA_CONDITIONAL_H__ -#define __ASURA_CONDITIONAL_H__ - -#include - -#include "mutex.h" -#include "semaphore.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -/// -/// 条件变量 -/// -class Conditional -{ -public: - - Conditional(); - ~Conditional(); - - void Signal(); - void Broadcast(); - bool Wait(Mutex* mutex, int timeout = ASURA_MUTEX_MAXWAIT); - -private: - - Mutex m_Mutex; - - Semaphore m_WaitSem; - Semaphore m_DoneSem; - - int m_Waiting; - int m_Signals; - -}; - -namespace_end -namespace_end - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/threading/coroutine.cpp b/source/modules/asura-utils/threading/coroutine.cpp deleted file mode 100644 index 552a415..0000000 --- a/source/modules/asura-utils/threading/coroutine.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "coroutine.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -/* -Coroutine::Coroutine() -{ - -} -*/ - - -namespace_end -namespace_end diff --git a/source/modules/asura-utils/threading/coroutine.h b/source/modules/asura-utils/threading/coroutine.h deleted file mode 100644 index 830dcd2..0000000 --- a/source/modules/asura-utils/threading/coroutine.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __ASURA_COROUTINE_H__ -#define __ASURA_COROUTINE_H__ - -#include - -#include "../scripting/portable.hpp" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -/// -/// lua协程,用来做一些逻辑并发操作。 -/// -class Coroutine ASURA_FINAL - : public AEScripting::Portable -{ -public: - - LUAX_DECL_FACTORY(Coroutine); - - - -private: - - /// - /// 当前协程的state - /// - lua_State* m_ThreadState; - - LUAX_DECL_METHOD(_New); - LUAX_DECL_METHOD(_Run); - -}; - -namespace_end -namespace_end - -namespace AEThreading = AsuraEngine::Threading; - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/threading/mutex.cpp b/source/modules/asura-utils/threading/mutex.cpp deleted file mode 100644 index ff0b3fa..0000000 --- a/source/modules/asura-utils/threading/mutex.cpp +++ /dev/null @@ -1,105 +0,0 @@ -#include - -#include "mutex.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -#define try_create_mutex(impl)\ -if (!m_Impl) \ -{ \ -try \ -{ \ - m_Impl = new impl(); \ -} \ -catch (Exception& e) \ -{ \ - m_Impl = nullptr; \ -} \ -} - -Mutex::Mutex() - : m_Impl(nullptr) -{ -#if ASURA_MUTEX_WIN32_CRITICLE_SECTION - try_create_mutex(MutexImplWin32_CS); -#endif -#if ASURA_MUTEX_WIN32_KERNAL_MUTEX - try_create_mutex(MutexImplWin32_KM); -#endif - ASSERT(m_Impl); -} - -Mutex::~Mutex() -{ - if(m_Impl) - delete m_Impl; -} - -void Mutex::Lock() -{ - ASSERT(m_Impl); - - m_Impl->Lock(); -} - -void Mutex::Unlock() -{ - ASSERT(m_Impl); - - m_Impl->Unlock(); -} - -#if ASURA_MUTEX_WIN32_CRITICLE_SECTION - -MutexImplWin32_CS::MutexImplWin32_CS() -{ - ::InitializeCriticalSection(&m_Mutex); -} - -MutexImplWin32_CS::~MutexImplWin32_CS() -{ - ::DeleteCriticalSection(&m_Mutex); -} - -void MutexImplWin32_CS::Lock() -{ - ::EnterCriticalSection(&m_Mutex); -} - -void MutexImplWin32_CS::Unlock() -{ - ::LeaveCriticalSection(&m_Mutex); -} - -#endif // ASURA_MUTEX_WIN32_CRITICLE_SECTION - -#if ASURA_MUTEX_WIN32_KERNAL_MUTEX - -MutexImplWin32_KM::MutexImplWin32_KM() -{ - m_Handle = ::CreateMutex(NULL, FALSE, NULL); - if (!m_Handle) - throw Exception("Cant use win32 mutex."); -} - -MutexImplWin32_KM::~MutexImplWin32_KM() -{ - ::CloseHandle(m_Handle); - m_Handle = NULL; -} - -void MutexImplWin32_KM::Lock() -{ - ::WaitForSingleObject(m_Handle, ASURA_MUTEX_MAXWAIT); -} - -void MutexImplWin32_KM::Unlock() -{ - ::ReleaseMutex(m_Handle); -} - -#endif // ASURA_MUTEX_WIN32_KERNAL_MUTEX - -namespace_end -namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/threading/mutex.h b/source/modules/asura-utils/threading/mutex.h deleted file mode 100644 index 623a3db..0000000 --- a/source/modules/asura-utils/threading/mutex.h +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef __ASURA_MUTEX_H__ -#define __ASURA_MUTEX_H__ - -#include -#include - -#include "../utils_config.h" - -#if ASURA_THREAD_WIN32 -#include -#endif - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -#define ASURA_MUTEX_MAXWAIT (~(uint32)0) - -class MutexImpl; - -class Mutex -{ -public: - - Mutex(); - ~Mutex(); - - void Lock(); - void Unlock(); - -private: - - // 禁止复制 - Mutex(const Mutex&); - Mutex& operator=(const Mutex&); - - MutexImpl* m_Impl; - -}; - -class _mutex_locker -{ -public: - _mutex_locker(Mutex& mutex) - : m(mutex) - { - m.Lock(); - }; - ~_mutex_locker() - { - m.Unlock(); - } - operator bool() { return false; }; -private: - void* operator new(size_t); - Mutex& m; -}; - -#define lock(m) \ -if(_mutex_locker _asura_mutex_locker = m){} else - -ASURA_ABSTRACT class MutexImpl -{ -public: - - MutexImpl() {}; - virtual ~MutexImpl() {}; - - virtual void Lock() = 0; - virtual void Unlock() = 0; - -}; - -#if ASURA_MUTEX_WIN32_CRITICLE_SECTION - -//https://blog.csdn.net/l799623787/article/details/18259949 -class MutexImplWin32_CS ASURA_FINAL : public MutexImpl -{ -public: - - MutexImplWin32_CS(); - ~MutexImplWin32_CS(); - - void Lock() override; - void Unlock() override; - -private: - - //HANDLE m_Handle; - CRITICAL_SECTION m_Mutex; - -}; - -#endif // ASURA_MUTEX_WIN32_CRITICLE_SECTION - -#if ASURA_MUTEX_WIN32_KERNAL_MUTEX - -class MutexImplWin32_KM ASURA_FINAL : public MutexImpl -{ -public: - - MutexImplWin32_KM(); - ~MutexImplWin32_KM(); - - void Lock() override; - void Unlock() override; - -private: - - HANDLE m_Handle; - -}; - -#endif // ASURA_MUTEX_WIN32_KERNAL_MUTEX - -#if ASURA_THREAD_STD - -class MutexImplSTD ASURA_FINAL : public MutexImpl -{ -}; - -#endif // ASURA_THREAD_STD - -namespace_end -namespace_end - -namespace AEThreading = AsuraEngine::Threading; - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/threading/semaphore.cpp b/source/modules/asura-utils/threading/semaphore.cpp deleted file mode 100644 index f9ffb35..0000000 --- a/source/modules/asura-utils/threading/semaphore.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "../exceptions/exception.h" -#include "../type.h" - -#include "mutex.h" -#include "semaphore.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -#define try_create_semaphore(impl) \ -if (!m_Impl) \ -{ \ - try \ - { \ - m_Impl = new impl(init_count); \ - } \ - catch (Exception& e) \ - { \ - m_Impl = nullptr; \ - } \ -} - -Semaphore::Semaphore(unsigned int init_count) - : m_Impl(nullptr) -{ -#ifdef ASURA_THREAD_WIN32 - try_create_semaphore(SemaphoreWin32); -#endif - //ASSERT(m_Impl); -} - -Semaphore::~Semaphore() -{ - if (m_Impl) delete m_Impl; -} - -void Semaphore::Signal() -{ - ASSERT(m_Impl); - m_Impl->Signal(); -} - -bool Semaphore::Wait(int timeout /*= ASURA_MUTEX_MAXWAIT*/) -{ - ASSERT(m_Impl); - return m_Impl->Wait(timeout); -} - -#if ASURA_THREAD_WIN32 - -SemaphoreWin32::SemaphoreWin32(unsigned int init_value) - : SemaphoreImpl(init_value) -{ - // UINT_MAX get error. - m_Sem = CreateSemaphore(NULL, init_value, INT_MAX, NULL); - if (!m_Sem) - { - int errorCode = GetLastError(); - throw Exception("Cant use win32 semaphore. Error code: %d.", errorCode); - } -} - -SemaphoreWin32::~SemaphoreWin32() -{ - CloseHandle(m_Sem); -} - -void SemaphoreWin32::Signal() -{ - InterlockedIncrement(&m_Count); - if (ReleaseSemaphore(m_Sem, 1, NULL) == FALSE) - InterlockedDecrement(&m_Count); -} - -bool SemaphoreWin32::Wait(int timeout) -{ - int result; - result = WaitForSingleObject(m_Sem, timeout); - if (result == WAIT_OBJECT_0) - { - InterlockedDecrement(&m_Count); - return true; - } - else if(result == WAIT_TIMEOUT) - { - // 超时 - return false; - } - else - { - // 未知错误 - throw Exception("WaitForSingleObject() failed"); - } -} - -#endif // ASURA_THREAD_WIN32 - -namespace_end -namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/threading/semaphore.h b/source/modules/asura-utils/threading/semaphore.h deleted file mode 100644 index ae7b10b..0000000 --- a/source/modules/asura-utils/threading/semaphore.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef __ASURA_SEMAPHORE_H__ -#define __ASURA_SEMAPHORE_H__ - -#include "../utils_config.h" - -#if ASURA_THREAD_WIN32 -#include -#endif - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -class SemaphoreImpl; - -/// -/// 信号量 -/// -class Semaphore -{ -public: - - Semaphore(unsigned int init_count = 1); - ~Semaphore(); - - void Signal(); - bool Wait(int timeout = ASURA_MUTEX_MAXWAIT); - -private: - SemaphoreImpl* m_Impl; -}; - -class SemaphoreImpl -{ -public: - SemaphoreImpl(unsigned int init_value) - : m_Count(init_value) - { - }; - virtual ~SemaphoreImpl() {}; - virtual void Signal() = 0; - virtual bool Wait(int timeout) = 0; - inline int Current() { return m_Count; } -protected: - unsigned int m_Count; -}; - -#define wait(sem, ...) sem.Wait(__VA_ARGS__) -#define signal(sem) sem.Signal() - -#if ASURA_THREAD_WIN32 - -class SemaphoreWin32 : public SemaphoreImpl -{ -public: - SemaphoreWin32(unsigned int init_value); - ~SemaphoreWin32(); - void Signal() override; - bool Wait(int timeout) override; -private: - HANDLE m_Sem; -}; - -#endif // ASURA_THREAD_WIN32 - -namespace_end -namespace_end - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/threading/task.cpp b/source/modules/asura-utils/threading/task.cpp deleted file mode 100644 index ea3f68e..0000000 --- a/source/modules/asura-utils/threading/task.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include "task.h" -#include "../scripting/portable.hpp" - -using namespace AEScripting; - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -namespace_end -namespace_end diff --git a/source/modules/asura-utils/threading/task.h b/source/modules/asura-utils/threading/task.h deleted file mode 100644 index b959012..0000000 --- a/source/modules/asura-utils/threading/task.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __ASURA_THRAD_TASK_H__ -#define __ASURA_THRAD_TASK_H__ - -#include -#include -#include - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -/// -/// 希望放在另一个线程处理的任务,继承Task并重写Execute方法。 -/// -ASURA_ABSTRACT class Task : public AEScripting::Object -{ -public: - - Task() {}; - virtual ~Task() {}; - - /// - /// 执行任务,完成后返回true,调用回调函数。 - /// - virtual bool Execute() = 0; - - /// - /// 调用回调。在invoke thread里面回调。 - /// - virtual void Invoke(lua_State* invokeThreaad) = 0; - -protected: - - // 取回调函数 - Luax::LuaxMemberRef m_Callback; - -}; - -namespace_end -namespace_end - -namespace AEThreading = AsuraEngine::Threading; - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/threading/thread.cpp b/source/modules/asura-utils/threading/thread.cpp deleted file mode 100644 index cb71d32..0000000 --- a/source/modules/asura-utils/threading/thread.cpp +++ /dev/null @@ -1,287 +0,0 @@ -#include "thread.h" - -#include "thread_impl_win32.h" -#include "thread_impl_posix.h" -#include "thread_impl_sdl.h" -#include "thread_impl_std.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -Thread::Thread(lua_State* luaThread, ThreadType type /*= THREAD_TYPE_DEFERRED*/, uint sleepTime /*= 0*/, const std::string& name /*= ""*/) - : m_Name(name) - , m_State(THREAD_STATE_IDLE) - , m_Type(type) - , m_LuaThread(luaThread) - , m_CallbackThread(nullptr) - , m_SleepTime(sleepTime) -{ - LUAX_STATE(luaThread); - if (type == THREAD_TYPE_IMMEDIATE) - { - Luax::LuaxVM* vm = state.GetVM(); - ASSERT(vm); - m_CallbackThread = vm->CreateThread(); - ASSERT(m_CallbackThread); - SetLuaxMemberRef(state, m_CallbackThreadRef, -1); - state.Pop(); // callback thread - } -} - -Thread::~Thread() -{ - if (m_Impl) - { - delete m_Impl; - m_Impl = nullptr; - } -} - -bool Thread::AddTask(Task* task) -{ - lock(m_TaskQueueMutex) - { - task->Retain(); - m_TaskQueue.push(task); - } - return true; -} - -uint Thread::GetTaskCount() -{ - return m_TaskQueue.size(); -} - -void Thread::Idle() -{ - m_State = THREAD_STATE_IDLE; -} - -#define try_start_thread(impl)\ -if (!m_Impl) \ -{ \ -m_Impl = new impl(); \ -if (!m_Impl->Start(this, stacksize)) \ -{ \ - delete m_Impl; \ - m_Impl = nullptr; \ -} \ -} - -bool Thread::Start(bool isDaemon /*= true*/, uint32 stacksize /*= 0*/) -{ - if (m_State != THREAD_STATE_IDLE) - return false; - - // 如果已经存在一个之前创建的,关闭它。 - if (m_Impl) - { - delete m_Impl; - m_Impl = nullptr; - } - -#if ASURA_THREAD_WIN32 - try_start_thread(ThreadImplWin32); -#endif - - if (!m_Impl) - return false; - - m_IsDaemon = isDaemon; - m_StateMutex.Lock(); - m_State = THREAD_STATE_RUNNING; - m_StateMutex.Unlock(); -} - -void Thread::Pause() -{ - ASSERT(m_Impl); - - lock(m_StateMutex) - { - m_State = THREAD_STATE_PAUSED; - } -} - -void Thread::Resume() -{ - ASSERT(m_Impl); - - lock(m_StateMutex) - { - if (m_State == THREAD_STATE_PAUSED) - m_State = THREAD_STATE_RUNNING; - } -} - -void Thread::Stop() -{ - ASSERT(m_Impl); - - lock(m_StateMutex) - { - m_State = THREAD_STATE_STOPPED; - } -} - -void Thread::PauseSync() -{ - Pause(); - wait(m_SemPause); -} - -void Thread::ResumeSync() -{ - Resume(); - wait(m_SemResume); -} - -void Thread::StopSync() -{ - Stop(); - wait(m_SemStop); -} - -void Thread::Join() -{ - ASSERT(m_Impl); - m_Impl->Join(); -} - -ThreadState Thread::GetState() -{ - ThreadState state; - lock(m_StateMutex) - { - state = m_State; - } - return state; -} - -bool Thread::IsRunning() -{ - ASSERT(m_Impl); - - return GetState() == THREAD_STATE_RUNNING; -} - -bool Thread::IsPaused() -{ - ASSERT(m_Impl); - - return GetState() == THREAD_STATE_PAUSED; -} - -bool Thread::IsStopped() -{ - ASSERT(m_Impl); - - return GetState() == THREAD_STATE_STOPPED; -} - -bool Thread::IsCurrent() -{ - ASSERT(m_Impl); - - return m_Impl->IsCurrent(); -} - -const std::string& Thread::GetName() -{ - return m_Name; -} - -int Thread::Process() -{ - LUAX_STATE(m_LuaThread); - - do{ - if (IsRunning()) - { - while (!m_TaskQueue.empty()) - { - Task* task = m_TaskQueue.front(); - if (task && task->Execute()) - { - if (m_Type == THREAD_TYPE_DEFERRED) - { - m_FinishedMutex.Lock(); - task->Retain(); - m_FinishedTasks.push(task); - m_FinishedMutex.Unlock(); - } - else if (m_Type == THREAD_TYPE_IMMEDIATE) - { - // unsafe - task->Invoke(m_CallbackThread); - this->LuaxRelease(state, task); - } - m_TaskQueueMutex.Lock(); - m_TaskQueue.pop(); - task->Release(); - m_TaskQueueMutex.Unlock(); - } - } - } - - // 退出循环 - if (IsStopped()) - break; - - // 降低CPU使用率 - Sleep(m_SleepTime); - - } while (m_IsDaemon); - - // 非守护线程,先切到stop状态 - if (!m_IsDaemon) - Stop(); - - signal(m_SemStop); - - // 重置状态为Idle - Idle(); - - return 0; -} - -/// -/// 延迟模式主动发布回调、 -/// -void Thread::Dispatch() -{ - if (m_Type != THREAD_TYPE_DEFERRED) - return; - - LUAX_STATE(m_LuaThread); - while (!m_FinishedTasks.empty()) - { - Task* task = m_FinishedTasks.front(); - if (task) - { - task->Invoke(m_LuaThread); - this->LuaxRelease(state, task); - m_FinishedMutex.Lock(); - m_FinishedTasks.pop(); - task->Release(); - m_FinishedMutex.Unlock(); - } - } -} - -void Thread::Sleep(uint ms) -{ - ASSERT(m_Impl); - if (m_Impl) - { - m_Impl->Sleep(ms); - } -} - -void Thread::SetSleepTime(uint ms) -{ - m_SleepTime = ms; -} - -namespace_end -namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/threading/thread.h b/source/modules/asura-utils/threading/thread.h deleted file mode 100644 index 0235b6a..0000000 --- a/source/modules/asura-utils/threading/thread.h +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef __ASURA_THREAD_H__ -#define __ASURA_THREAD_H__ - -#include -#include - -#include - -#include "task.h" -#include "mutex.h" -#include "semaphore.h" -#include "threadable.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -class ThreadImpl; - -/// -/// 线程的几种不同的实现: -/// 1: Deferred(延迟模式),线程上的任务完成后,需要手动在主线程调用Dispatch方法, -/// 在主线程调回调函数,将发布从异步改为同步操作,解决主lua_State冲突的问题。 -/// 2: Immediate(立即模式),每一个线程维护一个lua_newthread创建出来的lua_State。 -/// 回调函数在不同的lua_State中调用,避免不同的线程访问同一个lua_State。 -/// -enum ThreadType -{ - THREAD_TYPE_DEFERRED, - THREAD_TYPE_IMMEDIATE, // unsafe -}; - -enum ThreadState -{ - THREAD_STATE_IDLE, ///< 闲置,还未创建内核对象 - THREAD_STATE_RUNNING, ///< 正在运行循环 - THREAD_STATE_PAUSED, ///< 在循环中暂停 - THREAD_STATE_STOPPED, ///< 退出循环 -}; - -/// -/// 线程主体,每个线程维护一个task queue。 -/// -class Thread ASURA_FINAL - : public AEScripting::Portable - , public Threadable -{ -public: - - LUAX_DECL_FACTORY(Thread); - - Thread(lua_State* luaThread, ThreadType type = THREAD_TYPE_DEFERRED, uint sleepTime = 1, const std::string& name = ""); - ~Thread(); - - bool AddTask(Task* task); - /// - /// 获得等待处理的任务数 - /// - uint GetTaskCount(); - - void Idle(); - - /// - /// 创建内核对象,并运行。如果是daemon,会等待手动stop。否则会在某时刻队列完成后自动stop。 - /// - bool Start(bool daemon = true, uint32 stacksize = 0); - - /// - /// 非同步线程控制,不是实时的。可能需要在主线程里使用Is函数确认到达指定状态。 - /// - void Pause(); - void Resume(); - void Stop(); - - /// - /// 同步线程控制,会等返回来信号后继续向下执行。会造成主线程等待。 - /// - void PauseSync(); - void ResumeSync(); - void StopSync(); - - /// - /// 父线程等待本线程结束后才继续执行。 - /// - void Join(); - - ThreadState GetState(); - - /// - /// 逻辑层面的线程状态: - /// 1: Idle(空闲),线程创建后的默认状态,可以随时加任务并且Start。 - /// 2: Running(运行),内核对象呗创建,已经处于内核调度中,并处理具体Task。 - /// 3: Paused(暂停),依然存在于内核中,但是跳过了对任务的处理,逻辑上暂停。 - /// 4: Stopped(停止),依然存在于内核中,但是已经无法继续处理任务。 - /// - bool IsIdle(); - bool IsRunning(); - bool IsPaused(); - bool IsStopped(); - - bool IsCurrent(); - - /// - /// 执行任务队列。 - /// - int Process() override; - - const std::string& GetName(); - - /// - /// 回调。 - /// - void Dispatch(); - - /// - /// 休眠函数 - /// - void Sleep(uint ms); - - /// - /// 设置休眠时间 - /// - void SetSleepTime(uint ms); - -private: - - //----------------------------------------------------------------------------// - - LUAX_DECL_ENUM(ThreadType); - LUAX_DECL_ENUM(ThreadState); - - LUAX_DECL_METHOD(_New); - LUAX_DECL_METHOD(_AddTask); - LUAX_DECL_METHOD(_Start); - LUAX_DECL_METHOD(_Idle); - LUAX_DECL_METHOD(_Pause); - LUAX_DECL_METHOD(_Resume); - LUAX_DECL_METHOD(_Stop); - LUAX_DECL_METHOD(_Join); - LUAX_DECL_METHOD(_IsRunning); - LUAX_DECL_METHOD(_IsPaused); - LUAX_DECL_METHOD(_IsStopped); - LUAX_DECL_METHOD(_IsCurrent); - LUAX_DECL_METHOD(_Sleep); - LUAX_DECL_METHOD(_Dispatch); - LUAX_DECL_METHOD(_GetName); - LUAX_DECL_METHOD(_GetType); - LUAX_DECL_METHOD(_GetState); - LUAX_DECL_METHOD(_SetSleepTime); - - //----------------------------------------------------------------------------// - - ThreadImpl* m_Impl; - - lua_State* m_LuaThread; - - /// - /// 此次运行是否是守护模式。 - /// - bool m_IsDaemon; - - std::string m_Name; - ThreadType m_Type; - uint m_SleepTime; - - ThreadState m_State; - Mutex m_StateMutex; - - /// - /// 同步控制相关的信号量 - /// - Semaphore m_SemPause; - Semaphore m_SemResume; - Semaphore m_SemStop; - - /// - /// 待处理的任务队列。 - /// - std::queue m_TaskQueue; - Mutex m_TaskQueueMutex; - - /// - /// 延迟模式使用 - /// - std::queue m_FinishedTasks; - Mutex m_FinishedMutex; - - /// - /// 立即模式使用,回调使用的lua线程 - /// - lua_State* m_CallbackThread; - Luax::LuaxMemberRef m_CallbackThreadRef; - -}; - -/// -/// 线程的具体实现,对用户是透明的,一共准备了四种策略: -/// 1: win32 -/// 2: posix -/// 3: SDL -/// 4: std::thread -/// -ASURA_ABSTRACT class ThreadImpl -{ -public: - ThreadImpl() {}; - virtual ~ThreadImpl() {}; - - virtual bool Start(Threadable* thread, uint32 stacksize = 0) = 0; - virtual void Join() = 0; - virtual void Kill() = 0; - - virtual void Sleep(uint ms) = 0; - - virtual bool IsRunning() = 0; - virtual bool IsCurrent() = 0; - -}; - -namespace_end -namespace_end - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/threading/thread_impl_posix.cpp b/source/modules/asura-utils/threading/thread_impl_posix.cpp deleted file mode 100644 index d59bd8f..0000000 --- a/source/modules/asura-utils/threading/thread_impl_posix.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "thread_impl_posix.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - - - -namespace_end -namespace_end \ No newline at end of file diff --git a/source/modules/asura-utils/threading/thread_impl_posix.h b/source/modules/asura-utils/threading/thread_impl_posix.h deleted file mode 100644 index a65a2ca..0000000 --- a/source/modules/asura-utils/threading/thread_impl_posix.h +++ /dev/null @@ -1,2 +0,0 @@ -#include - diff --git a/source/modules/asura-utils/threading/thread_impl_sdl.cpp b/source/modules/asura-utils/threading/thread_impl_sdl.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/source/modules/asura-utils/threading/thread_impl_sdl.h b/source/modules/asura-utils/threading/thread_impl_sdl.h deleted file mode 100644 index e69de29..0000000 diff --git a/source/modules/asura-utils/threading/thread_impl_std.cpp b/source/modules/asura-utils/threading/thread_impl_std.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/source/modules/asura-utils/threading/thread_impl_std.h b/source/modules/asura-utils/threading/thread_impl_std.h deleted file mode 100644 index a2623ee..0000000 --- a/source/modules/asura-utils/threading/thread_impl_std.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __ASURA_THREAD_STD_H__ -#define __ASURA_THREAD_STD_H__ - -#include "../utils_config.h" - -#if ASURA_THREAD_STD - -#include - -#include "thread.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -/// -/// Thread的std::thread实现。 -/// -class ThreadImplSTD : public ThreadImpl -{ -public: - - ThreadImplSTD(); - ~ThreadImplSTD(); - - bool Start(Threadable* thread, uint32 stacksize) override; - void Join() override; - void Kill() override; - - bool IsRunning() override; - bool IsCurrent() override; - -private: - -}; - -namespace_end -namespace_end - -#endif // #if ASURA_THREAD_STD - -#endif // __ASURA_THREAD_STD_H__ \ No newline at end of file diff --git a/source/modules/asura-utils/threading/thread_impl_win32.cpp b/source/modules/asura-utils/threading/thread_impl_win32.cpp deleted file mode 100644 index c876be9..0000000 --- a/source/modules/asura-utils/threading/thread_impl_win32.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "thread_impl_win32.h" -#include "thread.h" - -#include - -#if ASURA_THREAD_WIN32 - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -static DWORD WINAPI _thread_win32_runner(LPVOID param) -{ - Threadable* thread = (Threadable*)param; - return thread->Process(); // 尾调用 -} - -ThreadImplWin32::ThreadImplWin32() -{ -} - -ThreadImplWin32::~ThreadImplWin32() -{ - if (!m_Handle) return; - ::CloseHandle(m_Handle); - m_Handle = 0; -} - -bool ThreadImplWin32::Start(Threadable* thread, uint32 stacksize/*=0*/) -{ - assert(!IsRunning()); - m_Handle = ::CreateThread( - NULL - , stacksize - , _thread_win32_runner - , thread - , 0 /*创建后立即进行调度*/ - , NULL); - - return m_Handle; -} - -void ThreadImplWin32::Join() -{ - // 父线程等待此线程返回 - ::WaitForSingleObject(m_Handle, INFINITE); -} - -void ThreadImplWin32::Kill() -{ - ::TerminateThread(m_Handle, FALSE); -} - -void ThreadImplWin32::Sleep(uint ms) -{ - ::Sleep(ms); -} - -bool ThreadImplWin32::IsRunning() -{ - if (m_Handle) { - DWORD exitCode = 0; - // https://blog.csdn.net/yuanmeng567/article/details/19485719 - ::GetExitCodeThread(m_Handle, &exitCode); - return exitCode == STILL_ACTIVE; - } - return false; -} - -bool ThreadImplWin32::IsCurrent() -{ - return m_Handle == ::GetCurrentThread(); -} - -namespace_end -namespace_end - -#endif // ASURA_THREAD_WIN32 \ No newline at end of file diff --git a/source/modules/asura-utils/threading/thread_impl_win32.h b/source/modules/asura-utils/threading/thread_impl_win32.h deleted file mode 100644 index 846670b..0000000 --- a/source/modules/asura-utils/threading/thread_impl_win32.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __ASURA_THREAD_WIN32_H__ -#define __ASURA_THREAD_WIN32_H__ - -#include "../utils_config.h" - -#if ASURA_THREAD_WIN32 - -#include - -#include "thread.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -/// -/// Thread的win32实现。 -/// -class ThreadImplWin32 : public ThreadImpl -{ -public: - - ThreadImplWin32(); - ~ThreadImplWin32(); - - bool Start(Threadable* thread, uint32 stacksize) override; - void Join() override; - void Kill() override; - - void Sleep(uint ms) override; - - bool IsRunning() override; - bool IsCurrent() override; - -private: - - HANDLE m_Handle; - -}; - -namespace_end -namespace_end - -#endif // #if ASURA_THREAD_WIN32 -#endif // __ASURA_THREAD_WIN32_H__ \ No newline at end of file diff --git a/source/modules/asura-utils/threading/threadable.h b/source/modules/asura-utils/threading/threadable.h deleted file mode 100644 index 66973c5..0000000 --- a/source/modules/asura-utils/threading/threadable.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __ASURA_THREADABLE_H__ -#define __ASURA_THREADABLE_H__ - -#include "../type.h" - -namespace_begin(AsuraEngine) -namespace_begin(Threading) - -ASURA_ABSTRACT class Threadable -{ -public: - - Threadable() {}; - virtual ~Threadable() {}; - - virtual int Process() = 0; - -}; - -namespace_end -namespace_end - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/type.h b/source/modules/asura-utils/type.h index 2976d3e..f7e54c6 100644 --- a/source/modules/asura-utils/type.h +++ b/source/modules/asura-utils/type.h @@ -1,10 +1,10 @@ -#ifndef __ASURA_UTILS_TYPE_H__ -#define __ASURA_UTILS_TYPE_H__ +#ifndef _ASURA_UTILS_TYPE_H_ +#define _ASURA_UTILS_TYPE_H_ #include #include -#include "asura-base/config.h" +#include "asura-base/Config.h" namespace AsuraEngine { @@ -31,4 +31,4 @@ namespace AsuraEngine } // namespace AsuraEngine -#endif // __ASURA_CONFIG_H__ \ No newline at end of file +#endif // _ASURA_CONFIG_H_ \ No newline at end of file diff --git a/source/modules/asura-utils/utils.h b/source/modules/asura-utils/utils.h index ce1c6a1..dfcd2a6 100644 --- a/source/modules/asura-utils/utils.h +++ b/source/modules/asura-utils/utils.h @@ -1,6 +1,6 @@ -#ifndef __ASURA_UTILS_H__ -#define __ASURA_UTILS_H__ +#ifndef _ASURA_UTILS_H_ +#define _ASURA_UTILS_H_ -#include "utils_module.h" +#include "UtilsModule.h" #endif \ No newline at end of file diff --git a/source/modules/asura-utils/utils_config.h b/source/modules/asura-utils/utils_config.h deleted file mode 100644 index 7b120f0..0000000 --- a/source/modules/asura-utils/utils_config.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __ASURA_UTILS_CONFIG_H__ -#define __ASURA_UTILS_CONFIG_H__ - -// 基本的编译配置 -#include "asura-base/config.h" - -#define ASURA_THREAD_WIN32 1 -#define ASURA_THREAD_STD 1 - -#define ASURA_MUTEX_WIN32_CRITICLE_SECTION 1 -#define ASURA_MUTEX_WIN32_KERNAL_MUTEX 1 - -#endif \ No newline at end of file diff --git a/source/modules/asura-utils/utils_module.cpp b/source/modules/asura-utils/utils_module.cpp deleted file mode 100644 index 5616be4..0000000 --- a/source/modules/asura-utils/utils_module.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "utils_module.h" - -using namespace AsuraEngine::IO; -using namespace AsuraEngine::Threading; - -namespace AsuraEngine -{ - - void UtilsModule::Initialize(Luax::LuaxState& state) - { - // IO - LUAX_REGISTER_SINGLETON(state, Filesystem); - LUAX_REGISTER_FACTORY(state, IOTask); - LUAX_REGISTER_FACTORY(state, DataBuffer); - LUAX_REGISTER_FACTORY(state, FileData); - LUAX_REGISTER_FACTORY(state, File); - // Threading - LUAX_REGISTER_FACTORY(state, Thread); - } - - void UtilsModule::Finalize(Luax::LuaxState& state) - { - } - -} \ No newline at end of file diff --git a/source/modules/asura-utils/utils_module.h b/source/modules/asura-utils/utils_module.h deleted file mode 100644 index 479b052..0000000 --- a/source/modules/asura-utils/utils_module.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __ASURA_LIBS_UTIL_MODULE_H__ -#define __ASURA_LIBS_UTIL_MODULE_H__ - -#include "io/file_system.h" -#include "io/data_buffer.h" -#include "io/file_data.h" -#include "io/file.h" -#include "io/io_task.h" - -#include "threading/thread.h" - -#include "module.h" - -#include "classes.h" - -namespace AsuraEngine -{ - - /// - /// Asura公用模块 - /// - class UtilsModule ASURA_FINAL : public Module - { - public: - - void Initialize(Luax::LuaxState& state) override; - - void Finalize(Luax::LuaxState& state) override; - - }; - -} - -#endif \ No newline at end of file -- cgit v1.1-26-g67d0