From 8b00d67febf133e89f6a0bfabc41feed555dc4a9 Mon Sep 17 00:00:00 2001 From: chai Date: Sat, 12 Jan 2019 21:48:33 +0800 Subject: =?UTF-8?q?*=E5=8E=BB=E6=8E=89=E6=96=87=E4=BB=B6=E5=89=8D=E7=BC=80?= =?UTF-8?q?je=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libjin/common/array.hpp | 123 ++++++++++++++++++++++++++ src/libjin/common/common.h | 8 ++ src/libjin/common/exception.cpp | 46 ++++++++++ src/libjin/common/exception.h | 46 ++++++++++ src/libjin/common/je_array.hpp | 123 -------------------------- src/libjin/common/je_common.h | 8 -- src/libjin/common/je_exception.cpp | 46 ---------- src/libjin/common/je_exception.h | 46 ---------- src/libjin/common/je_noncopyable.h | 26 ------ src/libjin/common/je_object.h | 19 ---- src/libjin/common/je_pool.hpp | 177 ------------------------------------- src/libjin/common/je_singleton.hpp | 84 ------------------ src/libjin/common/je_string.h | 72 --------------- src/libjin/common/je_stringmap.hpp | 145 ------------------------------ src/libjin/common/je_subsystem.hpp | 74 ---------------- src/libjin/common/je_temporary.h | 33 ------- src/libjin/common/je_types.h | 34 ------- src/libjin/common/noncopyable.h | 26 ++++++ src/libjin/common/object.h | 19 ++++ src/libjin/common/pool.hpp | 177 +++++++++++++++++++++++++++++++++++++ src/libjin/common/singleton.hpp | 84 ++++++++++++++++++ src/libjin/common/string.h | 72 +++++++++++++++ src/libjin/common/stringmap.hpp | 145 ++++++++++++++++++++++++++++++ src/libjin/common/subsystem.hpp | 74 ++++++++++++++++ src/libjin/common/temporary.h | 33 +++++++ src/libjin/common/types.h | 34 +++++++ 26 files changed, 887 insertions(+), 887 deletions(-) create mode 100644 src/libjin/common/array.hpp create mode 100644 src/libjin/common/common.h create mode 100644 src/libjin/common/exception.cpp create mode 100644 src/libjin/common/exception.h delete mode 100644 src/libjin/common/je_array.hpp delete mode 100644 src/libjin/common/je_common.h delete mode 100644 src/libjin/common/je_exception.cpp delete mode 100644 src/libjin/common/je_exception.h delete mode 100644 src/libjin/common/je_noncopyable.h delete mode 100644 src/libjin/common/je_object.h delete mode 100644 src/libjin/common/je_pool.hpp delete mode 100644 src/libjin/common/je_singleton.hpp delete mode 100644 src/libjin/common/je_string.h delete mode 100644 src/libjin/common/je_stringmap.hpp delete mode 100644 src/libjin/common/je_subsystem.hpp delete mode 100644 src/libjin/common/je_temporary.h delete mode 100644 src/libjin/common/je_types.h create mode 100644 src/libjin/common/noncopyable.h create mode 100644 src/libjin/common/object.h create mode 100644 src/libjin/common/pool.hpp create mode 100644 src/libjin/common/singleton.hpp create mode 100644 src/libjin/common/string.h create mode 100644 src/libjin/common/stringmap.hpp create mode 100644 src/libjin/common/subsystem.hpp create mode 100644 src/libjin/common/temporary.h create mode 100644 src/libjin/common/types.h (limited to 'src/libjin/common') diff --git a/src/libjin/common/array.hpp b/src/libjin/common/array.hpp new file mode 100644 index 0000000..8a5cbf1 --- /dev/null +++ b/src/libjin/common/array.hpp @@ -0,0 +1,123 @@ +#ifndef __JE_COMMON_ARRAY_H__ +#define __JE_COMMON_ARRAY_H__ + +namespace JinEngine +{ + + /// + /// A array created on heap. + /// + template + class Array + { + public: + /// + /// Array constructor. + /// + Array() + : length(0) + , data(nullptr) + { + } + + /// + /// Array constructor. + /// + /// @param l Length of array. + /// + Array(int l) + { + length = l; + data = new T[l]; + } + + /// + /// Array destructor. + /// + ~Array() + { + delete[] data; + length = 0; + } + + /// + /// Get address of data. + /// + /// @return Address of data. + /// + T* operator &() + { + return data; + } + + /// + /// Get specific element of array. + /// + /// @return Element of array. + /// + T& operator[](int index) + { + return data[index]; + } + + /// + /// Bind data with given data. + /// + /// @param data Data pointer. + /// @param length Length of data. + /// + void bind(T* data, int length) + { + if (data != nullptr) + delete data; + this->data = data; + this->length = length; + } + + /// + /// Add an element. + /// + /// @param v Value of element. + /// + void add(T value) + { + int len = length + 1; + T* d = new T[len]; + memcpy(d, data, size()); + d[length] = value; + bind(d, len); + } + + /// + /// Get size of data in byte. + /// + /// @return Size of data in byte. + /// + int size() + { + return sizeof(T) * length; + } + + /// + /// Get length of data. + /// + /// @return Count of data. + /// + int count() + { + return length; + } + + private: + // Disable new and delete. + void* operator new(size_t t); + void operator delete(void* ptr); + + T * data; + unsigned int length; + + }; + +} // namespace JinEngine + +#endif \ No newline at end of file diff --git a/src/libjin/common/common.h b/src/libjin/common/common.h new file mode 100644 index 0000000..6ca4dfd --- /dev/null +++ b/src/libjin/common/common.h @@ -0,0 +1,8 @@ +#ifndef __JE_COMMON_H__ +#define __JE_COMMON_H__ + +#include "exception.h" +#include "array.hpp" +#include "string.h" + +#endif \ No newline at end of file diff --git a/src/libjin/common/exception.cpp b/src/libjin/common/exception.cpp new file mode 100644 index 0000000..dc4e6ac --- /dev/null +++ b/src/libjin/common/exception.cpp @@ -0,0 +1,46 @@ +#include + +#include "exception.h" + +namespace JinEngine +{ + + 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); + + // see http://perfec.to/vsnprintf/pasprintf.c + // if size_out ... + // == -1 --> output was truncated + // == size_buffer --> output was truncated + // == size_buffer-1 --> ambiguous, /may/ have been truncated + // > size_buffer --> output was truncated, and size_out + // bytes would have been written + 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; // to avoid the ambiguous case + else + break; + + delete[] buffer; + } + mMessage = std::string(buffer); + delete[] buffer; + } + + Exception::~Exception() throw() + { + } + +} // namespace JinEngine \ No newline at end of file diff --git a/src/libjin/common/exception.h b/src/libjin/common/exception.h new file mode 100644 index 0000000..0dee14c --- /dev/null +++ b/src/libjin/common/exception.h @@ -0,0 +1,46 @@ +#ifndef __JE_EXCEPTION_H__ +#define __JE_EXCEPTION_H__ + +#include +#include + +#include "object.h" + +namespace JinEngine +{ + + /// + /// Jin Exception. + /// + class Exception : public Object, public std::exception + { + public: + /// + /// Creates a new Exception according to printf-rules. + /// + /// @param fmt The format string (see printf). + /// + Exception(const char *fmt, ...); + virtual ~Exception() throw(); + + /// + /// Returns a string containing reason for the exception. + /// + /// @return A description of the exception. + /// + inline virtual const char *what() const throw() + { + return mMessage.c_str(); + } + + private: + /// + /// Exception message. + /// + std::string mMessage; + + }; + +} // namespace JinEngine + +#endif \ No newline at end of file diff --git a/src/libjin/common/je_array.hpp b/src/libjin/common/je_array.hpp deleted file mode 100644 index 8a5cbf1..0000000 --- a/src/libjin/common/je_array.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#ifndef __JE_COMMON_ARRAY_H__ -#define __JE_COMMON_ARRAY_H__ - -namespace JinEngine -{ - - /// - /// A array created on heap. - /// - template - class Array - { - public: - /// - /// Array constructor. - /// - Array() - : length(0) - , data(nullptr) - { - } - - /// - /// Array constructor. - /// - /// @param l Length of array. - /// - Array(int l) - { - length = l; - data = new T[l]; - } - - /// - /// Array destructor. - /// - ~Array() - { - delete[] data; - length = 0; - } - - /// - /// Get address of data. - /// - /// @return Address of data. - /// - T* operator &() - { - return data; - } - - /// - /// Get specific element of array. - /// - /// @return Element of array. - /// - T& operator[](int index) - { - return data[index]; - } - - /// - /// Bind data with given data. - /// - /// @param data Data pointer. - /// @param length Length of data. - /// - void bind(T* data, int length) - { - if (data != nullptr) - delete data; - this->data = data; - this->length = length; - } - - /// - /// Add an element. - /// - /// @param v Value of element. - /// - void add(T value) - { - int len = length + 1; - T* d = new T[len]; - memcpy(d, data, size()); - d[length] = value; - bind(d, len); - } - - /// - /// Get size of data in byte. - /// - /// @return Size of data in byte. - /// - int size() - { - return sizeof(T) * length; - } - - /// - /// Get length of data. - /// - /// @return Count of data. - /// - int count() - { - return length; - } - - private: - // Disable new and delete. - void* operator new(size_t t); - void operator delete(void* ptr); - - T * data; - unsigned int length; - - }; - -} // namespace JinEngine - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_common.h b/src/libjin/common/je_common.h deleted file mode 100644 index a34268a..0000000 --- a/src/libjin/common/je_common.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __JE_COMMON_H__ -#define __JE_COMMON_H__ - -#include "je_exception.h" -#include "je_array.hpp" -#include "je_string.h" - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_exception.cpp b/src/libjin/common/je_exception.cpp deleted file mode 100644 index 5489a42..0000000 --- a/src/libjin/common/je_exception.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include - -#include "je_exception.h" - -namespace JinEngine -{ - - 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); - - // see http://perfec.to/vsnprintf/pasprintf.c - // if size_out ... - // == -1 --> output was truncated - // == size_buffer --> output was truncated - // == size_buffer-1 --> ambiguous, /may/ have been truncated - // > size_buffer --> output was truncated, and size_out - // bytes would have been written - 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; // to avoid the ambiguous case - else - break; - - delete[] buffer; - } - mMessage = std::string(buffer); - delete[] buffer; - } - - Exception::~Exception() throw() - { - } - -} // namespace JinEngine \ No newline at end of file diff --git a/src/libjin/common/je_exception.h b/src/libjin/common/je_exception.h deleted file mode 100644 index 71caa5a..0000000 --- a/src/libjin/common/je_exception.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __JE_EXCEPTION_H__ -#define __JE_EXCEPTION_H__ - -#include -#include - -#include "je_object.h" - -namespace JinEngine -{ - - /// - /// Jin Exception. - /// - class Exception : public Object, public std::exception - { - public: - /// - /// Creates a new Exception according to printf-rules. - /// - /// @param fmt The format string (see printf). - /// - Exception(const char *fmt, ...); - virtual ~Exception() throw(); - - /// - /// Returns a string containing reason for the exception. - /// - /// @return A description of the exception. - /// - inline virtual const char *what() const throw() - { - return mMessage.c_str(); - } - - private: - /// - /// Exception message. - /// - std::string mMessage; - - }; - -} // namespace JinEngine - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_noncopyable.h b/src/libjin/common/je_noncopyable.h deleted file mode 100644 index dab74a4..0000000 --- a/src/libjin/common/je_noncopyable.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef __JE_NONCOPYABLE_H__ -#define __JE_NONCOPYABLE_H__ - -#include "je_object.h" - -namespace JinEngine -{ - - /// - /// Class inherites this could not be copied. - /// - class Noncopyable : public Object - { - public: - Noncopyable(void) { } - virtual ~Noncopyable(void) { } - - private: - Noncopyable(const Noncopyable& other); - Noncopyable& operator=(const Noncopyable& other); - - }; - -} // namespace JinEngine - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_object.h b/src/libjin/common/je_object.h deleted file mode 100644 index 581500f..0000000 --- a/src/libjin/common/je_object.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __JE_OBJECT_H__ -#define __JE_OBJECT_H__ - -namespace JinEngine -{ - - /// - /// Base class of all classes in libjin. - /// - class Object - { - public: - virtual ~Object() {}; - - }; - -} // namespace JinEngine - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_pool.hpp b/src/libjin/common/je_pool.hpp deleted file mode 100644 index 0758b97..0000000 --- a/src/libjin/common/je_pool.hpp +++ /dev/null @@ -1,177 +0,0 @@ -/// -/// An O(1) Object Pool. Original from https://www.codeproject.com/Articles/746630/O-Object-Pool-in-Cplusplus -/// -#ifndef __JE_POOL_H__ -#define __JE_POOL_H__ - -#include -#include - -#include "je_types.h" - -namespace JinEngine -{ - - class DefaultMemoryAllocator : public Object - { - public: - static inline void *Allocate(size_t size) - { - return ::operator new(size, ::std::nothrow); - } - static inline void Deallocate(void *pointer, size_t size) - { - ::operator delete(pointer); - } - }; - - template - class Pool : public Object - { - private: - struct _Node - { - void *_memory; - size_t _capacity; - _Node *_nextNode; - - _Node(size_t capacity) - { - if (capacity < 1) - throw std::invalid_argument("capacity must be at least 1."); - - _memory = TMemoryAllocator::Allocate(_itemSize * capacity); - if (_memory == NULL) - throw std::bad_alloc(); - - _capacity = capacity; - _nextNode = NULL; - } - ~_Node() - { - TMemoryAllocator::Deallocate(_memory, _itemSize * _capacity); - } - }; - - void *_nodeMemory; - T *_firstDeleted; - size_t _countInNode; - size_t _nodeCapacity; - _Node _firstNode; - _Node *_lastNode; - size_t _maxBlockLength; - - static const size_t _itemSize; - - Pool(const Pool &source); - void operator = (const Pool &source); - - void _AllocateNewNode() - { - size_t size = _countInNode; - if (size >= _maxBlockLength) - size = _maxBlockLength; - else - { - size *= 2; - - if (size < _countInNode) - throw std::overflow_error("size became too big."); - - if (size >= _maxBlockLength) - size = _maxBlockLength; - } - - _Node *newNode = new _Node(size); - _lastNode->_nextNode = newNode; - _lastNode = newNode; - _nodeMemory = newNode->_memory; - _countInNode = 0; - _nodeCapacity = size; - } - - public: - explicit Pool(size_t initialCapacity = 32, size_t maxBlockLength = 1000000) - : _firstDeleted(NULL) - , _countInNode(0) - , _nodeCapacity(initialCapacity) - , _firstNode(initialCapacity) - , _maxBlockLength(maxBlockLength) - { - if (maxBlockLength < 1) - throw std::invalid_argument("maxBlockLength must be at least 1."); - - _nodeMemory = _firstNode._memory; - _lastNode = &_firstNode; - } - ~Pool() - { - _Node *node = _firstNode._nextNode; - while (node) - { - _Node *nextNode = node->_nextNode; - delete node; - node = nextNode; - } - } - - T *New() - { - if (_firstDeleted) - { - T *result = _firstDeleted; - _firstDeleted = *((T **)_firstDeleted); - new(result) T(); - return result; - } - - if (_countInNode >= _nodeCapacity) - _AllocateNewNode(); - - char *address = (char *)_nodeMemory; - address += _countInNode * _itemSize; - T *result = new(address) T(); - _countInNode++; - return result; - } - - // This method is useful if you want to call a non-default constructor. - // It should be used like this: - // new (pool.GetNextWithoutInitializing()) ObjectType(... parameters ...); - T *GetNextWithoutInitializing() - { - if (_firstDeleted) - { - T *result = (T *)_firstDeleted; - _firstDeleted = *((T **)_firstDeleted); - return result; - } - - if (_countInNode >= _nodeCapacity) - _AllocateNewNode(); - - char *address = (char *)_nodeMemory; - address += _countInNode * _itemSize; - _countInNode++; - return (T *)address; - } - void Delete(T *content) - { - content->~T(); - - *((T **)content) = _firstDeleted; - _firstDeleted = content; - } - void DeleteWithoutDestroying(T *content) - { - *((T **)content) = _firstDeleted; - _firstDeleted = content; - } - }; - - template - const size_t Pool::_itemSize = ((sizeof(T) + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *); - -} // namespace JinEngine - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_singleton.hpp b/src/libjin/common/je_singleton.hpp deleted file mode 100644 index 51dc9c5..0000000 --- a/src/libjin/common/je_singleton.hpp +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef __JE_SINGLETON_H__ -#define __JE_SINGLETON_H__ - -#include "je_object.h" -#include "je_exception.h" - -namespace JinEngine -{ - - /// - /// Singleton base class. - /// - template - class Singleton : public Object - { - public: - /// - /// Get singleton. - /// - /// @param Singleton instance of class. - /// - static T* get() - { - if (_instance == nullptr) - _instance = new T; - return _instance; - } - - /// - /// Destroy instance of singleton. - /// - static void destroy() - { - delete _instance; - _instance = nullptr; - } - - protected: - /// - /// Singleton constructor. - /// - Singleton() - { - // Check singleton. - if (_instance) - throw Exception("This is a singleton."); - }; - - /// - /// Singleton destructor. - /// - virtual ~Singleton() {}; - - /// - /// Singleton instance. - /// - static T* _instance; - - private: - /// - /// Singleton copy constructor. - /// - /// @param singleton Singleton of class. - /// - Singleton(const Singleton& singleton); - - /// - /// Singleton assignment. - /// - /// @param singleton Singleton of class. - /// - Singleton& operator = (const Singleton& singleton); - - }; - - /// - /// Singleton instance. - /// - template - T* Singleton::_instance = nullptr; - -} // namespace JinEngine - -#endif // __JE_SINGLETON_H__ \ No newline at end of file diff --git a/src/libjin/common/je_string.h b/src/libjin/common/je_string.h deleted file mode 100644 index 4e46f17..0000000 --- a/src/libjin/common/je_string.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef __JE_STRING_H__ -#define __JE_STRING_H__ - -#include - -namespace JinEngine -{ - - class String : public std::string - { - public: - inline String() - : std::string() - { - } - - inline String(const std::string& str) - : std::string(str) - { - } - - inline String(const String& str) - : std::string(str) - { - } - - inline String(const char* str) - : std::string(str) - { - } - - inline String& operator = (const String& str) - { - std::string::operator=(str); - return *this; - } - - inline operator const char* () const - { - return this->c_str(); - } - - inline const char* str() const - { - return this->c_str(); - } - - inline String(const String& s2, size_type pos2, size_type len2) - : std::string(s2, pos2, len2) - { - } - - inline String(const char* buf, size_type bufsize) - : std::string(buf, bufsize) - { - } - - inline String(size_type repetitions, char c) - : std::string(repetitions, c) - { - } - - inline int length() const - { - return size(); - } - - }; - -} - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_stringmap.hpp b/src/libjin/common/je_stringmap.hpp deleted file mode 100644 index b4cdccf..0000000 --- a/src/libjin/common/je_stringmap.hpp +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef __JE_COMMON_SREINGMAP_H__ -#define __JE_COMMON_SREINGMAP_H__ - -#include "je_object.h" - -namespace JinEngine -{ - - template - class StringMap : public Object - { - private: - - struct Record - { - const char * key; - T value; - bool set; - Record() : set(false) {} - }; - - const static unsigned MAX = SIZE * 2; - - Record records[MAX]; - const char * reverse[SIZE]; - - public: - - struct Entry - { - const char * key; - T value; - }; - - StringMap(Entry * entries, unsigned num) - { - - for (unsigned i = 0; i < SIZE; ++i) - reverse[i] = 0; - - unsigned n = num / sizeof(Entry); - - for (unsigned i = 0; i < n; ++i) - { - add(entries[i].key, entries[i].value); - } - } - - bool streq(const char * a, const char * b) - { - while (*a != 0 && *b != 0) - { - if (*a != *b) - return false; - ++a; - ++b; - } - - return (*a == 0 && *b == 0); - } - - bool find(const char * key, T & t) - { - //unsigned str_hash = djb2(key); - - for (unsigned i = 0; i < MAX; ++i) - { - //unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional? - - if (records[i].set && streq(records[i].key, key)) - { - t = records[i].value; - return true; - } - } - - return false; - } - - bool find(T key, const char *& str) - { - unsigned index = (unsigned)key; - - if (index >= SIZE) - return false; - - if (reverse[index] != 0) - { - str = reverse[index]; - return true; - } - else - { - return false; - } - } - - bool add(const char * key, T value) - { - unsigned str_hash = djb2(key); - bool inserted = false; - - for (unsigned i = 0; i < MAX; ++i) - { - unsigned str_i = (str_hash + i) % MAX; - - if (!records[str_i].set) - { - inserted = true; - records[str_i].set = true; - records[str_i].key = key; - records[str_i].value = value; - break; - } - } - - unsigned index = (unsigned)value; - - if (index >= SIZE) - { - printf("\nConstant %s out of bounds with %i!\n", key, index); - return false; - } - - reverse[index] = key; - - return inserted; - } - - unsigned djb2(const char * key) - { - unsigned hash = 5381; - int c; - - while ((c = *key++)) - hash = ((hash << 5) + hash) + c; - - return hash; - } - - }; // StringMap - -} // namespace JinEngine - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_subsystem.hpp b/src/libjin/common/je_subsystem.hpp deleted file mode 100644 index 8f682ef..0000000 --- a/src/libjin/common/je_subsystem.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef __JE_COMMON_SUBSYSTEM_H__ -#define __JE_COMMON_SUBSYSTEM_H__ - -#include "../utils/je_macros.h" - -#include "je_singleton.hpp" - -namespace JinEngine -{ - - /// - /// Subsystem class. - /// - template - class Subsystem : public Singleton - { - public: - /// - /// Subsystem setting. - /// - struct Setting - { - }; - - typedef Setting SettingBase; - - /// - /// Initialize subsystem. - /// - /// @param setting Subsystem setting. - /// @return True if initialize sucessful, otherwise return false. - /// - bool start(const SettingBase* setting = nullptr) - { - static bool success = startSystem(setting); - return success; - } - - /// - /// Quit subsystem. - /// - void quit() - { - // Call only once. - static char __dummy__ = (quitSystem(), 1); - Singleton::destroy(); - } - - /// - /// Subsystem constructor. - /// - Subsystem() {}; - - /// - /// Subsystem destructor. - /// - virtual ~Subsystem() {} - - protected: - /// - /// Initializer callback. - /// - virtual bool startSystem(const Setting* setting) = 0; - - /// - /// Quit subsystem callback. - /// - virtual void quitSystem() = 0; - - }; - -} // namespace JinEngine - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_temporary.h b/src/libjin/common/je_temporary.h deleted file mode 100644 index b89a601..0000000 --- a/src/libjin/common/je_temporary.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __JE_TEMPORARY_H__ -#define __JE_TEMPORARY_H__ - -#include "je_object.h" - -namespace JinEngine -{ - - /// - /// Class inherites this clound only be created on stack or static zone. - /// - class Temporary : public Object - { - public: - Temporary() {}; - virtual ~Temporary() {}; -/* - protected: - void operator delete(void* t) - { - if(t != nullptr) - free(t); - } -*/ - private: - // Disable new operands. - void* operator new(size_t); - - }; - -} // namespace JinEngine - -#endif \ No newline at end of file diff --git a/src/libjin/common/je_types.h b/src/libjin/common/je_types.h deleted file mode 100644 index e31ce5e..0000000 --- a/src/libjin/common/je_types.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __JE_TYPES_H__ -#define __JE_TYPES_H__ -#include -#include -#include - -namespace JinEngine -{ - - typedef int8_t int8; ///< Signed integer with a size of 8 bits. Supports values from -128 to 127 - typedef uint8_t uint8; ///< Unsigned integer with a size of 8 bits. Supports values from 0 to 255. - typedef uint8 byte; ///< Unsigned integer with 8 bits (1 byte). Supports 256 values from 0 to 255. - typedef int16_t int16; ///< Signed integer with a size of 16 bits. Supports values from -32768 to 32767 - typedef uint16_t uint16; ///< Unsigned integer with a size of 16 bits. Supports values from 0 to 65535. - typedef int32_t int32; ///< Signed integer with a size of 32 bits. Supports values from -2147483648 to 2147483647. - typedef uint32_t uint32; ///< Unsigned integer with a size of 32 bits. Supports values from 0 to 4294967295, (2^32 - 1). - typedef int64_t int64; ///< Signed integer with a size of 64 bits. Supports values from -(2^63) to (2^63 - 1). - typedef uint64_t uint64; ///< Unsigned integer with a size of 64 bits, Supports values from 0 to (2^64 - 1). - - typedef uint32_t uint; - typedef int32_t sint; - -#define Union(name, ...) \ -union _Ctor{ \ - _Ctor() { memset(this, 0, sizeof(*this)); } \ - __VA_ARGS__; \ -} name; - -#define Struct(name, ...) \ -struct {__VA_ARGS__;} name; - -} - -#endif \ No newline at end of file diff --git a/src/libjin/common/noncopyable.h b/src/libjin/common/noncopyable.h new file mode 100644 index 0000000..ddde7a1 --- /dev/null +++ b/src/libjin/common/noncopyable.h @@ -0,0 +1,26 @@ +#ifndef __JE_NONCOPYABLE_H__ +#define __JE_NONCOPYABLE_H__ + +#include "object.h" + +namespace JinEngine +{ + + /// + /// Class inherites this could not be copied. + /// + class Noncopyable : public Object + { + public: + Noncopyable(void) { } + virtual ~Noncopyable(void) { } + + private: + Noncopyable(const Noncopyable& other); + Noncopyable& operator=(const Noncopyable& other); + + }; + +} // namespace JinEngine + +#endif \ No newline at end of file diff --git a/src/libjin/common/object.h b/src/libjin/common/object.h new file mode 100644 index 0000000..581500f --- /dev/null +++ b/src/libjin/common/object.h @@ -0,0 +1,19 @@ +#ifndef __JE_OBJECT_H__ +#define __JE_OBJECT_H__ + +namespace JinEngine +{ + + /// + /// Base class of all classes in libjin. + /// + class Object + { + public: + virtual ~Object() {}; + + }; + +} // namespace JinEngine + +#endif \ No newline at end of file diff --git a/src/libjin/common/pool.hpp b/src/libjin/common/pool.hpp new file mode 100644 index 0000000..356ff87 --- /dev/null +++ b/src/libjin/common/pool.hpp @@ -0,0 +1,177 @@ +/// +/// An O(1) Object Pool. Original from https://www.codeproject.com/Articles/746630/O-Object-Pool-in-Cplusplus +/// +#ifndef __JE_POOL_H__ +#define __JE_POOL_H__ + +#include +#include + +#include "types.h" + +namespace JinEngine +{ + + class DefaultMemoryAllocator : public Object + { + public: + static inline void *Allocate(size_t size) + { + return ::operator new(size, ::std::nothrow); + } + static inline void Deallocate(void *pointer, size_t size) + { + ::operator delete(pointer); + } + }; + + template + class Pool : public Object + { + private: + struct _Node + { + void *_memory; + size_t _capacity; + _Node *_nextNode; + + _Node(size_t capacity) + { + if (capacity < 1) + throw std::invalid_argument("capacity must be at least 1."); + + _memory = TMemoryAllocator::Allocate(_itemSize * capacity); + if (_memory == NULL) + throw std::bad_alloc(); + + _capacity = capacity; + _nextNode = NULL; + } + ~_Node() + { + TMemoryAllocator::Deallocate(_memory, _itemSize * _capacity); + } + }; + + void *_nodeMemory; + T *_firstDeleted; + size_t _countInNode; + size_t _nodeCapacity; + _Node _firstNode; + _Node *_lastNode; + size_t _maxBlockLength; + + static const size_t _itemSize; + + Pool(const Pool &source); + void operator = (const Pool &source); + + void _AllocateNewNode() + { + size_t size = _countInNode; + if (size >= _maxBlockLength) + size = _maxBlockLength; + else + { + size *= 2; + + if (size < _countInNode) + throw std::overflow_error("size became too big."); + + if (size >= _maxBlockLength) + size = _maxBlockLength; + } + + _Node *newNode = new _Node(size); + _lastNode->_nextNode = newNode; + _lastNode = newNode; + _nodeMemory = newNode->_memory; + _countInNode = 0; + _nodeCapacity = size; + } + + public: + explicit Pool(size_t initialCapacity = 32, size_t maxBlockLength = 1000000) + : _firstDeleted(NULL) + , _countInNode(0) + , _nodeCapacity(initialCapacity) + , _firstNode(initialCapacity) + , _maxBlockLength(maxBlockLength) + { + if (maxBlockLength < 1) + throw std::invalid_argument("maxBlockLength must be at least 1."); + + _nodeMemory = _firstNode._memory; + _lastNode = &_firstNode; + } + ~Pool() + { + _Node *node = _firstNode._nextNode; + while (node) + { + _Node *nextNode = node->_nextNode; + delete node; + node = nextNode; + } + } + + T *New() + { + if (_firstDeleted) + { + T *result = _firstDeleted; + _firstDeleted = *((T **)_firstDeleted); + new(result) T(); + return result; + } + + if (_countInNode >= _nodeCapacity) + _AllocateNewNode(); + + char *address = (char *)_nodeMemory; + address += _countInNode * _itemSize; + T *result = new(address) T(); + _countInNode++; + return result; + } + + // This method is useful if you want to call a non-default constructor. + // It should be used like this: + // new (pool.GetNextWithoutInitializing()) ObjectType(... parameters ...); + T *GetNextWithoutInitializing() + { + if (_firstDeleted) + { + T *result = (T *)_firstDeleted; + _firstDeleted = *((T **)_firstDeleted); + return result; + } + + if (_countInNode >= _nodeCapacity) + _AllocateNewNode(); + + char *address = (char *)_nodeMemory; + address += _countInNode * _itemSize; + _countInNode++; + return (T *)address; + } + void Delete(T *content) + { + content->~T(); + + *((T **)content) = _firstDeleted; + _firstDeleted = content; + } + void DeleteWithoutDestroying(T *content) + { + *((T **)content) = _firstDeleted; + _firstDeleted = content; + } + }; + + template + const size_t Pool::_itemSize = ((sizeof(T) + sizeof(void *) - 1) / sizeof(void *)) * sizeof(void *); + +} // namespace JinEngine + +#endif \ No newline at end of file diff --git a/src/libjin/common/singleton.hpp b/src/libjin/common/singleton.hpp new file mode 100644 index 0000000..015c9b0 --- /dev/null +++ b/src/libjin/common/singleton.hpp @@ -0,0 +1,84 @@ +#ifndef __JE_SINGLETON_H__ +#define __JE_SINGLETON_H__ + +#include "object.h" +#include "exception.h" + +namespace JinEngine +{ + + /// + /// Singleton base class. + /// + template + class Singleton : public Object + { + public: + /// + /// Get singleton. + /// + /// @param Singleton instance of class. + /// + static T* get() + { + if (_instance == nullptr) + _instance = new T; + return _instance; + } + + /// + /// Destroy instance of singleton. + /// + static void destroy() + { + delete _instance; + _instance = nullptr; + } + + protected: + /// + /// Singleton constructor. + /// + Singleton() + { + // Check singleton. + if (_instance) + throw Exception("This is a singleton."); + }; + + /// + /// Singleton destructor. + /// + virtual ~Singleton() {}; + + /// + /// Singleton instance. + /// + static T* _instance; + + private: + /// + /// Singleton copy constructor. + /// + /// @param singleton Singleton of class. + /// + Singleton(const Singleton& singleton); + + /// + /// Singleton assignment. + /// + /// @param singleton Singleton of class. + /// + Singleton& operator = (const Singleton& singleton); + + }; + + /// + /// Singleton instance. + /// + template + T* Singleton::_instance = nullptr; + +} // namespace JinEngine + +#endif // __JE_SINGLETON_H__ \ No newline at end of file diff --git a/src/libjin/common/string.h b/src/libjin/common/string.h new file mode 100644 index 0000000..4e46f17 --- /dev/null +++ b/src/libjin/common/string.h @@ -0,0 +1,72 @@ +#ifndef __JE_STRING_H__ +#define __JE_STRING_H__ + +#include + +namespace JinEngine +{ + + class String : public std::string + { + public: + inline String() + : std::string() + { + } + + inline String(const std::string& str) + : std::string(str) + { + } + + inline String(const String& str) + : std::string(str) + { + } + + inline String(const char* str) + : std::string(str) + { + } + + inline String& operator = (const String& str) + { + std::string::operator=(str); + return *this; + } + + inline operator const char* () const + { + return this->c_str(); + } + + inline const char* str() const + { + return this->c_str(); + } + + inline String(const String& s2, size_type pos2, size_type len2) + : std::string(s2, pos2, len2) + { + } + + inline String(const char* buf, size_type bufsize) + : std::string(buf, bufsize) + { + } + + inline String(size_type repetitions, char c) + : std::string(repetitions, c) + { + } + + inline int length() const + { + return size(); + } + + }; + +} + +#endif \ No newline at end of file diff --git a/src/libjin/common/stringmap.hpp b/src/libjin/common/stringmap.hpp new file mode 100644 index 0000000..1db798e --- /dev/null +++ b/src/libjin/common/stringmap.hpp @@ -0,0 +1,145 @@ +#ifndef __JE_COMMON_SREINGMAP_H__ +#define __JE_COMMON_SREINGMAP_H__ + +#include "object.h" + +namespace JinEngine +{ + + template + class StringMap : public Object + { + private: + + struct Record + { + const char * key; + T value; + bool set; + Record() : set(false) {} + }; + + const static unsigned MAX = SIZE * 2; + + Record records[MAX]; + const char * reverse[SIZE]; + + public: + + struct Entry + { + const char * key; + T value; + }; + + StringMap(Entry * entries, unsigned num) + { + + for (unsigned i = 0; i < SIZE; ++i) + reverse[i] = 0; + + unsigned n = num / sizeof(Entry); + + for (unsigned i = 0; i < n; ++i) + { + add(entries[i].key, entries[i].value); + } + } + + bool streq(const char * a, const char * b) + { + while (*a != 0 && *b != 0) + { + if (*a != *b) + return false; + ++a; + ++b; + } + + return (*a == 0 && *b == 0); + } + + bool find(const char * key, T & t) + { + //unsigned str_hash = djb2(key); + + for (unsigned i = 0; i < MAX; ++i) + { + //unsigned str_i = (str_hash + i) % MAX; //this isn't used, is this intentional? + + if (records[i].set && streq(records[i].key, key)) + { + t = records[i].value; + return true; + } + } + + return false; + } + + bool find(T key, const char *& str) + { + unsigned index = (unsigned)key; + + if (index >= SIZE) + return false; + + if (reverse[index] != 0) + { + str = reverse[index]; + return true; + } + else + { + return false; + } + } + + bool add(const char * key, T value) + { + unsigned str_hash = djb2(key); + bool inserted = false; + + for (unsigned i = 0; i < MAX; ++i) + { + unsigned str_i = (str_hash + i) % MAX; + + if (!records[str_i].set) + { + inserted = true; + records[str_i].set = true; + records[str_i].key = key; + records[str_i].value = value; + break; + } + } + + unsigned index = (unsigned)value; + + if (index >= SIZE) + { + printf("\nConstant %s out of bounds with %i!\n", key, index); + return false; + } + + reverse[index] = key; + + return inserted; + } + + unsigned djb2(const char * key) + { + unsigned hash = 5381; + int c; + + while ((c = *key++)) + hash = ((hash << 5) + hash) + c; + + return hash; + } + + }; // StringMap + +} // namespace JinEngine + +#endif \ No newline at end of file diff --git a/src/libjin/common/subsystem.hpp b/src/libjin/common/subsystem.hpp new file mode 100644 index 0000000..9828c40 --- /dev/null +++ b/src/libjin/common/subsystem.hpp @@ -0,0 +1,74 @@ +#ifndef __JE_COMMON_SUBSYSTEM_H__ +#define __JE_COMMON_SUBSYSTEM_H__ + +#include "../utils/macros.h" + +#include "singleton.hpp" + +namespace JinEngine +{ + + /// + /// Subsystem class. + /// + template + class Subsystem : public Singleton + { + public: + /// + /// Subsystem setting. + /// + struct Setting + { + }; + + typedef Setting SettingBase; + + /// + /// Initialize subsystem. + /// + /// @param setting Subsystem setting. + /// @return True if initialize sucessful, otherwise return false. + /// + bool start(const SettingBase* setting = nullptr) + { + static bool success = startSystem(setting); + return success; + } + + /// + /// Quit subsystem. + /// + void quit() + { + // Call only once. + static char __dummy__ = (quitSystem(), 1); + Singleton::destroy(); + } + + /// + /// Subsystem constructor. + /// + Subsystem() {}; + + /// + /// Subsystem destructor. + /// + virtual ~Subsystem() {} + + protected: + /// + /// Initializer callback. + /// + virtual bool startSystem(const Setting* setting) = 0; + + /// + /// Quit subsystem callback. + /// + virtual void quitSystem() = 0; + + }; + +} // namespace JinEngine + +#endif \ No newline at end of file diff --git a/src/libjin/common/temporary.h b/src/libjin/common/temporary.h new file mode 100644 index 0000000..3f02b2b --- /dev/null +++ b/src/libjin/common/temporary.h @@ -0,0 +1,33 @@ +#ifndef __JE_TEMPORARY_H__ +#define __JE_TEMPORARY_H__ + +#include "object.h" + +namespace JinEngine +{ + + /// + /// Class inherites this clound only be created on stack or static zone. + /// + class Temporary : public Object + { + public: + Temporary() {}; + virtual ~Temporary() {}; +/* + protected: + void operator delete(void* t) + { + if(t != nullptr) + free(t); + } +*/ + private: + // Disable new operands. + void* operator new(size_t); + + }; + +} // namespace JinEngine + +#endif \ No newline at end of file diff --git a/src/libjin/common/types.h b/src/libjin/common/types.h new file mode 100644 index 0000000..e31ce5e --- /dev/null +++ b/src/libjin/common/types.h @@ -0,0 +1,34 @@ +#ifndef __JE_TYPES_H__ +#define __JE_TYPES_H__ +#include +#include +#include + +namespace JinEngine +{ + + typedef int8_t int8; ///< Signed integer with a size of 8 bits. Supports values from -128 to 127 + typedef uint8_t uint8; ///< Unsigned integer with a size of 8 bits. Supports values from 0 to 255. + typedef uint8 byte; ///< Unsigned integer with 8 bits (1 byte). Supports 256 values from 0 to 255. + typedef int16_t int16; ///< Signed integer with a size of 16 bits. Supports values from -32768 to 32767 + typedef uint16_t uint16; ///< Unsigned integer with a size of 16 bits. Supports values from 0 to 65535. + typedef int32_t int32; ///< Signed integer with a size of 32 bits. Supports values from -2147483648 to 2147483647. + typedef uint32_t uint32; ///< Unsigned integer with a size of 32 bits. Supports values from 0 to 4294967295, (2^32 - 1). + typedef int64_t int64; ///< Signed integer with a size of 64 bits. Supports values from -(2^63) to (2^63 - 1). + typedef uint64_t uint64; ///< Unsigned integer with a size of 64 bits, Supports values from 0 to (2^64 - 1). + + typedef uint32_t uint; + typedef int32_t sint; + +#define Union(name, ...) \ +union _Ctor{ \ + _Ctor() { memset(this, 0, sizeof(*this)); } \ + __VA_ARGS__; \ +} name; + +#define Struct(name, ...) \ +struct {__VA_ARGS__;} name; + +} + +#endif \ No newline at end of file -- cgit v1.1-26-g67d0