aboutsummaryrefslogtreecommitdiff
path: root/src/libjin/Common
diff options
context:
space:
mode:
Diffstat (limited to 'src/libjin/Common')
-rw-r--r--src/libjin/Common/je_array.hpp4
-rw-r--r--src/libjin/Common/je_common.h5
-rw-r--r--src/libjin/Common/je_exception.cpp46
-rw-r--r--src/libjin/Common/je_exception.h35
-rw-r--r--src/libjin/Common/je_noncopyable.h4
-rw-r--r--src/libjin/Common/je_object.h6
-rw-r--r--src/libjin/Common/je_pool.hpp172
-rw-r--r--src/libjin/Common/je_singleton.hpp6
-rw-r--r--src/libjin/Common/je_stringmap.hpp4
-rw-r--r--src/libjin/Common/je_subsystem.hpp4
-rw-r--r--src/libjin/Common/je_temporary.h4
-rw-r--r--src/libjin/Common/je_types.h4
-rw-r--r--src/libjin/Common/je_utf8.h6
13 files changed, 269 insertions, 31 deletions
diff --git a/src/libjin/Common/je_array.hpp b/src/libjin/Common/je_array.hpp
index 361f1f0..8a5cbf1 100644
--- a/src/libjin/Common/je_array.hpp
+++ b/src/libjin/Common/je_array.hpp
@@ -1,5 +1,5 @@
-#ifndef __JE_COMMON_ARRAY_H
-#define __JE_COMMON_ARRAY_H
+#ifndef __JE_COMMON_ARRAY_H__
+#define __JE_COMMON_ARRAY_H__
namespace JinEngine
{
diff --git a/src/libjin/Common/je_common.h b/src/libjin/Common/je_common.h
index 0dfa79a..31b67c6 100644
--- a/src/libjin/Common/je_common.h
+++ b/src/libjin/Common/je_common.h
@@ -1,6 +1,7 @@
-#ifndef __JE_COMMON_H
-#define __JE_COMMON_H
+#ifndef __JE_COMMON_H__
+#define __JE_COMMON_H__
+#include "je_exception.h"
#include "je_array.hpp"
#endif \ No newline at end of file
diff --git a/src/libjin/Common/je_exception.cpp b/src/libjin/Common/je_exception.cpp
index e69de29..5489a42 100644
--- a/src/libjin/Common/je_exception.cpp
+++ b/src/libjin/Common/je_exception.cpp
@@ -0,0 +1,46 @@
+#include <stdarg.h>
+
+#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
index 7c66af8..c319ebd 100644
--- a/src/libjin/Common/je_exception.h
+++ b/src/libjin/Common/je_exception.h
@@ -1,19 +1,42 @@
-#ifndef __JE_EXCEPTION_H
-#define __JE_EXCEPTION_H
+#ifndef __JE_EXCEPTION_H__
+#define __JE_EXCEPTION_H__
#include <exception>
+#include <string>
namespace JinEngine
{
///
- /// Built-in exception class.
+ /// Jin Exception.
///
- class JinException : public std::exception
+ class Exception : public std::exception
{
public:
- JinException();
- const char* what() const throw();
+
+ ///
+ /// 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;
};
diff --git a/src/libjin/Common/je_noncopyable.h b/src/libjin/Common/je_noncopyable.h
index 89a3e68..eff7121 100644
--- a/src/libjin/Common/je_noncopyable.h
+++ b/src/libjin/Common/je_noncopyable.h
@@ -1,5 +1,5 @@
-#ifndef __JE_NONCOPYABLE_H
-#define __JE_NONCOPYABLE_H
+#ifndef __JE_NONCOPYABLE_H__
+#define __JE_NONCOPYABLE_H__
namespace JinEngine
{
diff --git a/src/libjin/Common/je_object.h b/src/libjin/Common/je_object.h
index c256879..1afbf67 100644
--- a/src/libjin/Common/je_object.h
+++ b/src/libjin/Common/je_object.h
@@ -1,5 +1,5 @@
-#ifndef __JE_OBJECT_H
-#define __JE_OBJECT_H
+#ifndef __JE_OBJECT_H__
+#define __JE_OBJECT_H__
namespace JinEngine
{
@@ -9,6 +9,8 @@ namespace JinEngine
///
class Object
{
+ public:
+
};
} // namespace JinEngine
diff --git a/src/libjin/Common/je_pool.hpp b/src/libjin/Common/je_pool.hpp
index 1107fd5..cb96c5b 100644
--- a/src/libjin/Common/je_pool.hpp
+++ b/src/libjin/Common/je_pool.hpp
@@ -1,11 +1,177 @@
-#ifndef __JE_POOL_H
-#define __JE_POOL_H
+///
+/// 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 <stdlib.h>
+#include <iostream>
+
+#include "je_types.h"
namespace JinEngine
{
+ class DefaultMemoryAllocator
+ {
+ 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<typename T, class TMemoryAllocator = DefaultMemoryAllocator>
+ class Pool
+ {
+ 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<T, TMemoryAllocator> &source);
+ void operator = (const Pool<T, TMemoryAllocator> &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<typename T, class TMemoryAllocator>
+ const size_t Pool<T, TMemoryAllocator>::_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
index e981e7a..d7f52c9 100644
--- a/src/libjin/Common/je_singleton.hpp
+++ b/src/libjin/Common/je_singleton.hpp
@@ -1,5 +1,5 @@
-#ifndef __JE_SINGLETON_H
-#define __JE_SINGLETON_H
+#ifndef __JE_SINGLETON_H__
+#define __JE_SINGLETON_H__
namespace JinEngine
{
@@ -77,4 +77,4 @@ namespace JinEngine
} // namespace JinEngine
-#endif // __JE_SINGLETON_H \ No newline at end of file
+#endif // __JE_SINGLETON_H__
diff --git a/src/libjin/Common/je_stringmap.hpp b/src/libjin/Common/je_stringmap.hpp
index 43e3e9b..7a3bd80 100644
--- a/src/libjin/Common/je_stringmap.hpp
+++ b/src/libjin/Common/je_stringmap.hpp
@@ -1,5 +1,5 @@
-#ifndef __JE_COMMON_SREINGMAP_H
-#define __JE_COMMON_SREINGMAP_H
+#ifndef __JE_COMMON_SREINGMAP_H__
+#define __JE_COMMON_SREINGMAP_H__
namespace JinEngine
{
diff --git a/src/libjin/Common/je_subsystem.hpp b/src/libjin/Common/je_subsystem.hpp
index d8e106d..c015bef 100644
--- a/src/libjin/Common/je_subsystem.hpp
+++ b/src/libjin/Common/je_subsystem.hpp
@@ -1,5 +1,5 @@
-#ifndef __JE_COMMON_SUBSYSTEM_H
-#define __JE_COMMON_SUBSYSTEM_H
+#ifndef __JE_COMMON_SUBSYSTEM_H__
+#define __JE_COMMON_SUBSYSTEM_H__
#include "../utils/je_macros.h"
diff --git a/src/libjin/Common/je_temporary.h b/src/libjin/Common/je_temporary.h
index 5af8704..647bfba 100644
--- a/src/libjin/Common/je_temporary.h
+++ b/src/libjin/Common/je_temporary.h
@@ -1,5 +1,5 @@
-#ifndef __JE_ON_STACK_H
-#define __JE_ON_STACK_H
+#ifndef __JE_TEMPORARY_H__
+#define __JE_TEMPORARY_H__
namespace JinEngine
{
diff --git a/src/libjin/Common/je_types.h b/src/libjin/Common/je_types.h
index 446c413..448d7ac 100644
--- a/src/libjin/Common/je_types.h
+++ b/src/libjin/Common/je_types.h
@@ -1,5 +1,5 @@
-#ifndef __JE_TYPES_H
-#define __JE_TYPES_H
+#ifndef __JE_TYPES_H__
+#define __JE_TYPES_H__
#include <stdint.h>
namespace JinEngine
diff --git a/src/libjin/Common/je_utf8.h b/src/libjin/Common/je_utf8.h
index a11850c..d840b75 100644
--- a/src/libjin/Common/je_utf8.h
+++ b/src/libjin/Common/je_utf8.h
@@ -1,5 +1,5 @@
-#ifndef __JE_COMMON_UTF8_H
-#define __JE_COMMON_UTF8_H
+#ifndef __JE_COMMON_UTF8_H__
+#define __JE_COMMON_UTF8_H__
#include "../core/je_configuration.h"
#if jin_os == jin_os_windows
@@ -31,4 +31,4 @@ namespace JinEngine
#endif // jin_os == jin_os_windows
-#endif // __JE_COMMON_UTF8_H \ No newline at end of file
+#endif // __JE_COMMON_UTF8_H__