summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/3rdParty/Luax/lua.hpp6
-rw-r--r--Source/3rdParty/Luax/luax.h40
-rw-r--r--Source/3rdParty/Luax/luax_class.cpp50
-rw-r--r--Source/3rdParty/Luax/luax_class.h124
-rw-r--r--Source/3rdParty/Luax/luax_class.inl76
-rw-r--r--Source/3rdParty/Luax/luax_config.h47
-rw-r--r--Source/3rdParty/Luax/luax_ref.h27
-rw-r--r--Source/3rdParty/Luax/luax_state.cpp606
-rw-r--r--Source/3rdParty/Luax/luax_state.h166
-rw-r--r--Source/3rdParty/Luax/luax_state.inl110
-rw-r--r--Source/Asura.Engine/Application.cpp44
-rw-r--r--Source/Asura.Engine/Application.h28
-rw-r--r--Source/Asura.Engine/Asura.h5
-rw-r--r--Source/Asura.Engine/Audio/Sound.h12
-rw-r--r--Source/Asura.Engine/Audio/SoundDecoder.h2
-rw-r--r--Source/Asura.Engine/Config.h82
-rw-r--r--Source/Asura.Engine/Factory.h14
-rw-r--r--Source/Asura.Engine/FileSystem/DataBuffer.h12
-rw-r--r--Source/Asura.Engine/FileSystem/DecodedData.h8
-rw-r--r--Source/Asura.Engine/FileSystem/Reloadable.h11
-rw-r--r--Source/Asura.Engine/FileSystem/ResourceManager.h4
-rw-r--r--Source/Asura.Engine/Graphics/Application.Graphics.cpp3
-rw-r--r--Source/Asura.Engine/Graphics/Canvas.h45
-rw-r--r--Source/Asura.Engine/Graphics/Color.h14
-rw-r--r--Source/Asura.Engine/Graphics/Image.cpp15
-rw-r--r--Source/Asura.Engine/Graphics/Image.h29
-rw-r--r--Source/Asura.Engine/Graphics/ImageData.cpp4
-rw-r--r--Source/Asura.Engine/Graphics/ImageData.h34
-rw-r--r--Source/Asura.Engine/Graphics/ImageDecoder.h6
-rw-r--r--Source/Asura.Engine/Graphics/Mesh2D.h9
-rw-r--r--Source/Asura.Engine/Graphics/PNGDecoder.cpp4
-rw-r--r--Source/Asura.Engine/Graphics/PNGDecoder.h6
-rw-r--r--Source/Asura.Engine/Graphics/Port/Window.cpp11
-rw-r--r--Source/Asura.Engine/Graphics/Quad.cpp (renamed from Source/Asura.Engine/Font/Glyph.cpp)0
-rw-r--r--Source/Asura.Engine/Graphics/Quad.h1
-rw-r--r--Source/Asura.Engine/Graphics/RenderState.h4
-rw-r--r--Source/Asura.Engine/Graphics/RenderTarget.h4
-rw-r--r--Source/Asura.Engine/Graphics/STBDecoder.cpp26
-rw-r--r--Source/Asura.Engine/Graphics/STBDecoder.h6
-rw-r--r--Source/Asura.Engine/Graphics/Shader.h53
-rw-r--r--Source/Asura.Engine/Graphics/SpriteBatch.h6
-rw-r--r--Source/Asura.Engine/Graphics/Texture.h5
-rw-r--r--Source/Asura.Engine/Graphics/Window.cpp (renamed from Source/Asura.Engine/Window/Window.cpp)4
-rw-r--r--Source/Asura.Engine/Graphics/Window.h (renamed from Source/Asura.Engine/Window/Window.h)21
-rw-r--r--Source/Asura.Engine/Input/Clipboard.cpp (renamed from Source/Asura.Engine/Font/Glyph.h)0
-rw-r--r--Source/Asura.Engine/Input/Clipboard.h37
-rw-r--r--Source/Asura.Engine/Input/Cursor.cpp (renamed from Source/Asura.Engine/Font/TrueTypeFont.cpp)0
-rw-r--r--Source/Asura.Engine/Input/Cursor.defs25
-rw-r--r--Source/Asura.Engine/Input/Cursor.h54
-rw-r--r--Source/Asura.Engine/Input/InputDevice.hpp30
-rw-r--r--Source/Asura.Engine/Input/Keyboard.defs482
-rw-r--r--Source/Asura.Engine/Input/Keyboard.h73
-rw-r--r--Source/Asura.Engine/Input/Mouse.cpp (renamed from Source/Asura.Engine/Font/TrueTypeFont.h)0
-rw-r--r--Source/Asura.Engine/Input/Mouse.h56
-rw-r--r--Source/Asura.Engine/Math/Transform.h4
-rw-r--r--Source/Asura.Engine/Object.cpp27
-rw-r--r--Source/Asura.Engine/Object.h34
-rw-r--r--Source/Asura.Engine/Scripting/Luax.hpp2
-rw-r--r--Source/Asura.Engine/Scripting/Portable.cpp9
-rw-r--r--Source/Asura.Engine/Scripting/Portable.h13
-rw-r--r--Source/Asura.Engine/Scripting/Type.h17
-rw-r--r--Source/Asura.Engine/Singleton.hpp59
-rw-r--r--Source/Asura.Engine/StringMap.hpp4
-rw-r--r--Source/Asura.Engine/Text/Glyph.cpp0
-rw-r--r--Source/Asura.Engine/Text/Glyph.h0
-rw-r--r--Source/Asura.Engine/Text/String.cpp376
-rw-r--r--Source/Asura.Engine/Text/String.hpp594
-rw-r--r--Source/Asura.Engine/Text/String.inl29
-rw-r--r--Source/Asura.Engine/Text/TrueTypeFont.cpp0
-rw-r--r--Source/Asura.Engine/Text/TrueTypeFont.h0
-rw-r--r--Source/Asura.Engine/Text/Utf.hpp720
-rw-r--r--Source/Asura.Engine/Text/Utf.inl752
-rw-r--r--Source/Asura.Engine/Type.h13
-rw-r--r--Source/Asura.Framework/scripts/ai/state_graph.lua2
-rw-r--r--Source/Asura.Framework/scripts/audio/sound.lua2
-rw-r--r--Source/Asura.Framework/scripts/audio/source.lua2
-rw-r--r--Source/Asura.Framework/scripts/class.lua2
-rw-r--r--Source/Asura.Framework/scripts/component.lua2
-rw-r--r--Source/Asura.Framework/scripts/gameobject.lua4
-rw-r--r--Source/Asura.Framework/scripts/graphics/animation.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/animator.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/camera.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/canvas.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/image.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/material.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/mesh2d.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/mesh2d_renderer.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/particle_system.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/renderer.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/shader.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/shape.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/shape_renderer.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/sprite.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/sprite_batch_renderer.lua2
-rw-r--r--Source/Asura.Framework/scripts/graphics/sprite_renderer.lua2
-rw-r--r--Source/Asura.Framework/scripts/gui/button.lua2
-rw-r--r--Source/Asura.Framework/scripts/scene.lua3
-rw-r--r--Source/Asura.Runner/Runner.cpp10
-rw-r--r--Source/Asura.Runner/Runner.h1
-rw-r--r--Source/Asura.Runner/main.cpp12
-rw-r--r--Source/Samples/LuaxTest/header.h60
-rw-r--r--Source/Samples/LuaxTest/main.cpp190
102 files changed, 5164 insertions, 354 deletions
diff --git a/Source/3rdParty/Luax/lua.hpp b/Source/3rdParty/Luax/lua.hpp
index 2ad2293..ab14a19 100644
--- a/Source/3rdParty/Luax/lua.hpp
+++ b/Source/3rdParty/Luax/lua.hpp
@@ -4,8 +4,8 @@
// Include lua first
extern "C" {
-#include "lua.h"
-#include "lualib.h"
-#include "lauxlib.h"
+#include "lua51/lua.h"
+#include "lua51/lualib.h"
+#include "lua51/lauxlib.h"
}
#endif \ No newline at end of file
diff --git a/Source/3rdParty/Luax/luax.h b/Source/3rdParty/Luax/luax.h
index 68ff9f2..66162a4 100644
--- a/Source/3rdParty/Luax/luax.h
+++ b/Source/3rdParty/Luax/luax.h
@@ -1,11 +1,8 @@
#ifndef __LUAX_H__
#define __LUAX_H__
-extern "C" {
-#include "lua.h"
-#include "lualib.h"
-#include "lauxlib.h"
-}
+// moai-coreг
+
// include lua.hpp before this
#include "luax_runtime.h"
#include "luax_state.h"
@@ -17,5 +14,38 @@ extern "C" {
// * modules
// * class
// *
+/*
+
+GetClassName
+GetClass
+New
+Extend
+GetInterfaceTable
+
+
+
+__index
+__newIndex
+__gc
+__mode
+__tostring
+
+
+
+ݳԱҪʣֵ͵õֵͨʵ֣__indexΪԪ
+
+ƿռͨʵ
+
+ͨupvalueʵֵߵķʣҪͨselfͨBaseClass.Extend("SubClass")BaseClassֲͬbase class
+BaseClassΪExtendupvaluecfunctionͨlua_upvalueindexupvalue
+
+֮ͨ.úΪԪԪԸuserdatatableΪԪuserdataԵãʵϲҪ
+
+interface table -> member table
+member table -> ref table
+ref table -> userdata ˶ÿ͵úühLuaUserdataΪkey)Ϊdebug
+
+class table ͵ı壨NewExtendGetClassName
+*/
#endif \ No newline at end of file
diff --git a/Source/3rdParty/Luax/luax_class.cpp b/Source/3rdParty/Luax/luax_class.cpp
index e69de29..99da697 100644
--- a/Source/3rdParty/Luax/luax_class.cpp
+++ b/Source/3rdParty/Luax/luax_class.cpp
@@ -0,0 +1,50 @@
+#include "luax_state.h"
+#include "luax_class.h"
+
+namespace Luax
+{
+
+ LuaxClass::LuaxClass()
+ : mRefCount(1) // ʱĬһ
+ {
+ }
+
+ LuaxClass::~LuaxClass()
+ {
+ }
+
+ void LuaxClass::Retain()
+ {
+ ++mRefCount;
+ }
+
+ void LuaxClass::Release()
+ {
+ if (--mRefCount <= 0)
+ delete this;
+ }
+
+ bool LuaxClass::PushLuaUserdata(LuaxState& state)
+ {
+ return true;
+ }
+
+ void LuaxClass::BindToLua(LuaxState& state)
+ {
+ assert(!mUserdata);
+
+ }
+
+ //--------------------------------------------------------------------------------------------------------------
+
+ ///
+ /// ͷŹʵ
+ ///
+ int LuaxClass::l_GC(lua_State* L)
+ {
+ LUAX_SETUP(L, "U");
+
+ return 0;
+ }
+
+} \ No newline at end of file
diff --git a/Source/3rdParty/Luax/luax_class.h b/Source/3rdParty/Luax/luax_class.h
index 1721ec4..d241030 100644
--- a/Source/3rdParty/Luax/luax_class.h
+++ b/Source/3rdParty/Luax/luax_class.h
@@ -3,50 +3,110 @@
#include <vector>
+#include "lua.hpp"
+#include "luax_config.h"
+#include "luax_state.h"
+
namespace Luax
{
-#define LUAX_DECL_METHOD(MTD) static int MTD(lua_State*)
-#define LUAX_DECL_FACTORY(CLS) static int RegisterLuaClass(lua_State*);
-#define LUAX_DECL_SINGLETON(CLS)
+#define LUAX_DECL_METHOD(mtd) static int mtd(lua_State*)
+
+ ///
+ /// RegisterLuaxClass עķͳԱö١ȵclass table
+ /// LuaxRegisterInterface עӿڷinterface table
+ /// LuaxGetFactoryName ùͬʱעʱעΪsingletonͨʱ
+ ///
+#define LUAX_DECL_FACTORY(type) \
+ static void RegisterLuaxClass(LuaxState&);\
+ static void RegisterLuaxInterface(LuaxState&);\
+ static const char* GetLuaxFactoryName() { return #type; };\
+ static const char* GetLuaxClassName() { return #type; };\
+ static bool IsLuaxClassSingleton() { return false; };
+
+
+ ///
+ /// RegisterLuaxClass עķͳԱö١ȵclass table
+ /// LuaxGetSingletonName õ
+ ///
+#define LUAX_DECL_SINGLETON(type) \
+ static void RegisterLuaxClass(LuaxState&); \
+ static const char* GetLuaxSingletonName() { return #type; }; \
+ static const char* GetLuaxClassName() { return #type; }; \
+ static bool IsLuaxClassSingleton() { return true; };
+
+
+ ///
+ /// Ҫ¶luaclassҪ̳дࡣͨluaʵҪȷüȷԣڶ߳Ҫȷͷš
+ ///
+ class LuaxClass
+ {
+ public:
+
+ void Retain();
+ void Release();
+
+ //------------------------------------------------------------------------------------------------------------
+ //
+
+ template<class T>
+ static void RegisterLuaxClass(LuaxState& state);
+
+ template<class T>
+ LUAX_DECL_METHOD(l_GetClassName);
+
+ //------------------------------------------------------------------------------------------------------------
+ //
+
+ template<class T>
+ static void RegisterLuaxFactoryClass(LuaxState& state);
+
+ template<class T>
+ static void RegisterLuaxInterface(LuaxState& state);
+
+ LUAX_DECL_METHOD(l_GC);
+
+ //------------------------------------------------------------------------------------------------------------
+ //
+
+ template<class T>
+ static void RegisterLuaxSingletonClass(LuaxState& state);
+
+ protected:
+
+ LuaxClass();
+ ~LuaxClass();
-#define LUAX_REGISTER_CLASS(CLS) CLS::RegisterLuaType()
- /*
- ///
- /// Ҫ¶luaclassҪ̳дࡣ
- ///
- class LuaxClass
- {
- public:
+ ///
+ /// userdata pushջûгʼmUserdataʼúԪѳʼõuserdataջ
+ ///
+ bool PushLuaUserdata(LuaxState& state);
- static void RegisterLuaType();
+ private:
- static void RegisterLuaFuncs();
+ ///
+ /// ȡַҪַֻͨڶϴʵõջϺ;̬ıȡַ֤ü׼ȷ
+ /// ҪãʹôݶǴݵַ
+ ///
+ void* operator &();
- private:
-
- };
+ void BindToLua(LuaxState& state);
- ///
- /// ҪΪuserdata̳дࡣΪ࣬ͨLUAX_DECL_FACTORY(CLS)ָ
- ///
- class LuaxFactory : public LuaxClass
- {
-
+ int mRefCount;
- };
+ void* mUserdata;
+
+ };
- ///
- /// עluaĵ̳дࡣ
- ///
- class LuaxSingleton : public LuaxClass
- {
- public:
+ ///
+ /// ڳԱﴴLuaxStateԲм顣
+ ///
+#define LUAX_SETUP(L, params) \
+ LuaxState state(L);\
+ if(!state.CheckParams(1, params)) return 0;
- private:
+#include "luax_class.inl"
- };
- */
}
#endif \ No newline at end of file
diff --git a/Source/3rdParty/Luax/luax_class.inl b/Source/3rdParty/Luax/luax_class.inl
new file mode 100644
index 0000000..23d4c28
--- /dev/null
+++ b/Source/3rdParty/Luax/luax_class.inl
@@ -0,0 +1,76 @@
+
+//----------------------------------------------------------------------------------------------------------------
+// ӿ
+
+///
+/// ԲͬͣͨGetLuaClassName
+///
+template<class T>
+int LuaxClass::l_GetClassName(lua_State* L)
+{
+ LUAX_SETUP(L, "*");
+
+ cc8* type = T::GetLuaxClassName();
+ state.Push(type);
+ return 1;
+}
+
+//----------------------------------------------------------------------------------------------------------------
+
+///
+/// עṤ͵еԱ
+///
+template<class T>
+void LuaxClass::RegisterLuaxClass(LuaxState& state)
+{
+ luaL_Reg regTable[] = {
+ { "GetClassName", l_GetClassName<T> },
+ { NULL, NULL }
+ };
+
+ state.Register(regTable);
+}
+
+
+///
+/// ijԱעclass table
+///
+template<class T>
+void LuaxClass::RegisterLuaxFactoryClass(LuaxState& state)
+{
+ luaL_Reg regTable[] = {
+ { "Extend", l_ExtendFactory },
+ { NULL, NULL }
+ };
+
+ state.Register(regTable);
+}
+
+
+///
+/// ʵijԱעinterface table
+///
+template<class T>
+void LuaxClass::RegisterLuaxInterface(LuaxState& state)
+{
+ luaL_Reg regTable[] = {
+ { "__gc", l_GC },
+ { NULL, NULL }
+ };
+
+ state.Register(regTable);
+}
+
+
+///
+/// ijԱעclass table
+///
+template<class T>
+void LuaxClass::RegisterLuaxSingletonClass(LuaxState& state)
+{
+ luaL_Reg regTable[] = {
+ {NULL, NULL}
+ };
+
+ state.Register(regTable);
+} \ No newline at end of file
diff --git a/Source/3rdParty/Luax/luax_config.h b/Source/3rdParty/Luax/luax_config.h
new file mode 100644
index 0000000..a33750f
--- /dev/null
+++ b/Source/3rdParty/Luax/luax_config.h
@@ -0,0 +1,47 @@
+#ifndef __LUAX_TYPE_H__
+#define __LUAX_TYPE_H__
+
+#include <assert.h>
+
+namespace Luax
+{
+
+ typedef unsigned int uint;
+ typedef unsigned long uintptr;
+ typedef long sintptr;
+
+ typedef const char cc8;
+
+ typedef unsigned char u8;
+ typedef unsigned short u16;
+ typedef unsigned int u32;
+ typedef unsigned long long u64;
+
+ typedef signed char s8;
+ typedef signed short s16;
+ typedef signed int s32;
+ typedef signed long long s64;
+
+#ifdef _WIN32
+ #define LUAX_FINAL final
+ #define LUAX_LIBRARY_EXPORT __declspec(dllexport)
+ #define LUAX_LIBRARY_IMPORT __declspec(dllimport)
+ #define LUAX_FORCE_INLINE __forceinline
+ #define LUAX_RESTRICT __restrict
+ #define LUAX_ATTRIBUTE_USED
+ #define LUAX_ABSTRACT
+ #define LUAX_API LUAX_LIBRARY_EXPORT
+#else
+ #define LUAX_FINAL final
+ #define LUAX_LIBRARY_EXPORT __attribute__((visibility("default")))
+ #define LUAX_LIBRARY_IMPORT
+ #define LUAX_FORCE_INLINE __attribute__((always_inline)) inline
+ #define LUAX_RESTRICT __restrict__
+ #define LUAX_ATTRIBUTE_USED __attribute__((used))
+ #define LUAX_ABSTRACT
+ #define LUAX_API LUAX_LIBRARY_EXPORT
+#endif
+
+}
+
+#endif \ No newline at end of file
diff --git a/Source/3rdParty/Luax/luax_ref.h b/Source/3rdParty/Luax/luax_ref.h
index e69de29..122c448 100644
--- a/Source/3rdParty/Luax/luax_ref.h
+++ b/Source/3rdParty/Luax/luax_ref.h
@@ -0,0 +1,27 @@
+#ifndef __LUAX_REF_H__
+#define __LUAX_REF_H__
+
+namespace Luax
+{
+
+ ///
+ /// Lua referenceLUA_REGISTRYINDEXĴ档
+ ///
+ class LuaxRef
+ {
+
+ };
+
+ class LuaxStrongRef: public LuaxRef
+ {
+
+ };
+
+ class LuaxWeakRef : public LuaxRef
+ {
+
+ };
+
+}
+
+#endif \ No newline at end of file
diff --git a/Source/3rdParty/Luax/luax_state.cpp b/Source/3rdParty/Luax/luax_state.cpp
index 3fc1645..a92d697 100644
--- a/Source/3rdParty/Luax/luax_state.cpp
+++ b/Source/3rdParty/Luax/luax_state.cpp
@@ -1,8 +1,612 @@
-//#include "luax_state.h"
+#include "luax_state.h"
namespace Luax
{
+
+#define L mState
+ LuaxState::LuaxState(lua_State* state)
+ : L(state)
+ {
+ assert(state);
+ }
+ LuaxState::~LuaxState()
+ {
+ }
+
+ LuaxState::operator lua_State*()
+ {
+ return L;
+ };
+
+ LuaxState::operator bool()
+ {
+ return L != nullptr;
+ }
+
+ lua_State* LuaxState::operator ->()
+ {
+ return L;
+ }
+
+ lua_State& LuaxState::operator*()
+ {
+ return *L;
+ }
+
+ void LuaxState::OpenLibs()
+ {
+ luaL_openlibs(L);
+ }
+
+ void LuaxState::PushNamespace(cc8* name)
+ {
+ bool isG = !lua_istable(L, -1);
+ int idx = isG ? LUA_GLOBALSINDEX : -1;
+ lua_getfield(L, idx, name);
+ if (lua_isnil(L, -1))
+ {
+ lua_pop(L, 1);
+ lua_newtable(L);
+ assert(lua_istable(L, -1));
+ lua_pushvalue(L, -1);
+ int t = isG ? LUA_GLOBALSINDEX : -3;
+ lua_setfield(L, t, name);
+ }
+
+ // stack:
+ // -1 namespace
+ }
+
+ void LuaxState::PopNamespace()
+ {
+ assert(lua_istable(L, -1));
+ lua_pop(L, 1);
+ }
+
+ void LuaxState::DoString(const std::string& code)
+ {
+ luaL_dostring(L, code.c_str());
+ }
+
+ int LuaxState::AbsIndex(int idx)
+ {
+ if (idx < 0) {
+ return lua_gettop(L) + idx + 1;
+ }
+ return idx;
+ }
+
+ int LuaxState::Call(int nArgs, int nResults)
+ {
+ return 0;
+ }
+
+ void LuaxState::Push()
+ {
+ lua_pushnil(L);
+ }
+
+ void LuaxState::Push(bool value)
+ {
+ lua_pushboolean(L, value ? 1 : 0);
+ }
+
+ void LuaxState::Push(cc8* value)
+ {
+ lua_pushstring(L, value);
+ }
+
+ void LuaxState::Push(double value)
+ {
+ lua_pushnumber(L, value);
+ }
+
+ void LuaxState::Push(float value)
+ {
+ lua_pushnumber(L, value);
+ }
+
+ void LuaxState::Push(int value)
+ {
+ lua_pushnumber(L, value);
+ }
+
+ void LuaxState::Push(u16 value)
+ {
+ lua_pushnumber(L, value);
+ }
+
+ void LuaxState::Push(u32 value)
+ {
+ lua_pushnumber(L, value);
+ }
+
+ void LuaxState::Push(u64 value)
+ {
+ lua_pushnumber(L, (double)value);
+ }
+
+ void LuaxState::Push(uintptr value)
+ {
+ lua_pushlightuserdata(L, (void*)value);
+ }
+
+ void LuaxState::Push(lua_CFunction value)
+ {
+ lua_pushcfunction(L, value);
+ }
+
+ void LuaxState::Push(void* data, size_t size)
+ {
+ lua_pushlstring(L, (cc8*)data, size);
+ }
+
+ void LuaxState::Push(const void* value)
+ {
+ lua_pushlightuserdata(L, (void*)value);
+ }
+
+ void LuaxState::Pop(int n /* = 1 */)
+ {
+ lua_pop(L, n);
+ }
+
+ bool LuaxState::IsNil(int idx)
+ {
+ return lua_isnil(L, idx);
+ }
+
+ bool LuaxState::IsNilOrNone(int idx)
+ {
+ int t = lua_type(L, idx);
+ return ((t == LUA_TNONE) || (t == LUA_TNIL));
+ }
+
+ bool LuaxState::IsTableOrUserdata(int idx)
+ {
+ int check = lua_type(L, idx);
+ return ((check == LUA_TTABLE) || (check == LUA_TUSERDATA));
+ }
+
+ bool LuaxState::IsTrueOrNotNil(int idx)
+ {
+ if (lua_isboolean(L, idx)) {
+ return lua_toboolean(L, idx) ? true : false;
+ }
+ return !lua_isnil(L, idx);
+ }
+
+ bool LuaxState::IsType(int idx, int type)
+ {
+ return (lua_type(L, idx) == type);
+ }
+
+ bool LuaxState::IsType(int idx, cc8* name, int type)
+ {
+ return this->HasField(idx, name, type);
+ }
+
+ bool LuaxState::IsValid()
+ {
+ return (L != 0);
+ }
+
+ int LuaxState::GetTop()
+ {
+ return lua_gettop(mState);
+ }
+
+ bool LuaxState::HasField(int idx, cc8* name) {
+
+ lua_getfield(L, idx, name);
+ bool hasField = (lua_isnil(L, -1) == false);
+ lua_pop(L, 1);
+
+ return hasField;
+ }
+
+ bool LuaxState::HasField(int idx, int key) {
+
+ this->GetField(idx, key);
+ bool hasField = (lua_isnil(L, -1) == false);
+ lua_pop(L, 1);
+
+ return hasField;
+ }
+
+ bool LuaxState::HasField(int idx, cc8* name, int type) {
+
+ lua_getfield(L, idx, name);
+ bool hasField = (lua_type(L, -1) == type);
+ lua_pop(L, 1);
+
+ return hasField;
+ }
+
+ bool LuaxState::HasField(int idx, int key, int type) {
+
+ this->GetField(idx, key);
+ bool hasField = (lua_type(L, -1) == type);
+ lua_pop(L, 1);
+
+ return hasField;
+ }
+
+ bool LuaxState::HasKeys(int idx) {
+
+ idx = this->AbsIndex(idx);
+
+ lua_pushnil(L); /* first key */
+ if (lua_next(L, idx) != 0) {
+ lua_pop(L, 2);
+ return true;
+ }
+ return false;
+ }
+
+ void LuaxState::Register(const luaL_Reg *l)
+ {
+ luaL_register(L, 0, l);
+ }
+
+ void LuaxState::GetField(int idx, cc8* name)
+ {
+ lua_getfield(L, idx, name);
+ }
+
+ void LuaxState::GetField(int idx, int key)
+ {
+ idx = this->AbsIndex(idx);
+
+ lua_pushinteger(L, key);
+ lua_gettable(L, idx);
+ }
+
+ std::string LuaxState::GetField(int idx, cc8* key, cc8* value)
+ {
+ std::string str;
+ if (this->GetFieldWithType(idx, key, LUA_TSTRING)) {
+ str = lua_tostring(L, -1);
+ lua_pop(L, 1);
+ }
+ else {
+ str = value;
+ }
+ return str;
+ }
+
+ std::string LuaxState::GetField(int idx, int key, cc8* value)
+ {
+ std::string str;
+ if (this->GetFieldWithType(idx, key, LUA_TSTRING)) {
+ str = lua_tostring(L, -1);
+ lua_pop(L, 1);
+ }
+ else {
+ str = value;
+ }
+ return str;
+ }
+
+ std::string LuaxState::GetField(int idx, cc8* key, const std::string& value)
+ {
+ std::string str;
+ if (this->GetFieldWithType(idx, key, LUA_TSTRING)) {
+ str = lua_tostring(L, -1);
+ lua_pop(L, 1);
+ }
+ else {
+ str = value;
+ }
+ return str;
+ }
+
+ std::string LuaxState::GetField(int idx, int key, const std::string& value)
+ {
+ std::string str;
+ if (this->GetFieldWithType(idx, key, LUA_TSTRING)) {
+ str = lua_tostring(L, -1);
+ lua_pop(L, 1);
+ }
+ else {
+ str = value;
+ }
+ return str;
+ }
+
+ bool LuaxState::GetFieldWithType(int idx, cc8* name, int type)
+ {
+ lua_getfield(L, idx, name);
+ if (lua_type(L, -1) != type) {
+ lua_pop(L, 1);
+ return false;
+ }
+ return true;
+ }
+
+ bool LuaxState::GetFieldWithType(int idx, int key, int type)
+ {
+ this->GetField(idx, key);
+ if (lua_type(L, -1) != type) {
+ lua_pop(L, 1);
+ return false;
+ }
+ return true;
+ }
+
+ void LuaxState::SetField(int idx, cc8* key)
+ {
+ if (IsTableOrUserdata(idx))
+ {
+ idx = AbsIndex(idx);
+ lua_setfield(L, idx, key);
+ }
+ }
+
+ cc8* LuaxState::GetLuaTypeName(int type)
+ {
+ switch (type) {
+ case LUA_TNONE: return "none";
+ case LUA_TNIL: return "nil";
+ case LUA_TBOOLEAN: return "boolean";
+ case LUA_TLIGHTUSERDATA: return "lightuserdata";
+ case LUA_TNUMBER: return "number";
+ case LUA_TSTRING: return "string";
+ case LUA_TTABLE: return "table";
+ case LUA_TFUNCTION: return "function";
+ case LUA_TUSERDATA: return "userdata";
+ case LUA_TTHREAD: return "thread";
+ }
+ return "unknown";
+ }
+
+
+ bool LuaxState::GetSubfieldWithType(int idx, cc8* format, int type, ...)
+ {
+ va_list args;
+ va_start(args, type);
+
+ idx = this->AbsIndex(idx);
+ lua_pushvalue(this->mState, idx);
+
+ for (cc8* c = format; *c; ++c) {
+ switch (*c) {
+ // number
+ case 'N':
+ lua_pushnumber(this->mState, va_arg(args, int));
+ lua_gettable(this->mState, -1);
+ break;
+
+ // string
+ case 'S':
+ lua_getfield(this->mState, -1, va_arg(args, char*));
+ break;
+
+ default:
+ lua_pushnil(this->mState);
+ }
+
+ if (lua_isnil(this->mState, -1)) break;
+ lua_replace(this->mState, -2);
+ }
+ va_end(args);
+ if (lua_type(this->mState, -1) != type) {
+ lua_pop(this->mState, 1);
+ return false;
+ }
+ return true;
+ }
+
+ bool LuaxState::CheckParams(int idx, cc8* format)
+ {
+ idx = AbsIndex(idx);
+
+ for (int i = 0; format[i]; ++i) {
+
+ int pos = idx + i;
+ int type = LUA_TNIL;
+ int expected = LUA_TNONE;
+
+ if (pos <= GetTop()) {
+ type = lua_type(mState, pos);
+ }
+
+ switch (format[i]) {
+
+ // boolean
+ case 'B':
+ if (type != LUA_TBOOLEAN) expected = LUA_TBOOLEAN;
+ break;
+
+ // coroutine
+ case 'C':
+ if (type != LUA_TTHREAD) expected = LUA_TTHREAD;
+ break;
+
+ // function
+ case 'F':
+ if (type != LUA_TFUNCTION) expected = LUA_TFUNCTION;
+ break;
+
+ // light userdata
+ case 'L':
+ if (type != LUA_TLIGHTUSERDATA) expected = LUA_TLIGHTUSERDATA;
+ break;
+
+ // number
+ case 'N':
+ if (type != LUA_TNUMBER) expected = LUA_TNUMBER;
+ break;
+
+ // string
+ case 'S':
+ if (type != LUA_TSTRING) expected = LUA_TSTRING;
+ break;
+
+ // table
+ case 'T':
+ if (type != LUA_TTABLE) expected = LUA_TTABLE;
+ break;
+
+ // userdata
+ case 'U':
+ if (type != LUA_TUSERDATA) expected = LUA_TUSERDATA;
+ break;
+
+ // any type
+ case '*':
+ case '.':
+ break;
+ }
+
+ if (expected != LUA_TNONE) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ template <>
+ bool LuaxState::GetValue < bool >(int idx, const bool value) {
+
+ if (this->IsType(idx, LUA_TBOOLEAN)) {
+ return (lua_toboolean(this->mState, idx) != 0);
+ }
+ return value;
+ }
+
+
+ template <>
+ cc8* LuaxState::GetValue < cc8* >(int idx, const cc8* value) {
+
+ if (this->IsType(idx, LUA_TSTRING)) {
+ return lua_tostring(this->mState, idx);
+ }
+ return value;
+ }
+
+ template <>
+ std::string LuaxState::GetValue<std::string>(int idx, const std::string value)
+ {
+ std::string str;
+ if (lua_type(this->mState, idx) == LUA_TSTRING) {
+ str = lua_tostring(this->mState, idx);
+ }
+ else {
+ str = value;
+ }
+ return str;
+ }
+
+ template <>
+ double LuaxState::GetValue < double >(int idx, const double value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+ template <>
+ float LuaxState::GetValue < float >(int idx, const float value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return (float)lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+ template <>
+ s8 LuaxState::GetValue < s8 >(int idx, const s8 value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return (s8)lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+
+ template <>
+ s16 LuaxState::GetValue < s16 >(int idx, const s16 value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return (s16)lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+
+ template <>
+ s32 LuaxState::GetValue < s32 >(int idx, const s32 value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return (s32)lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+ template <>
+ s64 LuaxState::GetValue < s64 >(int idx, const s64 value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return (s64)lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+ template <>
+ u8 LuaxState::GetValue < u8 >(int idx, const u8 value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return (u8)lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+ template <>
+ u16 LuaxState::GetValue < u16 >(int idx, const u16 value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return (u16)lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+ template <>
+ u32 LuaxState::GetValue < u32 >(int idx, const u32 value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return (u32)lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+ template <>
+ u64 LuaxState::GetValue < u64 >(int idx, const u64 value)
+ {
+ if (this->IsType(idx, LUA_TNUMBER)) {
+ return (u64)lua_tonumber(this->mState, idx);
+ }
+ return value;
+ }
+
+ template <>
+ const void* LuaxState::GetValue < const void* >(int idx, const void* value)
+ {
+ if (this->IsType(idx, LUA_TLIGHTUSERDATA)) {
+ return (void*)lua_touserdata(this->mState, idx);
+ }
+ return value;
+ }
+
+ void LuaxState::PushPtrUserData(void* ptr) {
+
+ void** handle = (void**)lua_newuserdata(this->mState, sizeof(void*));
+ assert(handle);
+ (*handle) = ptr;
+ }
} \ No newline at end of file
diff --git a/Source/3rdParty/Luax/luax_state.h b/Source/3rdParty/Luax/luax_state.h
index 7b6338f..52b8f38 100644
--- a/Source/3rdParty/Luax/luax_state.h
+++ b/Source/3rdParty/Luax/luax_state.h
@@ -1,26 +1,166 @@
#ifndef __LUAX_STATE_H__
#define __LUAX_STATE_H__
+#include <string>
+
+#include "lua.hpp"
+#include "luax_config.h"
+
namespace Luax
{
- class LuaxState
- {
- public:
- LuaxState(lua_State* state) : mState(state){};
- ~LuaxState() {};
+ class LuaxClass;
+
+ ///
+ /// lua_StateĴ˱һlua_Stateòݡһʵmetatable£
+ /// interface table
+ /// member table
+ /// ref table
+ /// userdata
+ /// userdataͨgetmetatableȡϼmetatable֮⻹һclass tableעڶӦƿռ
+ ///
+ LUAX_API class LuaxState
+ {
+ public:
+
+ LuaxState(lua_State* state);
+ ~LuaxState();
+
+ operator lua_State*();
+ operator bool();
+ lua_State* operator ->();
+ lua_State& operator *();
+
+ //------------------------------------------------------------------------------------------------------------
+
+ void OpenLibs();
+
+ //------------------------------------------------------------------------------------------------------------
+ // ƿռƿռһ_Gı
+
+ void PushNamespace(cc8* name);
+ void PopNamespace();
+
+ //------------------------------------------------------------------------------------------------------------
+
+ int GetTop();
+ bool CheckParams(int idx, cc8* format);
+ int AbsIndex(int idx);
+ int Call(int nArgs, int nResults);
+
+ //------------------------------------------------------------------------------------------------------------
+
+ ///
+ /// עCעһ{0 0}
+ ///
+ void Register(const luaL_Reg *l);
+
+ void GetField(int idx, cc8* name);
+ void GetField(int idx, int key);
+ std::string GetField(int idx, cc8* key, cc8* value);
+ std::string GetField(int idx, int key, cc8* value);
+ std::string GetField(int idx, cc8* key, const std::string& value);
+ std::string GetField(int idx, int key, const std::string& value);
+ bool GetFieldWithType(int idx, cc8* name, int type);
+ bool GetFieldWithType(int idx, int key, int type);
+ bool GetSubfieldWithType(int idx, cc8* format, int type, ...);
+ static cc8* GetLuaTypeName(int type);
+
+ void SetField(int idx, cc8* key);
+
+ bool IsNil(int idx);
+ bool IsNilOrNone(int idx);
+ bool IsTableOrUserdata(int idx);
+ bool IsTrueOrNotNil(int idx);
+ bool IsType(int idx, int type);
+ bool IsType(int idx, cc8* name, int type);
+ bool IsValid();
+
+ bool HasField(int idx, cc8* name);
+ bool HasField(int idx, int key);
+ bool HasField(int idx, cc8* name, int type);
+ bool HasField(int idx, int name, int type);
+ bool HasKeys(int idx);
+
+ void Push();
+ void Push(bool value);
+ void Push(cc8* value);
+ void Push(double value);
+ void Push(float value);
+ void Push(int value);
+ void Push(u16 value);
+ void Push(u32 value);
+ void Push(u64 value);
+ void Push(uintptr value);
+ void Push(lua_CFunction value);
+ void Push(void* data, size_t size);
+ void Push(const void* value);
+
+ ///
+ /// void** ʽuserdataֵΪptr
+ ///
+ void PushPtrUserData(void* ptr);
+
+ void Pop(int n = 1);
+
+ //------------------------------------------------------------------------------------------------------------
+
+ template<typename T> T GetValue(int idx, T default_value);
+ template<typename T> T GetField(int idx, int key, T value);
+ template<typename T> T GetField(int idx, cc8* key, T value);
+ template<typename T> void SetField(int idx, cc8* key, T value);
+ template<typename T> void SetFieldByIndex(int idx, int key, T value);
+
+ //------------------------------------------------------------------------------------------------------------
+
+ void DoString(const std::string& code);
+ void DoFile(const std::string& file);
+
+ //------------------------------------------------------------------------------------------------------------
+
+ ///
+ /// עṤͨ࣬New
+ ///
+ template<typename T>
+ void RegisterFactory();
+
+ ///
+ /// עᵥûNew
+ ///
+ template<typename T>
+ void RegisterSingleton();
+
+ private:
+
+ ///
+ /// ζLuaxStateĵַز
+ ///
+ void* operator &();
+ void* operator new(size_t size);
+
+ lua_State* const mState;
- inline operator lua_State*() { return mState; };
- operator bool();
- inline lua_State* operator ->() { return mState; };
- inline lua_State& operator *() { return *mState; };
+ };
- private:
- void* operator new(size_t size);
+#include "luax_state.inl"
- lua_State* mState;
+ //--------------------------------------------------------------------------------------------------------------
+ // GetValue()ģػ
- };
+ template <> bool LuaxState::GetValue < bool >(int idx, const bool value);
+ template <> cc8* LuaxState::GetValue < cc8* >(int idx, const cc8* value);
+ template <> double LuaxState::GetValue < double >(int idx, const double value);
+ template <> float LuaxState::GetValue < float >(int idx, const float value);
+ template <> s8 LuaxState::GetValue < s8 >(int idx, const s8 value);
+ template <> s16 LuaxState::GetValue < s16 >(int idx, const s16 value);
+ template <> s32 LuaxState::GetValue < s32 >(int idx, const s32 value);
+ template <> s64 LuaxState::GetValue < s64 >(int idx, const s64 value);
+ template <> u8 LuaxState::GetValue < u8 >(int idx, const u8 value);
+ template <> u16 LuaxState::GetValue < u16 >(int idx, const u16 value);
+ template <> u32 LuaxState::GetValue < u32 >(int idx, const u32 value);
+ template <> u64 LuaxState::GetValue < u64 >(int idx, const u64 value);
+ template <> std::string LuaxState::GetValue < std::string >(int idx, const std::string value);
+ template <> const void* LuaxState::GetValue < const void* >(int idx, const void* value);
}
diff --git a/Source/3rdParty/Luax/luax_state.inl b/Source/3rdParty/Luax/luax_state.inl
new file mode 100644
index 0000000..1515123
--- /dev/null
+++ b/Source/3rdParty/Luax/luax_state.inl
@@ -0,0 +1,110 @@
+
+// ͨ͵вͬע̣ͨLuaxStateRegister_ʵ
+
+// עṤΪעinterface tableclass tabletype nameΪƿռϡע׶βԪȵNewõʱŻᡣ
+
+template<typename T>
+void LuaxState::RegisterFactory()
+{
+ lua_State* L = mState;
+
+ int top = lua_gettop(L); // namespace table
+
+ const char* type = T::GetLuaxFactoryName();
+
+ // interface table.
+ lua_newtable(L);
+
+ int idx = AbsIndex(-1);
+
+ LuaxClass::RegisterLuaxInterface<T>(*this);
+ T::RegisterLuaxInterface(*this);
+
+ // TǷûעķ
+#define assertMethods(I, NAME)\
+ GetField(I, NAME);\
+ assert(IsType(-1, LUA_TFUNCTION));\
+ Pop();
+
+ assertMethods(idx, "New");
+
+#undef assertMethods
+
+ lua_settop(L, top);
+
+ // class table.
+ lua_newtable(L);
+
+ assert(lua_istable(L, -1));
+
+ lua_pushvalue(L, -1);
+
+ LuaxClass::RegisterLuaxClass<T>(*this);
+ LuaxClass::RegisterLuaxFactoryClass<T>(*this);
+ T::RegisterLuaxClass(*this);
+
+ SetField(top, type);
+
+ // reset top
+ lua_settop(L, top);
+
+}
+
+// עᵥ
+template<typename T>
+void LuaxState::RegisterSingleton()
+{
+ lua_State* L = mState;
+
+ int top = lua_gettop(L); // namespace table
+
+ const char* type = T::GetLuaxSingletonName();
+
+ // class table.
+ lua_newtable(L);
+
+ assert(lua_istable(L, -1));
+
+ lua_pushvalue(L, -1);
+
+ LuaxClass::RegisterLuaxClass<T>(*this);
+ LuaxClass::RegisterLuaxFactoryClass<T>(*this);
+ T::RegisterLuaxClass(*this);
+
+ SetField(top, type);
+
+ // reset top
+ lua_settop(L, top);
+
+}
+
+template<typename T>
+void LuaxState::SetField(int idx, cc8* key, T value)
+{
+ if (IsTableOrUserdata(idx))
+ {
+ idx = AbsIndex(idx);
+ this->Push(value);
+ lua_setfield(mState, idx, key);
+ }
+}
+
+template<typename T>
+T LuaxState::GetField(int idx, cc8* key, T value)
+{
+ GetField(idx, key);
+ T result = GetValue < T >(-1, value);
+ this->Pop();
+
+ return result;
+}
+
+template<typename T>
+T LuaxState::GetField(int idx, int key, T value)
+{
+ GetField(idx, key);
+ T result = GetValue < T >(-1, value);
+ Pop();
+
+ return result;
+}
diff --git a/Source/Asura.Engine/Application.cpp b/Source/Asura.Engine/Application.cpp
index 59f5aae..598bca8 100644
--- a/Source/Asura.Engine/Application.cpp
+++ b/Source/Asura.Engine/Application.cpp
@@ -1,6 +1,9 @@
-#include "Application.h"
#include "Sdl2/SDL.h"
#include "Exceptions/Exception.h"
+#include "Scripting/Luax.hpp"
+#include "Application.h"
+
+using namespace Luax;
namespace AsuraEngine
{
@@ -15,7 +18,7 @@ namespace AsuraEngine
}
- bool Application::Application::InitSubModules(uint flag)
+ bool Application::InitSubModules(uint flag)
{
// ʼģ
#define TryInitSubModule(module_name, func_name) \
@@ -23,15 +26,34 @@ namespace AsuraEngine
throw Exception("Asura init submodule %s failed.", #module_name);
TryInitSubModule(GRAPHICS, Graphics);
- TryInitSubModule(AUDIO, Audio);
- TryInitSubModule(FONT, Font);
- TryInitSubModule(INPUT, Input);
- TryInitSubModule(MATH, Math);
- TryInitSubModule(PHYSICS, Physics);
- TryInitSubModule(TIME, Time);
- TryInitSubModule(WINDOW, Window);
-
-
+ TryInitSubModule(AUDIO, Audio);
+ TryInitSubModule(FONT, Font);
+ TryInitSubModule(INPUT, Input);
+ TryInitSubModule(MATH, Math);
+ TryInitSubModule(PHYSICS, Physics);
+ TryInitSubModule(TIME, Time);
+ TryInitSubModule(WINDOW, Window);
+
+ }
+
+ void Application::PortToLua()
+ {
+ LuaxState state(mLuaState);
+
+#define RegisterLuaFactory(T) state.RegisterFactory<T>();
+
+ state.SetToGlobalNamespace();
+ state.PushNamespace("AsuraEngine");
+
+ RegisterLuaFactory(AEGraphics::Image>);
+
+#ifdef ASURA_AUTHOR
+ state.PushNamespace("Version");
+
+ state.PopNamespace(); // AsuraEngine.Version
+#endif
+
+ state.PopNamespace(); // AsuraEngine
}
} \ No newline at end of file
diff --git a/Source/Asura.Engine/Application.h b/Source/Asura.Engine/Application.h
index 431924a..08b3bea 100644
--- a/Source/Asura.Engine/Application.h
+++ b/Source/Asura.Engine/Application.h
@@ -1,7 +1,8 @@
#ifndef __ASURA_ENGINE_APPLICATION_H__
#define __ASURA_ENGINE_APPLICATION_H__
-#include "Object.h"
+#include "Scripting/Portable.h"
+#include "Config.h"
namespace AsuraEngine
{
@@ -28,7 +29,7 @@ namespace AsuraEngine
///
/// ѭ
///
- class Application : public Object
+ ASURA_ABSTRACT class Application
{
public:
@@ -40,11 +41,27 @@ namespace AsuraEngine
/// ʼǰϵͳ
///
bool InitSubModules(uint flag = ASURA_MODULE_ALL);
+
+ ///
+ /// עlua࣬ԱأԶ嵼
+ ///
+ virtual void PortToLua();
- virtual void Run();
+ ///
+ ///
+ ///
+ virtual void Run(int argc, char* args[]);
+
+ ///
+ /// ˳runʱĴ
+ ///
+ virtual void Exit();
private:
+ ///
+ /// ģʼڸģļʵ֡
+ ///
bool InitGraphics();
bool InitAudio();
bool InitFont();
@@ -54,6 +71,11 @@ namespace AsuraEngine
bool InitTime();
bool InitWindow();
+ ///
+ /// Lua state.
+ ///
+ lua_State* mLuaState;
+
};
}
diff --git a/Source/Asura.Engine/Asura.h b/Source/Asura.Engine/Asura.h
index e1d8940..5ca56f3 100644
--- a/Source/Asura.Engine/Asura.h
+++ b/Source/Asura.Engine/Asura.h
@@ -5,10 +5,11 @@
#include "Graphics/Shader.h"
-namespace AEGraphics = AsuraEngine::Graphics;
-namespace AEMath = AsuraEngine::Math;
+//namespace AEGraphics = AsuraEngine::Graphics;
+//namespace AEMath = AsuraEngine::Math;
//namespace AETime = AsuraEngine::Time;
//namespace AEInput = AsuraEngine::Input;
//namespace AEProfiler = AsuraEngine::Profiler;
+//namespace AEFont = AsuraEngine::Font;
#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/Audio/Sound.h b/Source/Asura.Engine/Audio/Sound.h
index 3bacd09..095bdb7 100644
--- a/Source/Asura.Engine/Audio/Sound.h
+++ b/Source/Asura.Engine/Audio/Sound.h
@@ -1,15 +1,23 @@
#ifndef __ASURA_ENGINE_SOUND_H__
#define __ASURA_ENGINE_SOUND_H__
-#include "Object.h"
+#include "Scripting/Portable.h"
namespace AsuraEngine
{
namespace Audio
{
- class Sound : virtual public Object, public Scripting::Portable
+ class Sound ASURA_FINAL: virtual public Scripting::Portable
{
+ public:
+
+ Sound();
+ ~Sound();
+
+ private:
+
+
};
diff --git a/Source/Asura.Engine/Audio/SoundDecoder.h b/Source/Asura.Engine/Audio/SoundDecoder.h
index 7b8eb59..ad9f761 100644
--- a/Source/Asura.Engine/Audio/SoundDecoder.h
+++ b/Source/Asura.Engine/Audio/SoundDecoder.h
@@ -12,7 +12,7 @@ namespace AsuraEngine
///
/// Ƶļ
///
- class SoundDecoder : virtual public Object
+ class SoundDecoder
{
public:
diff --git a/Source/Asura.Engine/Config.h b/Source/Asura.Engine/Config.h
new file mode 100644
index 0000000..f02a2ba
--- /dev/null
+++ b/Source/Asura.Engine/Config.h
@@ -0,0 +1,82 @@
+#ifndef __ASURA_CONFIG_H__
+#define __ASURA_CONFIG_H__
+
+namespace AsuraEngine
+{
+
+ //----------------------------------------------------------------------------------------------------------------
+ //
+
+ typedef int8_t int8;
+ typedef uint8_t uint8;
+ typedef uint8 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;
+
+ //----------------------------------------------------------------------------------------------------------------
+ // assert
+
+#ifndef ASSERT
+ #ifdef NDEBUG
+ #define ASSERT(x) { false ? (void)(x) : (void)0; }
+ #else
+ #ifdef _WIN32
+ #define ASURA_DEBUG_BREAK() __debugbreak()
+ #else
+ #define ASURA_DEBUG_BREAK() raise(SIGTRAP)
+ #endif
+ #define ASSERT(x) do { const volatile bool asura_assert_b____ = !(x); if(asura_assert_b____) ASURA_DEBUG_BREAK(); } while (false)
+ #endif
+#endif
+
+ //----------------------------------------------------------------------------------------------------------------
+ //
+
+#ifdef _WIN32
+ #define ASURA_FINAL final
+ #define ASURA_LIBRARY_EXPORT __declspec(dllexport)
+ #define ASURA_LIBRARY_IMPORT __declspec(dllimport)
+ #define ASURA_FORCE_INLINE __forceinline
+ #define ASURA_RESTRICT __restrict
+ #define ASURA_ATTRIBUTE_USED
+ #define ASURA_ABSTRACT
+ #define ASURA_API ASURA_LIBRARY_EXPORT
+#else
+ #define ASURA_FINAL final
+ #define ASURA_LIBRARY_EXPORT __attribute__((visibility("default")))
+ #define ASURA_LIBRARY_IMPORT
+ #define ASURA_FORCE_INLINE __attribute__((always_inline)) inline
+ #define ASURA_RESTRICT __restrict__
+ #define ASURA_ATTRIBUTE_USED __attribute__((used))
+ #define ASURA_ABSTRACT
+ #define ASURA_API ASURA_LIBRARY_EXPORT
+#endif
+
+ //----------------------------------------------------------------------------------------------------------------
+ // Ĭ
+
+#define ASURA_RUN(App) \
+int main(int argc, char* args[]) \
+{ \
+ App app; \
+ app.InitSubModules(); \
+ app.PortToLua(); \
+ app.Run(argc, args); \
+ return 0; \
+}
+
+ //----------------------------------------------------------------------------------------------------------------
+ //
+
+} // namespace AsuraEngine
+
+#endif // __ASURA_CONFIG_H__ \ No newline at end of file
diff --git a/Source/Asura.Engine/Factory.h b/Source/Asura.Engine/Factory.h
deleted file mode 100644
index 984d54f..0000000
--- a/Source/Asura.Engine/Factory.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __ASURA_ENGINE_FACTORY_H__
-#define __ASURA_ENGINE_FACTORY_H__
-
-namespace AsuraEngine
-{
-
- class Factory
- {
-
- };
-
-}
-
-#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/FileSystem/DataBuffer.h b/Source/Asura.Engine/FileSystem/DataBuffer.h
index f7d8cba..84d445c 100644
--- a/Source/Asura.Engine/FileSystem/DataBuffer.h
+++ b/Source/Asura.Engine/FileSystem/DataBuffer.h
@@ -4,7 +4,7 @@
#include <cstdlib>
#include "Scripting/Luax.hpp"
-#include "Object.h"
+#include "Scripting/Portable.h"
namespace AsuraEngine
{
@@ -14,17 +14,17 @@ namespace AsuraEngine
///
/// ڴݵķװеʹData bufferװֱʹconst void*ͨresource managerȡ
///
- class DataBuffer final : virtual public Object, public Scripting::Portable
+ class DataBuffer ASURA_FINAL: public Scripting::Portable
{
public:
DataBuffer(const void* data, std::size_t size);
- virtual ~DataBuffer();
+ ~DataBuffer();
+
+ byte* data;
+ size_t size;
- const void* data;
- std::size_t size;
-
//----------------------------------------------------------------------------------------------------------
LUAX_DECL_FACTORY(DataBuffer);
diff --git a/Source/Asura.Engine/FileSystem/DecodedData.h b/Source/Asura.Engine/FileSystem/DecodedData.h
index 927052f..0b661b6 100644
--- a/Source/Asura.Engine/FileSystem/DecodedData.h
+++ b/Source/Asura.Engine/FileSystem/DecodedData.h
@@ -4,7 +4,7 @@
#include <cstdlib>
#include "DataBuffer.h"
-#include "Object.h"
+#include "Scripting/Portable.h"
namespace AsuraEngine
{
@@ -15,14 +15,14 @@ namespace AsuraEngine
/// һ̹߳data̳дࡣͼƬݡƵݵȣһ߳нԭļڲݸʽ
/// ȡ
///
- class DecodedData : virtual public Object
+ ASURA_ABSTRACT class DecodedData
{
public:
///
/// ڴйdataԷһ߳棬Դϵͳء
///
- DecodedData(const DataBuffer* databuffer);
+ DecodedData(const DataBuffer& databuffer);
virtual ~DecodedData();
@@ -31,7 +31,7 @@ namespace AsuraEngine
///
/// ڴеݡ
///
- virtual void Decode(const DataBuffer* buffer) = 0;
+ virtual void Decode(const DataBuffer& buffer) = 0;
};
diff --git a/Source/Asura.Engine/FileSystem/Reloadable.h b/Source/Asura.Engine/FileSystem/Reloadable.h
index e07b094..eb35d3e 100644
--- a/Source/Asura.Engine/FileSystem/Reloadable.h
+++ b/Source/Asura.Engine/FileSystem/Reloadable.h
@@ -1,20 +1,23 @@
#ifndef __ASURA_ENGINE_RELOADABLE_H__
#define __ASURA_ENGINE_RELOADABLE_H__
-#include "Object.h"
+#include "Scripting/Portable.h"
namespace AsuraEngine
{
namespace Filesystem
{
- class Reloadable : virtual public Object
+ ///
+ /// ¹ݽṹͼƬƵ֣ⲿݿֱӹڱ༭¹ڲıhandleԴ
+ ///
+ ASURA_ABSTRACT class Reloadable
{
public:
Reloadable();
- ~Reloadable();
+ virtual ~Reloadable();
- virtual bool Load();
+ // ̳ReloadableҪṩһload
};
diff --git a/Source/Asura.Engine/FileSystem/ResourceManager.h b/Source/Asura.Engine/FileSystem/ResourceManager.h
index b4aef54..e22ce91 100644
--- a/Source/Asura.Engine/FileSystem/ResourceManager.h
+++ b/Source/Asura.Engine/FileSystem/ResourceManager.h
@@ -4,7 +4,7 @@
#include <string>
#include "DataBuffer.h"
-#include "Object.h"
+#include "Scripting/Portable.h"
namespace AsuraEngine
{
@@ -14,7 +14,7 @@ namespace AsuraEngine
///
/// Դء洢ԴָĿ¼ȡ
///
- class ResourceManager final : virtual public Object
+ class ResourceManager ASURA_FINAL
{
public:
diff --git a/Source/Asura.Engine/Graphics/Application.Graphics.cpp b/Source/Asura.Engine/Graphics/Application.Graphics.cpp
index 64b9e09..4d3102f 100644
--- a/Source/Asura.Engine/Graphics/Application.Graphics.cpp
+++ b/Source/Asura.Engine/Graphics/Application.Graphics.cpp
@@ -15,6 +15,5 @@ namespace AsuraEngine
return false;
}
-
-
+
} \ No newline at end of file
diff --git a/Source/Asura.Engine/Graphics/Canvas.h b/Source/Asura.Engine/Graphics/Canvas.h
index c258793..c4e0f65 100644
--- a/Source/Asura.Engine/Graphics/Canvas.h
+++ b/Source/Asura.Engine/Graphics/Canvas.h
@@ -8,15 +8,18 @@
#include "Texture.h"
#include "RenderTarget.h"
-namespace AsuraEngine
+namespace AsuraEngine
{
- namespace Graphics
+ namespace Graphics
{
-
+
///
/// CanvasҲԳΪrender textureҲΪtextureȾ
///
- class Canvas final : public Drawable, public RenderTarget, public Scripting::Portable
+ class Canvas ASURA_FINAL
+ : public Drawable
+ , public RenderTarget
+ , public Scripting::Portable
{
public:
@@ -29,25 +32,17 @@ namespace AsuraEngine
///
void SetSize(uint w, uint h);
- ///
- /// ȾtexturertϣԭϽǣң
- ///
- void Render(const RenderTarget* rt, const Math::Vector2i& pos, const Math::Vector2i& scale, const Math::Vector2i& center, float rot);
+ void Clear(const Color& col = Color::Black) override;
- ///
- /// ȾtextureһֵrtϣԭϽǣң졣
- ///
- void Render(const RenderTarget* rt, const Math::Rectf& quad, const Math::Vector2i& pos, const Math::Vector2i& scale, const Math::Vector2i& center, float rot);
+ void Clear(const Math::Recti& quad, const Color& col = Color::Black) override;
- //----------------------------------------------------------------------------------------------------------
+ void Render(const RenderTarget* rt, const Math::Vector2i& pos, const Math::Vector2i& scale, const Math::Vector2i& center, float rot);
- LUAX_DECL_FACTORY(SimCanvas);
+ void Render(const RenderTarget* rt, const Math::Rectf& quad, const Math::Vector2i& pos, const Math::Vector2i& scale, const Math::Vector2i& center, float rot);
- LUAX_DECL_METHOD(l_SetSize);
- LUAX_DECL_METHOD(l_Bind);
- LUAX_DECL_METHOD(l_Unbind);
+ void Draw(const Drawable* texture, const RenderState& state);
- //----------------------------------------------------------------------------------------------------------
+ void Draw(const Drawable* texture, const Math::Recti& quad, const RenderState& state);
private:
@@ -61,8 +56,20 @@ namespace AsuraEngine
///
uint mWidth, mHeight;
+ public:
+
+ //----------------------------------------------------------------------------------------------------------
+
+ LUAX_DECL_FACTORY(SimCanvas);
+
+ LUAX_DECL_METHOD(l_SetSize);
+ LUAX_DECL_METHOD(l_Bind);
+ LUAX_DECL_METHOD(l_Unbind);
+
+ //----------------------------------------------------------------------------------------------------------
+
};
-
+
///
/// CanvasΪRenderTexture
///
diff --git a/Source/Asura.Engine/Graphics/Color.h b/Source/Asura.Engine/Graphics/Color.h
index d8f39a0..0d65cb1 100644
--- a/Source/Asura.Engine/Graphics/Color.h
+++ b/Source/Asura.Engine/Graphics/Color.h
@@ -2,8 +2,8 @@
#define __ASURA_ENGINE_COLOR_H__
#include "Scripting/Luax.hpp"
-#include "Object.h"
-#include "Type.h"
+#include "Scripting/Portable.h"
+#include "Config.h"
namespace AsuraEngine
{
@@ -15,12 +15,14 @@ namespace AsuraEngine
///
/// 32bitsɫ
///
- class Color32 : virtual public Object
+ class Color32 ASURA_FINAL: public Scripting::Portable
{
public:
Color32();
+ ~Color32();
+
Color32(const Color32& c);
Color32(const Color& c);
@@ -33,6 +35,7 @@ namespace AsuraEngine
LUAX_DECL_FACTORY(Color32);
+ LUAX_DECL_METHOD(l_ToColor);
LUAX_DECL_METHOD(l_GetRed);
LUAX_DECL_METHOD(l_GetGreen);
LUAX_DECL_METHOD(l_GetBlue);
@@ -48,7 +51,7 @@ namespace AsuraEngine
///
/// 淶ɫ
///
- class Color : virtual public Object
+ class Color ASURA_FINAL: public Scripting::Portable
{
public:
@@ -66,6 +69,8 @@ namespace AsuraEngine
Color(const Color32& c);
+ ~Color();
+
Color operator *(const Color& c);
float r, g, b, a;
@@ -74,6 +79,7 @@ namespace AsuraEngine
LUAX_DECL_FACTORY(Color);
+ LUAX_DECL_METHOD(l_ToColor32);
LUAX_DECL_METHOD(l_SetColor);
LUAX_DECL_METHOD(l_GetColor);
LUAX_DECL_METHOD(l_Multiply); // ɫ˷
diff --git a/Source/Asura.Engine/Graphics/Image.cpp b/Source/Asura.Engine/Graphics/Image.cpp
index 8287d76..e704945 100644
--- a/Source/Asura.Engine/Graphics/Image.cpp
+++ b/Source/Asura.Engine/Graphics/Image.cpp
@@ -1,3 +1,4 @@
+#include "Config.h"
#include "Image.h"
#include "GL.h"
@@ -7,7 +8,6 @@ namespace AsuraEngine
{
Image::Image()
- : Texture()
{
}
@@ -16,18 +16,17 @@ namespace AsuraEngine
}
//\Ϣ
- bool Image::Load(const ImageData* data)
+ bool Image::Load(ImageData* data)
{
- if (!data)
- return false;
- if (mImageData)
- delete mImageData;
- mImageData = data;
+ ASSERT(data);
+
glBindTexture(GL_TEXTURE_2D, mTextureHandle);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, data->width, data->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data->pixels);
glBindTexture(GL_TEXTURE_2D, 0);
return true;
+
+ RRA(data, mImageData);
}
}
-}
+} \ No newline at end of file
diff --git a/Source/Asura.Engine/Graphics/Image.h b/Source/Asura.Engine/Graphics/Image.h
index 7897f74..6d12303 100644
--- a/Source/Asura.Engine/Graphics/Image.h
+++ b/Source/Asura.Engine/Graphics/Image.h
@@ -1,12 +1,12 @@
#ifndef __ASURA_ENGINE_IMAGE_H__
#define __ASURA_ENGINE_IMAGE_H__
+#include "Math/Vector2.hpp"
#include "FileSystem/Reloadable.h"
#include "StringMap.hpp"
#include "Manager.hpp"
#include "Texture.h"
#include "Color.h"
-#include "Factory.h"
#include "ImageData.h"
namespace AsuraEngine
@@ -20,46 +20,55 @@ namespace AsuraEngine
/// ImageͼƬڴ󣬶ȡϷ󱣴ĽһImageڴ桢ԴֻᱣһݣҪ
/// imageêλãźתǶȣʹspriteһֻࡣҪǿǵeditorengineʹòͬķװ
///
- class Image final : public Drawable, public Scripting::Portable, public Filesystem::Reloadable
+ class Image ASURA_FINAL
+ : public Drawable
+ , public Scripting::Portable
+ , public Filesystem::Reloadable
{
public:
Image();
+
~Image();
///
/// bufferimageϢmPixelsΪգݡ¹imageʹglTexImage2Dύimage
/// ݡ
///
- bool Load(const ImageData* data);
+ bool Load(ImageData* data);
uint GetWidth();
uint GetHeight();
+ Math::Vector2u GetSize();
///
/// ijһλõ
///
Color32 GetPixel(uint x, uint y);
- virtual void Render(const RenderTarget* rt, const RenderState& state) override;
+ void Render(const RenderTarget* rt, const RenderState& state) override;
+
+ void Render(const RenderTarget* rt, const Math::Rectf& quad, const RenderState& state) override;
+
+ private:
+
+ ImageData* mImageData;
- virtual void Render(const RenderTarget* rt, const Math::Rectf& quad, const RenderState& state) override;
+ Math::Vector2u mSize;
+
+ public:
//----------------------------------------------------------------------------------------------------------
LUAX_DECL_FACTORY(SimImage);
LUAX_DECL_METHOD(l_Load);
- LUAX_DECL_METHOD(l_GetPixel);
LUAX_DECL_METHOD(l_GetWidth);
LUAX_DECL_METHOD(l_GetHeight);
+ LUAX_DECL_METHOD(l_GetSize);
//----------------------------------------------------------------------------------------------------------
- private:
-
- const ImageData* mImageData;
-
};
}
diff --git a/Source/Asura.Engine/Graphics/ImageData.cpp b/Source/Asura.Engine/Graphics/ImageData.cpp
index 002de67..68781a1 100644
--- a/Source/Asura.Engine/Graphics/ImageData.cpp
+++ b/Source/Asura.Engine/Graphics/ImageData.cpp
@@ -15,7 +15,7 @@ namespace AsuraEngine
new STBDecoder() // jpeg, tga, bmp
};
- ImageData::ImageData(const Filesystem::DataBuffer* buffer)
+ ImageData::ImageData(const Filesystem::DataBuffer& buffer)
: DecodedData(buffer)
{
}
@@ -29,7 +29,7 @@ namespace AsuraEngine
///
/// ޷ɹ׳쳣
///
- void ImageData::Decode(const Filesystem::DataBuffer* buffer)
+ void ImageData::Decode(const Filesystem::DataBuffer& buffer)
{
for (ImageDecoder* decoder : ImageDecoders)
{
diff --git a/Source/Asura.Engine/Graphics/ImageData.h b/Source/Asura.Engine/Graphics/ImageData.h
index 925a5a0..931eaa3 100644
--- a/Source/Asura.Engine/Graphics/ImageData.h
+++ b/Source/Asura.Engine/Graphics/ImageData.h
@@ -13,43 +13,47 @@ namespace AsuraEngine
{
namespace Graphics
{
-
- class ImageData final : public Filesystem::DecodedData, public Scripting::Portable
+
+ class ImageData ASURA_FINAL
+ : public Filesystem::DecodedData
+ , public Scripting::Portable
{
public:
///
/// ͼƬļϢʧܣ׳쳣
///
- ImageData(const Filesystem::DataBuffer* buffer);
+ ImageData(const Filesystem::DataBuffer& buffer);
+
~ImageData();
Color GetPixel(uint x, uint y);
- uint width, height;
+ uint width, height;
PixelFormat format;
std::size_t size;
byte* pixels;
- //----------------------------------------------------------------------------------------------------------
-
- LUAX_DECL_FACTORY(ImageData);
-
- LUAX_DECL_METHOD(l_GetPixel);
- LUAX_DECL_METHOD(l_GetSize);
-
- //----------------------------------------------------------------------------------------------------------
-
private:
- // stbJPEGTGABMP,lodePNGpngͼƬ
- void Decode(const Filesystem::DataBuffer* buffer) override;
+ void Decode(const Filesystem::DataBuffer& buffer) override;
///
/// ڵһ׼image dataʱṩdecoderڼdecodersмѡԡ
///
static std::list<ImageDecoder*> ImageDecoders;
+ public:
+
+ //----------------------------------------------------------------------------------------------------------
+
+ LUAX_DECL_FACTORY(ImageData);
+
+ LUAX_DECL_METHOD(l_GetPixel);
+ LUAX_DECL_METHOD(l_GetSize);
+
+ //----------------------------------------------------------------------------------------------------------
+
};
}
diff --git a/Source/Asura.Engine/Graphics/ImageDecoder.h b/Source/Asura.Engine/Graphics/ImageDecoder.h
index 9dc2188..2c73fd1 100644
--- a/Source/Asura.Engine/Graphics/ImageDecoder.h
+++ b/Source/Asura.Engine/Graphics/ImageDecoder.h
@@ -10,7 +10,7 @@ namespace AsuraEngine
namespace Graphics
{
- class ImageDecoder : virtual public Object
+ class ImageDecoder
{
public:
@@ -20,12 +20,12 @@ namespace AsuraEngine
///
/// жڴǷñdecoderѹ
///
- virtual bool CanDecode(const Filesystem::DataBuffer* buffer) = 0;
+ virtual bool CanDecode(const Filesystem::DataBuffer& buffer) = 0;
///
/// һڴ棬һѹImage dataѹʧܷnullptr
///
- virtual void Decode(const Filesystem::DataBuffer* buffer, ImageData* data) = 0;
+ virtual void Decode(const Filesystem::DataBuffer& buffer, ImageData& data) = 0;
};
diff --git a/Source/Asura.Engine/Graphics/Mesh2D.h b/Source/Asura.Engine/Graphics/Mesh2D.h
index cadbec1..de4a0c8 100644
--- a/Source/Asura.Engine/Graphics/Mesh2D.h
+++ b/Source/Asura.Engine/Graphics/Mesh2D.h
@@ -3,7 +3,7 @@
#include "Scripting/Luax.hpp"
-#include "Object.h"
+#include "Scripting/Portable.h"
namespace AsuraEngine
{
@@ -13,8 +13,13 @@ namespace AsuraEngine
///
/// 2D meshһЩ㶯
///
- class Mesh2D : virtual public Object, public Scripting::Portable
+ class Mesh2D ASURA_FINAL: public Scripting::Portable
{
+ public:
+
+ Mesh2D();
+
+ ~Mesh2D();
};
diff --git a/Source/Asura.Engine/Graphics/PNGDecoder.cpp b/Source/Asura.Engine/Graphics/PNGDecoder.cpp
index 363d478..f919090 100644
--- a/Source/Asura.Engine/Graphics/PNGDecoder.cpp
+++ b/Source/Asura.Engine/Graphics/PNGDecoder.cpp
@@ -5,12 +5,12 @@ namespace AsuraEngine
namespace Graphics
{
- bool PNGDecoder::CanDecode(const Filesystem::DataBuffer* buffer)
+ bool PNGDecoder::CanDecode(const Filesystem::DataBuffer& buffer)
{
return false;
}
- void PNGDecoder::Decode(const Filesystem::DataBuffer* buffer, ImageData* data)
+ void PNGDecoder::Decode(const Filesystem::DataBuffer& buffer, ImageData& data)
{
}
diff --git a/Source/Asura.Engine/Graphics/PNGDecoder.h b/Source/Asura.Engine/Graphics/PNGDecoder.h
index dc5bb60..980753f 100644
--- a/Source/Asura.Engine/Graphics/PNGDecoder.h
+++ b/Source/Asura.Engine/Graphics/PNGDecoder.h
@@ -11,13 +11,13 @@ namespace AsuraEngine
///
/// ʹlodepngѹpngļ
///
- class PNGDecoder final : public ImageDecoder
+ class PNGDecoder ASURA_FINAL: public ImageDecoder
{
public:
- bool CanDecode(const Filesystem::DataBuffer* buffer) override;
+ bool CanDecode(const Filesystem::DataBuffer& buffer) override;
- void Decode(const Filesystem::DataBuffer* buffer, ImageData* data) override;
+ void Decode(const Filesystem::DataBuffer& buffer, ImageData& data) override;
};
diff --git a/Source/Asura.Engine/Graphics/Port/Window.cpp b/Source/Asura.Engine/Graphics/Port/Window.cpp
new file mode 100644
index 0000000..3befc8c
--- /dev/null
+++ b/Source/Asura.Engine/Graphics/Port/Window.cpp
@@ -0,0 +1,11 @@
+#include "../Window.h"
+
+namespace AsuraEngine
+{
+ namespace Graphics
+ {
+
+
+
+ }
+}
diff --git a/Source/Asura.Engine/Font/Glyph.cpp b/Source/Asura.Engine/Graphics/Quad.cpp
index e69de29..e69de29 100644
--- a/Source/Asura.Engine/Font/Glyph.cpp
+++ b/Source/Asura.Engine/Graphics/Quad.cpp
diff --git a/Source/Asura.Engine/Graphics/Quad.h b/Source/Asura.Engine/Graphics/Quad.h
new file mode 100644
index 0000000..b7dd3d9
--- /dev/null
+++ b/Source/Asura.Engine/Graphics/Quad.h
@@ -0,0 +1 @@
+// Quadrectڣrectǵıƫᣬquadһ
diff --git a/Source/Asura.Engine/Graphics/RenderState.h b/Source/Asura.Engine/Graphics/RenderState.h
index 9524ef6..f313296 100644
--- a/Source/Asura.Engine/Graphics/RenderState.h
+++ b/Source/Asura.Engine/Graphics/RenderState.h
@@ -16,10 +16,8 @@ namespace AsuraEngine
///
/// Ⱦǰķʽ
///
- class RenderState final : virtual public Object
+ struct RenderState ASURA_FINAL
{
- public:
-
///
/// Ĭϵrender state
///
diff --git a/Source/Asura.Engine/Graphics/RenderTarget.h b/Source/Asura.Engine/Graphics/RenderTarget.h
index afa8967..d6de164 100644
--- a/Source/Asura.Engine/Graphics/RenderTarget.h
+++ b/Source/Asura.Engine/Graphics/RenderTarget.h
@@ -3,7 +3,7 @@
#include "Math/Rect.hpp"
#include "Texture.h"
-#include "Object.h"
+#include "Scripting/Portable.h"
#include "Color.h"
namespace AsuraEngine
@@ -18,7 +18,7 @@ namespace AsuraEngine
/// Canvas(RenderTexture)
/// Window(RenderWindow)
///
- class RenderTarget : virtual public Object
+ class RenderTarget
{
public:
diff --git a/Source/Asura.Engine/Graphics/STBDecoder.cpp b/Source/Asura.Engine/Graphics/STBDecoder.cpp
index d4d578f..b14d0f3 100644
--- a/Source/Asura.Engine/Graphics/STBDecoder.cpp
+++ b/Source/Asura.Engine/Graphics/STBDecoder.cpp
@@ -8,25 +8,21 @@ namespace AsuraEngine
namespace Graphics
{
- bool STBDecoder::CanDecode(const Filesystem::DataBuffer* buffer)
+ bool STBDecoder::CanDecode(const Filesystem::DataBuffer& buffer)
{
int w = 0;
int h = 0;
int comp = 0;
- int status = stbi_info_from_memory((const stbi_uc *)buffer->data, buffer->size, &w, &h, &comp);
+ int status = stbi_info_from_memory((const stbi_uc*)buffer.data, buffer.size, &w, &h, &comp);
return status == 1 && w > 0 && h > 0;
}
- void STBDecoder::Decode(const Filesystem::DataBuffer* db, ImageData* imageData)
+ void STBDecoder::Decode(const Filesystem::DataBuffer& db, ImageData& imageData)
{
- if (!db)
- throw Exception("Could not decode image with stb decoder because of null databuffer.");
- if (!imageData)
- throw Exception("Could not decode image with stb decoder because of null output image data.");
- const stbi_uc *buffer = (const stbi_uc *)db->data;
- int bufferlen = db->size;
+ const stbi_uc *buffer = (const stbi_uc *)db.data;
+ int bufferlen = db.size;
int width, height;
int comp = 0;
byte* data = nullptr;
@@ -49,12 +45,12 @@ namespace AsuraEngine
if (data)
{
// ֤ڴ汻ͷţһϲûͷŵΪimage dataһԵģimageǶεġ
- if (imageData->pixels)
- delete[] imageData->pixels;
- imageData->pixels = (byte*)data;
- imageData->format = format;
- imageData->width = width;
- imageData->height = height;
+ if (imageData.pixels)
+ delete[] imageData.pixels;
+ imageData.pixels = (byte*)data;
+ imageData.format = format;
+ imageData.width = width;
+ imageData.height = height;
}
else
{
diff --git a/Source/Asura.Engine/Graphics/STBDecoder.h b/Source/Asura.Engine/Graphics/STBDecoder.h
index d89042e..5567466 100644
--- a/Source/Asura.Engine/Graphics/STBDecoder.h
+++ b/Source/Asura.Engine/Graphics/STBDecoder.h
@@ -11,13 +11,13 @@ namespace AsuraEngine
///
/// ʹstb_imageѹJPEGTGABMPļ
///
- class STBDecoder final : public ImageDecoder
+ class STBDecoder ASURA_FINAL: public ImageDecoder
{
public:
- bool CanDecode(const Filesystem::DataBuffer* buffer) override;
+ bool CanDecode(const Filesystem::DataBuffer& buffer) override;
- void Decode(const Filesystem::DataBuffer* buffer, ImageData* data) override;
+ void Decode(const Filesystem::DataBuffer& buffer, ImageData& data) override;
};
diff --git a/Source/Asura.Engine/Graphics/Shader.h b/Source/Asura.Engine/Graphics/Shader.h
index 7dbfb0d..932cc42 100644
--- a/Source/Asura.Engine/Graphics/Shader.h
+++ b/Source/Asura.Engine/Graphics/Shader.h
@@ -11,7 +11,7 @@
#include "Math/Vector4.h"
#include "Math/Matrix44.h"
#include "StringMap.hpp"
-#include "Object.h"
+#include "Scripting/Portable.h"
#include "Color.h"
#include "Manager.hpp"
#include "Texture.h"
@@ -26,13 +26,16 @@ namespace AsuraEngine
/// һshaderһڲʼ乲ijShaderuniformsͶݣֻṩuniformsuseɫķ༭
/// ÿshaderͨshaderҵuniforms¶frameworkmaterialá
///
- class Shader final : virtual public Object, public Filesystem::Reloadable
+ class Shader ASURA_FINAL
+ : public Scripting::Portable
+ , public Filesystem::Reloadable
{
public:
Shader();
+
~Shader();
-
+
///
/// ӴshaderʱȼǷϴλuniforms location mapʹglAttachShader±ɫ
/// ɫ
@@ -42,12 +45,12 @@ namespace AsuraEngine
///
/// shaderΪ
///
- void Use();
+ void Use();
///
/// shaderΪǻ
///
- void Unuse();
+ void Unuse();
///
/// Ѿ֪uniform location£ֵ
@@ -71,25 +74,6 @@ namespace AsuraEngine
///
static uint GetGLTextureUnitCount();
- //----------------------------------------------------------------------------------------------------------
-
- LUAX_DECL_FACTORY(SimShader);
-
- LUAX_DECL_METHOD(l_Use);
- LUAX_DECL_METHOD(l_Unuse);
- LUAX_DECL_METHOD(l_Load);
- LUAX_DECL_METHOD(l_HasUniform);
- LUAX_DECL_METHOD(l_GetUniformLocation);
- LUAX_DECL_METHOD(l_SetBuiltInUniforms);
- LUAX_DECL_METHOD(l_SetUniformFloat);
- LUAX_DECL_METHOD(l_SetUniformTexture);
- LUAX_DECL_METHOD(l_SetUniformVector2);
- LUAX_DECL_METHOD(l_SetUniformVector3);
- LUAX_DECL_METHOD(l_SetUniformVector4);
- LUAX_DECL_METHOD(l_SetUniformColor);
-
- //----------------------------------------------------------------------------------------------------------
-
private:
///
@@ -110,6 +94,27 @@ namespace AsuraEngine
///
GLuint mProgramHandle;
+ public:
+
+ //----------------------------------------------------------------------------------------------------------
+
+ LUAX_DECL_FACTORY(SimShader);
+
+ LUAX_DECL_METHOD(l_Use);
+ LUAX_DECL_METHOD(l_Unuse);
+ LUAX_DECL_METHOD(l_Load);
+ LUAX_DECL_METHOD(l_HasUniform);
+ LUAX_DECL_METHOD(l_GetUniformLocation);
+ LUAX_DECL_METHOD(l_SetBuiltInUniforms);
+ LUAX_DECL_METHOD(l_SetUniformFloat);
+ LUAX_DECL_METHOD(l_SetUniformTexture);
+ LUAX_DECL_METHOD(l_SetUniformVector2);
+ LUAX_DECL_METHOD(l_SetUniformVector3);
+ LUAX_DECL_METHOD(l_SetUniformVector4);
+ LUAX_DECL_METHOD(l_SetUniformColor);
+
+ //----------------------------------------------------------------------------------------------------------
+
};
}
diff --git a/Source/Asura.Engine/Graphics/SpriteBatch.h b/Source/Asura.Engine/Graphics/SpriteBatch.h
index a571775..353bf77 100644
--- a/Source/Asura.Engine/Graphics/SpriteBatch.h
+++ b/Source/Asura.Engine/Graphics/SpriteBatch.h
@@ -1,7 +1,7 @@
#ifndef __ASURA_ENGINE_SPRITE_BATCH_H__
#define __ASURA_ENGINE_SPRITE_BATCH_H__
-#include "Object.h"
+#include "Scripting/Portable.h"
namespace AsuraEngine
{
@@ -11,12 +11,14 @@ namespace AsuraEngine
///
/// Sprite batchȾͼƬĵطϵͳ
///
- class SpriteBatch : virtual public Object
+ class SpriteBatch ASURA_FINAL : public Scripting::Portable
{
public:
SpriteBatch();
+ ~SpriteBatch();
+
};
}
diff --git a/Source/Asura.Engine/Graphics/Texture.h b/Source/Asura.Engine/Graphics/Texture.h
index c1411fc..81aa469 100644
--- a/Source/Asura.Engine/Graphics/Texture.h
+++ b/Source/Asura.Engine/Graphics/Texture.h
@@ -1,6 +1,7 @@
#ifndef __ASURA_ENGINE_TEXTURE_H__
#define __ASURA_ENGINE_TEXTURE_H__
+#include "Config.h"
#include "Math/Rect.hpp"
#include "Math/Vector2.hpp"
#include "Scripting/Luax.hpp"
@@ -18,7 +19,7 @@ namespace AsuraEngine
/// 2D࣬2d meshrender targetбʹáTextureȾԭϽǣϷϲԵѿϵΪ׼
/// EditorҲϽΪԭ㣬Ϊ˷㡣
///
- class Texture : virtual public Object
+ ASURA_ABSTRACT class Texture
{
public:
@@ -48,7 +49,7 @@ namespace AsuraEngine
///
void SetRepeated();
- protected:
+ protected:
///
/// OpenGL texture handle
diff --git a/Source/Asura.Engine/Window/Window.cpp b/Source/Asura.Engine/Graphics/Window.cpp
index 6e9300f..bb941e1 100644
--- a/Source/Asura.Engine/Window/Window.cpp
+++ b/Source/Asura.Engine/Graphics/Window.cpp
@@ -1,3 +1,4 @@
+#include "Config.h"
#include "Window.h"
namespace AsuraEngine
@@ -22,7 +23,8 @@ namespace AsuraEngine
void Window::SetPosition(int x, int y)
{
-
+ ASSERT(mWindowHandle);
+ SDL_SetWindowPosition(mWindowHandle, x, y);
}
void Window::SetTitle(const std::string& title)
diff --git a/Source/Asura.Engine/Window/Window.h b/Source/Asura.Engine/Graphics/Window.h
index 71aaf0e..973fd98 100644
--- a/Source/Asura.Engine/Window/Window.h
+++ b/Source/Asura.Engine/Graphics/Window.h
@@ -4,6 +4,7 @@
#include "SDL2/Sdl.h"
#include "Graphics/RenderTarget.h"
#include "Math/Vector2.hpp"
+#include "Scripting/Portable.h"
namespace AsuraEngine
{
@@ -18,7 +19,9 @@ namespace AsuraEngine
///
/// ڣֶ֧രڡڱ༭Ҫ֧֣runnerֻҪһڡ
///
- class Window : public RenderTarget
+ class Window ASURA_FINAL
+ : public RenderTarget
+ , public Scripting::Portable
{
public:
@@ -45,13 +48,13 @@ namespace AsuraEngine
///
void SwapRenderBuffer();
- void Clear(const Color& col = Color::Black);
+ void Clear(const Color& col = Color::Black) override;
- void Clear(const Math::Recti& quad, const Color& col = Color::Black);
+ void Clear(const Math::Recti& quad, const Color& col = Color::Black) override;
- void Draw(const Drawable* texture, const RenderState& state);
+ void Draw(const Drawable* texture, const RenderState& state) override;
- void Draw(const Drawable* texture, const Math::Recti& quad, const RenderState& state);
+ void Draw(const Drawable* texture, const Math::Recti& quad, const RenderState& state) override;
private:
@@ -64,6 +67,14 @@ namespace AsuraEngine
Math::Vector2i mSize;
+ public:
+
+ //----------------------------------------------------------------------------------------------------------
+
+ LUAX_DECL_FACTORY(Window);
+
+ //----------------------------------------------------------------------------------------------------------
+
};
using RenderWindow = Window;
diff --git a/Source/Asura.Engine/Font/Glyph.h b/Source/Asura.Engine/Input/Clipboard.cpp
index e69de29..e69de29 100644
--- a/Source/Asura.Engine/Font/Glyph.h
+++ b/Source/Asura.Engine/Input/Clipboard.cpp
diff --git a/Source/Asura.Engine/Input/Clipboard.h b/Source/Asura.Engine/Input/Clipboard.h
new file mode 100644
index 0000000..4cecd55
--- /dev/null
+++ b/Source/Asura.Engine/Input/Clipboard.h
@@ -0,0 +1,37 @@
+#ifndef __ASURA_ENGINE_CLIPBOARD_H__
+#define __ASURA_ENGINE_CLIPBOARD_H__
+
+#include "Text/String.hpp"
+#include "InputDevice.hpp"
+
+namespace AsuraEngine
+{
+ namespace Input
+ {
+
+ class Clipboard ASURA_FINAL : public InputDevice<Clipboard>
+ {
+ public:
+
+ Clipboard();
+
+ Text::String GetString();
+
+ void SetString(const Text::String& text);
+
+ //----------------------------------------------------------------------------------------------------------
+
+ LUAX_DECL_SINGLETON(Clipboard);
+
+ //----------------------------------------------------------------------------------------------------------
+
+ private:
+
+ ~Clipboard();
+
+ };
+
+ };
+}
+
+#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/Font/TrueTypeFont.cpp b/Source/Asura.Engine/Input/Cursor.cpp
index e69de29..e69de29 100644
--- a/Source/Asura.Engine/Font/TrueTypeFont.cpp
+++ b/Source/Asura.Engine/Input/Cursor.cpp
diff --git a/Source/Asura.Engine/Input/Cursor.defs b/Source/Asura.Engine/Input/Cursor.defs
new file mode 100644
index 0000000..f8b8492
--- /dev/null
+++ b/Source/Asura.Engine/Input/Cursor.defs
@@ -0,0 +1,25 @@
+
+// Types of system cursors.
+enum SystemCursor
+{
+ CURSOR_ARROW,
+ CURSOR_IBEAM,
+ CURSOR_WAIT,
+ CURSOR_CROSSHAIR,
+ CURSOR_WAITARROW,
+ CURSOR_SIZENWSE,
+ CURSOR_SIZENESW,
+ CURSOR_SIZEWE,
+ CURSOR_SIZENS,
+ CURSOR_SIZEALL,
+ CURSOR_NO,
+ CURSOR_HAND,
+ CURSOR_MAX_ENUM
+};
+
+enum CursorType
+{
+ CURSORTYPE_SYSTEM,
+ CURSORTYPE_IMAGE,
+ CURSORTYPE_MAX_ENUM
+};
diff --git a/Source/Asura.Engine/Input/Cursor.h b/Source/Asura.Engine/Input/Cursor.h
new file mode 100644
index 0000000..7125869
--- /dev/null
+++ b/Source/Asura.Engine/Input/Cursor.h
@@ -0,0 +1,54 @@
+#ifndef __ASURA_ENGINE_CURSOR_H__
+#define __ASURA_ENGINE_CURSOR_H__
+
+#include <SDL2/SDL.h>
+
+#include "Scripting/Portable.h"
+#include "Graphics/ImageData.h"
+#include "InputDevice.hpp"
+
+namespace AsuraEngine
+{
+ namespace Input
+ {
+
+ class Cursor : public Scripting::Portable
+ {
+ public:
+
+ // ָö
+ #include "Cursor.defs"
+
+ Cursor(Graphics::ImageData& imageData, int hotx, int hoty);
+ Cursor(SystemCursor cursortype);
+
+ ~Cursor();
+
+ SDL_Cursor* GetHandle() const;
+ CursorType GetType() const;
+ SystemCursor GetSystemType() const;
+
+ private:
+
+ SDL_Cursor* mCursorHandle;
+
+ CursorType mType;
+ SystemCursor mSystemType;
+
+ public:
+
+ //----------------------------------------------------------------------------------------------------------
+
+ LUAX_DECL_FACTORY(Cursor);
+
+ LUAX_DECL_ENUM(EnumCursorType);
+ LUAX_DECL_ENUM(EnumSystemCursor);
+
+ //----------------------------------------------------------------------------------------------------------
+
+ };
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/Input/InputDevice.hpp b/Source/Asura.Engine/Input/InputDevice.hpp
new file mode 100644
index 0000000..eb0b7a3
--- /dev/null
+++ b/Source/Asura.Engine/Input/InputDevice.hpp
@@ -0,0 +1,30 @@
+#ifndef __ASURA_ENGINE_INPUT_BASE_H__
+#define __ASURA_ENGINE_INPUT_BASE_H__
+
+#include "Scripting/Portable.h"
+#include "Config.h"
+#include "Singleton.hpp"
+
+namespace AsuraEngine
+{
+ namespace Input
+ {
+
+ ///
+ /// 豸һ
+ ///
+ template<class T>
+ ASURA_ABSTRACT class InputDevice
+ : virtual public Scripting::Portable
+ , virtual public Singleton<T>
+ {
+ public:
+ InputDevice();
+ virtual ~InputDevice();
+
+ };
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/Input/Keyboard.defs b/Source/Asura.Engine/Input/Keyboard.defs
new file mode 100644
index 0000000..8f04dc2
--- /dev/null
+++ b/Source/Asura.Engine/Input/Keyboard.defs
@@ -0,0 +1,482 @@
+
+/**
+* Keyboard keys. They are dependent on the current layout of the keyboard.
+**/
+enum Key
+{
+ KEY_UNKNOWN,
+
+ KEY_RETURN,
+ KEY_ESCAPE,
+ KEY_BACKSPACE,
+ KEY_TAB,
+ KEY_SPACE,
+ KEY_EXCLAIM,
+ KEY_QUOTEDBL,
+ KEY_HASH,
+ KEY_PERCENT,
+ KEY_DOLLAR,
+ KEY_AMPERSAND,
+ KEY_QUOTE,
+ KEY_LEFTPAREN,
+ KEY_RIGHTPAREN,
+ KEY_ASTERISK,
+ KEY_PLUS,
+ KEY_COMMA,
+ KEY_MINUS,
+ KEY_PERIOD,
+ KEY_SLASH,
+ KEY_0,
+ KEY_1,
+ KEY_2,
+ KEY_3,
+ KEY_4,
+ KEY_5,
+ KEY_6,
+ KEY_7,
+ KEY_8,
+ KEY_9,
+ KEY_COLON,
+ KEY_SEMICOLON,
+ KEY_LESS,
+ KEY_EQUALS,
+ KEY_GREATER,
+ KEY_QUESTION,
+ KEY_AT,
+
+ KEY_LEFTBRACKET,
+ KEY_BACKSLASH,
+ KEY_RIGHTBRACKET,
+ KEY_CARET,
+ KEY_UNDERSCORE,
+ KEY_BACKQUOTE,
+ KEY_A,
+ KEY_B,
+ KEY_C,
+ KEY_D,
+ KEY_E,
+ KEY_F,
+ KEY_G,
+ KEY_H,
+ KEY_I,
+ KEY_J,
+ KEY_K,
+ KEY_L,
+ KEY_M,
+ KEY_N,
+ KEY_O,
+ KEY_P,
+ KEY_Q,
+ KEY_R,
+ KEY_S,
+ KEY_T,
+ KEY_U,
+ KEY_V,
+ KEY_W,
+ KEY_X,
+ KEY_Y,
+ KEY_Z,
+
+ KEY_CAPSLOCK,
+
+ KEY_F1,
+ KEY_F2,
+ KEY_F3,
+ KEY_F4,
+ KEY_F5,
+ KEY_F6,
+ KEY_F7,
+ KEY_F8,
+ KEY_F9,
+ KEY_F10,
+ KEY_F11,
+ KEY_F12,
+
+ KEY_PRINTSCREEN,
+ KEY_SCROLLLOCK,
+ KEY_PAUSE,
+ KEY_INSERT,
+ KEY_HOME,
+ KEY_PAGEUP,
+ KEY_DELETE,
+ KEY_END,
+ KEY_PAGEDOWN,
+ KEY_RIGHT,
+ KEY_LEFT,
+ KEY_DOWN,
+ KEY_UP,
+
+ KEY_NUMLOCKCLEAR,
+ KEY_KP_DIVIDE,
+ KEY_KP_MULTIPLY,
+ KEY_KP_MINUS,
+ KEY_KP_PLUS,
+ KEY_KP_ENTER,
+ KEY_KP_1,
+ KEY_KP_2,
+ KEY_KP_3,
+ KEY_KP_4,
+ KEY_KP_5,
+ KEY_KP_6,
+ KEY_KP_7,
+ KEY_KP_8,
+ KEY_KP_9,
+ KEY_KP_0,
+ KEY_KP_PERIOD,
+ KEY_KP_COMMA,
+ KEY_KP_EQUALS,
+
+ KEY_APPLICATION,
+ KEY_POWER,
+ KEY_F13,
+ KEY_F14,
+ KEY_F15,
+ KEY_F16,
+ KEY_F17,
+ KEY_F18,
+ KEY_F19,
+ KEY_F20,
+ KEY_F21,
+ KEY_F22,
+ KEY_F23,
+ KEY_F24,
+ KEY_EXECUTE,
+ KEY_HELP,
+ KEY_MENU,
+ KEY_SELECT,
+ KEY_STOP,
+ KEY_AGAIN,
+ KEY_UNDO,
+ KEY_CUT,
+ KEY_COPY,
+ KEY_PASTE,
+ KEY_FIND,
+ KEY_MUTE,
+ KEY_VOLUMEUP,
+ KEY_VOLUMEDOWN,
+
+ KEY_ALTERASE,
+ KEY_SYSREQ,
+ KEY_CANCEL,
+ KEY_CLEAR,
+ KEY_PRIOR,
+ KEY_RETURN2,
+ KEY_SEPARATOR,
+ KEY_OUT,
+ KEY_OPER,
+ KEY_CLEARAGAIN,
+
+ KEY_THOUSANDSSEPARATOR,
+ KEY_DECIMALSEPARATOR,
+ KEY_CURRENCYUNIT,
+ KEY_CURRENCYSUBUNIT,
+
+ KEY_LCTRL,
+ KEY_LSHIFT,
+ KEY_LALT,
+ KEY_LGUI,
+ KEY_RCTRL,
+ KEY_RSHIFT,
+ KEY_RALT,
+ KEY_RGUI,
+
+ KEY_MODE,
+
+ KEY_AUDIONEXT,
+ KEY_AUDIOPREV,
+ KEY_AUDIOSTOP,
+ KEY_AUDIOPLAY,
+ KEY_AUDIOMUTE,
+ KEY_MEDIASELECT,
+ KEY_WWW,
+ KEY_MAIL,
+ KEY_CALCULATOR,
+ KEY_COMPUTER,
+ KEY_APP_SEARCH,
+ KEY_APP_HOME,
+ KEY_APP_BACK,
+ KEY_APP_FORWARD,
+ KEY_APP_STOP,
+ KEY_APP_REFRESH,
+ KEY_APP_BOOKMARKS,
+
+ KEY_BRIGHTNESSDOWN,
+ KEY_BRIGHTNESSUP,
+ KEY_DISPLAYSWITCH,
+ KEY_KBDILLUMTOGGLE,
+ KEY_KBDILLUMDOWN,
+ KEY_KBDILLUMUP,
+ KEY_EJECT,
+ KEY_SLEEP,
+
+ KEY_MAX_ENUM
+};
+
+/**
+* Scancodes represent physical keys independent of the current layout.
+* Their names may not match the names of the keys printed on the keyboard.
+* Some of them are very esoteric...
+**/
+enum Scancode
+{
+ SCANCODE_UNKNOWN,
+
+ SCANCODE_A,
+ SCANCODE_B,
+ SCANCODE_C,
+ SCANCODE_D,
+ SCANCODE_E,
+ SCANCODE_F,
+ SCANCODE_G,
+ SCANCODE_H,
+ SCANCODE_I,
+ SCANCODE_J,
+ SCANCODE_K,
+ SCANCODE_L,
+ SCANCODE_M,
+ SCANCODE_N,
+ SCANCODE_O,
+ SCANCODE_P,
+ SCANCODE_Q,
+ SCANCODE_R,
+ SCANCODE_S,
+ SCANCODE_T,
+ SCANCODE_U,
+ SCANCODE_V,
+ SCANCODE_W,
+ SCANCODE_X,
+ SCANCODE_Y,
+ SCANCODE_Z,
+
+ SCANCODE_1,
+ SCANCODE_2,
+ SCANCODE_3,
+ SCANCODE_4,
+ SCANCODE_5,
+ SCANCODE_6,
+ SCANCODE_7,
+ SCANCODE_8,
+ SCANCODE_9,
+ SCANCODE_0,
+
+ SCANCODE_RETURN,
+ SCANCODE_ESCAPE,
+ SCANCODE_BACKSPACE,
+ SCANCODE_TAB,
+ SCANCODE_SPACE,
+
+ SCANCODE_MINUS,
+ SCANCODE_EQUALS,
+ SCANCODE_LEFTBRACKET,
+ SCANCODE_RIGHTBRACKET,
+ SCANCODE_BACKSLASH,
+ SCANCODE_NONUSHASH,
+ SCANCODE_SEMICOLON,
+ SCANCODE_APOSTROPHE,
+ SCANCODE_GRAVE,
+ SCANCODE_COMMA,
+ SCANCODE_PERIOD,
+ SCANCODE_SLASH,
+
+ SCANCODE_CAPSLOCK,
+
+ SCANCODE_F1,
+ SCANCODE_F2,
+ SCANCODE_F3,
+ SCANCODE_F4,
+ SCANCODE_F5,
+ SCANCODE_F6,
+ SCANCODE_F7,
+ SCANCODE_F8,
+ SCANCODE_F9,
+ SCANCODE_F10,
+ SCANCODE_F11,
+ SCANCODE_F12,
+
+ SCANCODE_PRINTSCREEN,
+ SCANCODE_SCROLLLOCK,
+ SCANCODE_PAUSE,
+ SCANCODE_INSERT,
+ SCANCODE_HOME,
+ SCANCODE_PAGEUP,
+ SCANCODE_DELETE,
+ SCANCODE_END,
+ SCANCODE_PAGEDOWN,
+ SCANCODE_RIGHT,
+ SCANCODE_LEFT,
+ SCANCODE_DOWN,
+ SCANCODE_UP,
+
+ SCANCODE_NUMLOCKCLEAR,
+ SCANCODE_KP_DIVIDE,
+ SCANCODE_KP_MULTIPLY,
+ SCANCODE_KP_MINUS,
+ SCANCODE_KP_PLUS,
+ SCANCODE_KP_ENTER,
+ SCANCODE_KP_1,
+ SCANCODE_KP_2,
+ SCANCODE_KP_3,
+ SCANCODE_KP_4,
+ SCANCODE_KP_5,
+ SCANCODE_KP_6,
+ SCANCODE_KP_7,
+ SCANCODE_KP_8,
+ SCANCODE_KP_9,
+ SCANCODE_KP_0,
+ SCANCODE_KP_PERIOD,
+
+ SCANCODE_NONUSBACKSLASH,
+ SCANCODE_APPLICATION,
+ SCANCODE_POWER,
+ SCANCODE_KP_EQUALS,
+ SCANCODE_F13,
+ SCANCODE_F14,
+ SCANCODE_F15,
+ SCANCODE_F16,
+ SCANCODE_F17,
+ SCANCODE_F18,
+ SCANCODE_F19,
+ SCANCODE_F20,
+ SCANCODE_F21,
+ SCANCODE_F22,
+ SCANCODE_F23,
+ SCANCODE_F24,
+ SCANCODE_EXECUTE,
+ SCANCODE_HELP,
+ SCANCODE_MENU,
+ SCANCODE_SELECT,
+ SCANCODE_STOP,
+ SCANCODE_AGAIN,
+ SCANCODE_UNDO,
+ SCANCODE_CUT,
+ SCANCODE_COPY,
+ SCANCODE_PASTE,
+ SCANCODE_FIND,
+ SCANCODE_MUTE,
+ SCANCODE_VOLUMEUP,
+ SCANCODE_VOLUMEDOWN,
+ SCANCODE_KP_COMMA,
+ SCANCODE_KP_EQUALSAS400,
+
+ SCANCODE_INTERNATIONAL1,
+ SCANCODE_INTERNATIONAL2,
+ SCANCODE_INTERNATIONAL3,
+ SCANCODE_INTERNATIONAL4,
+ SCANCODE_INTERNATIONAL5,
+ SCANCODE_INTERNATIONAL6,
+ SCANCODE_INTERNATIONAL7,
+ SCANCODE_INTERNATIONAL8,
+ SCANCODE_INTERNATIONAL9,
+ SCANCODE_LANG1,
+ SCANCODE_LANG2,
+ SCANCODE_LANG3,
+ SCANCODE_LANG4,
+ SCANCODE_LANG5,
+ SCANCODE_LANG6,
+ SCANCODE_LANG7,
+ SCANCODE_LANG8,
+ SCANCODE_LANG9,
+
+ SCANCODE_ALTERASE,
+ SCANCODE_SYSREQ,
+ SCANCODE_CANCEL,
+ SCANCODE_CLEAR,
+ SCANCODE_PRIOR,
+ SCANCODE_RETURN2,
+ SCANCODE_SEPARATOR,
+ SCANCODE_OUT,
+ SCANCODE_OPER,
+ SCANCODE_CLEARAGAIN,
+ SCANCODE_CRSEL,
+ SCANCODE_EXSEL,
+
+ SCANCODE_KP_00,
+ SCANCODE_KP_000,
+ SCANCODE_THOUSANDSSEPARATOR,
+ SCANCODE_DECIMALSEPARATOR,
+ SCANCODE_CURRENCYUNIT,
+ SCANCODE_CURRENCYSUBUNIT,
+ SCANCODE_KP_LEFTPAREN,
+ SCANCODE_KP_RIGHTPAREN,
+ SCANCODE_KP_LEFTBRACE,
+ SCANCODE_KP_RIGHTBRACE,
+ SCANCODE_KP_TAB,
+ SCANCODE_KP_BACKSPACE,
+ SCANCODE_KP_A,
+ SCANCODE_KP_B,
+ SCANCODE_KP_C,
+ SCANCODE_KP_D,
+ SCANCODE_KP_E,
+ SCANCODE_KP_F,
+ SCANCODE_KP_XOR,
+ SCANCODE_KP_POWER,
+ SCANCODE_KP_PERCENT,
+ SCANCODE_KP_LESS,
+ SCANCODE_KP_GREATER,
+ SCANCODE_KP_AMPERSAND,
+ SCANCODE_KP_DBLAMPERSAND,
+ SCANCODE_KP_VERTICALBAR,
+ SCANCODE_KP_DBLVERTICALBAR,
+ SCANCODE_KP_COLON,
+ SCANCODE_KP_HASH,
+ SCANCODE_KP_SPACE,
+ SCANCODE_KP_AT,
+ SCANCODE_KP_EXCLAM,
+ SCANCODE_KP_MEMSTORE,
+ SCANCODE_KP_MEMRECALL,
+ SCANCODE_KP_MEMCLEAR,
+ SCANCODE_KP_MEMADD,
+ SCANCODE_KP_MEMSUBTRACT,
+ SCANCODE_KP_MEMMULTIPLY,
+ SCANCODE_KP_MEMDIVIDE,
+ SCANCODE_KP_PLUSMINUS,
+ SCANCODE_KP_CLEAR,
+ SCANCODE_KP_CLEARENTRY,
+ SCANCODE_KP_BINARY,
+ SCANCODE_KP_OCTAL,
+ SCANCODE_KP_DECIMAL,
+ SCANCODE_KP_HEXADECIMAL,
+
+ SCANCODE_LCTRL,
+ SCANCODE_LSHIFT,
+ SCANCODE_LALT,
+ SCANCODE_LGUI,
+ SCANCODE_RCTRL,
+ SCANCODE_RSHIFT,
+ SCANCODE_RALT,
+ SCANCODE_RGUI,
+
+ SCANCODE_MODE,
+
+ SCANCODE_AUDIONEXT,
+ SCANCODE_AUDIOPREV,
+ SCANCODE_AUDIOSTOP,
+ SCANCODE_AUDIOPLAY,
+ SCANCODE_AUDIOMUTE,
+ SCANCODE_MEDIASELECT,
+ SCANCODE_WWW,
+ SCANCODE_MAIL,
+ SCANCODE_CALCULATOR,
+ SCANCODE_COMPUTER,
+ SCANCODE_AC_SEARCH,
+ SCANCODE_AC_HOME,
+ SCANCODE_AC_BACK,
+ SCANCODE_AC_FORWARD,
+ SCANCODE_AC_STOP,
+ SCANCODE_AC_REFRESH,
+ SCANCODE_AC_BOOKMARKS,
+
+ SCANCODE_BRIGHTNESSDOWN,
+ SCANCODE_BRIGHTNESSUP,
+ SCANCODE_DISPLAYSWITCH,
+ SCANCODE_KBDILLUMTOGGLE,
+ SCANCODE_KBDILLUMDOWN,
+ SCANCODE_KBDILLUMUP,
+ SCANCODE_EJECT,
+ SCANCODE_SLEEP,
+
+ SCANCODE_APP1,
+ SCANCODE_APP2,
+
+ SCANCODE_MAX_ENUM
+};
diff --git a/Source/Asura.Engine/Input/Keyboard.h b/Source/Asura.Engine/Input/Keyboard.h
index e69de29..488209b 100644
--- a/Source/Asura.Engine/Input/Keyboard.h
+++ b/Source/Asura.Engine/Input/Keyboard.h
@@ -0,0 +1,73 @@
+#ifndef __ASURA_INPUT_KEYBOARD_H__
+#define __ASURA_INPUT_KEYBOARD_H__
+
+#include <SDL2/SDL.h>
+
+#include "InputDevice.hpp"
+#include "Scripting/Portable.h"
+
+namespace AsuraEngine
+{
+ namespace Input
+ {
+
+ class Keyboard ASURA_FINAL : public InputDevice<Keyboard>
+ {
+ public:
+
+ // صö
+ #include "Keyboard.defs"
+
+ Keyboard();
+
+ void SetKeyRepeat(bool enable);
+ bool HasKeyRepeat() const;
+ bool IsDown(const std::vector<Key> &keylist) const;
+ bool IsScancodeDown(const std::vector<Scancode> &scancodelist) const;
+
+ Key GetKeyFromScancode(Scancode scancode) const;
+ Scancode GetScancodeFromKey(Key key) const;
+
+ void SetTextInput(bool enable);
+ void SetTextInput(bool enable, double x, double y, double w, double h);
+ bool HasTextInput() const;
+ bool HasScreenKeyboard() const;
+
+ bool GetConstant(Scancode in, SDL_Scancode &out);
+ bool GetConstant(SDL_Scancode in, Scancode &out);
+
+ private:
+
+ ~Keyboard();
+
+ public:
+
+ //----------------------------------------------------------------------------------------------------------
+
+ LUAX_DECL_SINGLETON(Keyboard); // ͨAsuraEngine.KeyboardֱӷʣûNew
+
+ LUAX_DECL_ENUM(Key);
+ LUAX_DECL_ENUM(ScanCode);
+
+ LUAX_DECL_METHOD(SetKeyRepeat);
+ LUAX_DECL_METHOD(HasKeyRepeat);
+ LUAX_DECL_METHOD(IsDown);
+ LUAX_DECL_METHOD(IsScancodeDown);
+
+ LUAX_DECL_METHOD(GetKeyFromScancode);
+ LUAX_DECL_METHOD(GetScancodeFromKey);
+
+ LUAX_DECL_METHOD(SetTextInput);
+ LUAX_DECL_METHOD(HasTextInput);
+ LUAX_DECL_METHOD(HasScreenKeyboard);
+
+ LUAX_DECL_METHOD(GetConstant);
+
+ //----------------------------------------------------------------------------------------------------------
+
+ };
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/Font/TrueTypeFont.h b/Source/Asura.Engine/Input/Mouse.cpp
index e69de29..e69de29 100644
--- a/Source/Asura.Engine/Font/TrueTypeFont.h
+++ b/Source/Asura.Engine/Input/Mouse.cpp
diff --git a/Source/Asura.Engine/Input/Mouse.h b/Source/Asura.Engine/Input/Mouse.h
new file mode 100644
index 0000000..0f34fdd
--- /dev/null
+++ b/Source/Asura.Engine/Input/Mouse.h
@@ -0,0 +1,56 @@
+#ifndef __ASURA_ENGINE_MOUSE_H__
+#define __ASURA_ENGINE_MOUSE_H__
+
+#include "Cursor.h"
+#include "InputDevice.hpp"
+
+namespace AsuraEngine
+{
+ namespace Input
+ {
+
+ class Mouse : public InputDevice<Mouse>
+ {
+ public:
+
+ ///
+ /// ͼƬйָʹϵͳָ
+ ///
+ Cursor *CreateCursor(Graphics::ImageData *data, int hotx, int hoty);
+ Cursor *GetSystemCursor(Cursor::SystemCursor cursortype);
+
+ void SetCursor(Cursor *cursor);
+ void SetCursor() ;
+
+ Cursor* GetCursor() const;
+
+ bool IsCursorSupported() const;
+
+ double GetX() const;
+ double GetY() const;
+ void GetPosition(double &x, double &y) const;
+ void GetX(double x) ;
+ void SetY(double y) ;
+ void SetPosition(double x, double y) ;
+ void SetVisible(bool visible) ;
+ bool IsDown(const std::vector<int> &buttons) const;
+ bool IsVisible() const;
+ void SetGrabbed(bool grab) ;
+ bool IsGrabbed() const;
+ bool SetRelativeMode(bool relative) ;
+ bool GetRelativeMode() const;
+
+ //----------------------------------------------------------------------------------------------------------
+
+ LUAX_DECL_SINGLETON(Mouse);
+
+ //----------------------------------------------------------------------------------------------------------
+
+ private:
+
+ };
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/Math/Transform.h b/Source/Asura.Engine/Math/Transform.h
index aafb66c..33c3d4b 100644
--- a/Source/Asura.Engine/Math/Transform.h
+++ b/Source/Asura.Engine/Math/Transform.h
@@ -1,14 +1,14 @@
#ifndef __ASURA_ENGINE_TRANSFORM_H__
#define __ASURA_ENGINE_TRANSFORM_H__
-#include "Object.h"
+#include "Scripting/Portable.h"
namespace AsuraEngine
{
namespace Math
{
- class Transform : virtual public Object
+ class Transform
{
public:
diff --git a/Source/Asura.Engine/Object.cpp b/Source/Asura.Engine/Object.cpp
deleted file mode 100644
index 9ecd825..0000000
--- a/Source/Asura.Engine/Object.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "Object.h"
-
-namespace AsuraEngine
-{
-
- Object::Object()
- : mRC(0)
- {
-
- }
-
- void Object::Retain(Object* obj)
- {
- if (!obj)
- return;
- ++obj->mRC;
- }
-
- void Object::Release(Object* obj)
- {
- if (!obj)
- return;
- if (--obj->mRC == 0)
- delete obj;
- }
-
-} \ No newline at end of file
diff --git a/Source/Asura.Engine/Object.h b/Source/Asura.Engine/Object.h
deleted file mode 100644
index 352a61b..0000000
--- a/Source/Asura.Engine/Object.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __ASURA_ENGINE_OBJECT_H__
-#define __ASURA_ENGINE_OBJECT_H__
-
-#include "Type.h"
-
-///
-/// 룬ʵҪüеļصĶluaɡObjectֻΪʹá
-/// //ࡣΪ˱֤nativeͷŵʱ򲻻ᵼԼָ뱻ͷţҪһülua
-/// //ͷʱǷͷnativenativeָ롣
-/// //Object࣬ǴڶϵģӦͨObject::Releaseֶͷš
-/// Objectָ뱾Ϊlight userdataΪweak tablekeyobjectsʹַһЩͳơ
-///
-class Object
-{
-public:
-
- Object();
-
- virtual ~Object();
-
- static void Retain(Object* obj);
-
- static void Release(Object* obj);
-
- void Retain();
- void Release();
-
-private:
-
- unsigned int mRC; // ü
-
-};
-
-#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/Scripting/Luax.hpp b/Source/Asura.Engine/Scripting/Luax.hpp
index e1407ee..2bb1160 100644
--- a/Source/Asura.Engine/Scripting/Luax.hpp
+++ b/Source/Asura.Engine/Scripting/Luax.hpp
@@ -4,8 +4,10 @@
///
/// Scripting with Lua.
///
+extern "C" {
#include "Lua51/lua.h"
#include "Lua51/lauxlib.h"
+}
#include "Luax/luax.h"
///
diff --git a/Source/Asura.Engine/Scripting/Portable.cpp b/Source/Asura.Engine/Scripting/Portable.cpp
new file mode 100644
index 0000000..0aa5f08
--- /dev/null
+++ b/Source/Asura.Engine/Scripting/Portable.cpp
@@ -0,0 +1,9 @@
+#include "Portable.h"
+
+namespace AsuraEngine
+{
+ namespace Scripting
+ {
+
+ }
+}
diff --git a/Source/Asura.Engine/Scripting/Portable.h b/Source/Asura.Engine/Scripting/Portable.h
index ae36cc2..c188378 100644
--- a/Source/Asura.Engine/Scripting/Portable.h
+++ b/Source/Asura.Engine/Scripting/Portable.h
@@ -1,21 +1,16 @@
#ifndef __ASURA_ENGINE_PORTABLE_H__
#define __ASURA_ENGINE_PORTABLE_H__
-#include "Object.h"
+#include "Luax.hpp"
+#include "Config.h"
+#include "Type.h"
namespace AsuraEngine
{
namespace Scripting
{
- class Portable : virtual public Object
- {
- public:
-
- Portable();
- virtual ~Portable();
-
- };
+ using Portable = Luax::LuaxClass;
}
}
diff --git a/Source/Asura.Engine/Scripting/Type.h b/Source/Asura.Engine/Scripting/Type.h
new file mode 100644
index 0000000..0665810
--- /dev/null
+++ b/Source/Asura.Engine/Scripting/Type.h
@@ -0,0 +1,17 @@
+#ifndef __ASURA_SCRIPTING_TYPE_H__
+#define __ASURA_SCRIPTING_TYPE_H__
+
+namespace AsuraEngine
+{
+ namespace Scripting
+ {
+
+ class Type
+ {
+
+ };
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/Singleton.hpp b/Source/Asura.Engine/Singleton.hpp
new file mode 100644
index 0000000..756209a
--- /dev/null
+++ b/Source/Asura.Engine/Singleton.hpp
@@ -0,0 +1,59 @@
+#ifndef __ASURA_SINGLETON_H__
+#define __ASURA_SINGLETON_H__
+
+#include "Config.h"
+
+namespace AsuraEngine
+{
+
+ ///
+ /// ̳Singletonڵһʵʱʵ֮ٴʵᱨ
+ ///
+ template<class T>
+ 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<T*>(this);
+ };
+
+ virtual ~Singleton() {};
+
+ static T* instance;
+
+ private:
+
+ Singleton(const Singleton& singleton);
+
+ Singleton& operator = (const Singleton& singleton);
+
+ };
+
+ // ʵʼΪ
+ template<class T>
+ T* Singleton<T>::instance = nullptr;
+
+}
+
+#endif // __ASURA_SINGLETON_H__ \ No newline at end of file
diff --git a/Source/Asura.Engine/StringMap.hpp b/Source/Asura.Engine/StringMap.hpp
index 971a890..ddba128 100644
--- a/Source/Asura.Engine/StringMap.hpp
+++ b/Source/Asura.Engine/StringMap.hpp
@@ -1,7 +1,7 @@
#ifndef __ASURA_ENGINE_STRINGMAP_H__
#define __ASURA_ENGINE_STRINGMAP_H__
-#include "String.h"
+#include <string>
namespace AsuraEngine
{
@@ -18,7 +18,7 @@ namespace AsuraEngine
bool ContainsString(const String& str);
- String GetStringByKey(const key_type& key);
+ std::string GetStringByKey(const key_type& key);
key_type GetKeyByString(const String& str);
diff --git a/Source/Asura.Engine/Text/Glyph.cpp b/Source/Asura.Engine/Text/Glyph.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/Asura.Engine/Text/Glyph.cpp
diff --git a/Source/Asura.Engine/Text/Glyph.h b/Source/Asura.Engine/Text/Glyph.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/Asura.Engine/Text/Glyph.h
diff --git a/Source/Asura.Engine/Text/String.cpp b/Source/Asura.Engine/Text/String.cpp
new file mode 100644
index 0000000..8c9c55a
--- /dev/null
+++ b/Source/Asura.Engine/Text/String.cpp
@@ -0,0 +1,376 @@
+#include "String.hpp"
+#include "Utf.hpp"
+
+namespace AsuraEngine
+{
+ namespace Text
+ {
+
+
+ ////////////////////////////////////////////////////////////
+ const std::size_t String::InvalidPos = std::basic_string<uint32>::npos;
+
+
+ ////////////////////////////////////////////////////////////
+ String::String()
+ {
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(char ansiChar, const std::locale& locale)
+ {
+ mString += Utf32::DecodeAnsi(ansiChar, locale);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(wchar_t wideChar)
+ {
+ mString += Utf32::DecodeWide(wideChar);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(uint32 utf32Char)
+ {
+ mString += utf32Char;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(const char* ansiString, const std::locale& locale)
+ {
+ if (ansiString)
+ {
+ std::size_t length = strlen(ansiString);
+ if (length > 0)
+ {
+ mString.reserve(length + 1);
+ Utf32::FromAnsi(ansiString, ansiString + length, std::back_inserter(mString), locale);
+ }
+ }
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(const std::string& ansiString, const std::locale& locale)
+ {
+ mString.reserve(ansiString.length() + 1);
+ Utf32::FromAnsi(ansiString.begin(), ansiString.end(), std::back_inserter(mString), locale);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(const wchar_t* wideString)
+ {
+ if (wideString)
+ {
+ std::size_t length = std::wcslen(wideString);
+ if (length > 0)
+ {
+ mString.reserve(length + 1);
+ Utf32::FromWide(wideString, wideString + length, std::back_inserter(mString));
+ }
+ }
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(const std::wstring& wideString)
+ {
+ mString.reserve(wideString.length() + 1);
+ Utf32::FromWide(wideString.begin(), wideString.end(), std::back_inserter(mString));
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(const uint32* utf32String)
+ {
+ if (utf32String)
+ mString = utf32String;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(const std::basic_string<uint32>& utf32String) :
+ mString(utf32String)
+ {
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::String(const String& copy) :
+ mString(copy.mString)
+ {
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::operator std::string() const
+ {
+ return ToAnsiString();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::operator std::wstring() const
+ {
+ return ToWideString();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ std::string String::ToAnsiString(const std::locale& locale) const
+ {
+ // Prepare the output string
+ std::string output;
+ output.reserve(mString.length() + 1);
+
+ // Convert
+ Utf32::ToAnsi(mString.begin(), mString.end(), std::back_inserter(output), 0, locale);
+
+ return output;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ std::wstring String::ToWideString() const
+ {
+ // Prepare the output string
+ std::wstring output;
+ output.reserve(mString.length() + 1);
+
+ // Convert
+ Utf32::ToWide(mString.begin(), mString.end(), std::back_inserter(output), 0);
+
+ return output;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ std::basic_string<uint8> String::ToUtf8() const
+ {
+ // Prepare the output string
+ std::basic_string<uint8> output;
+ output.reserve(mString.length());
+
+ // Convert
+ Utf32::ToUtf8(mString.begin(), mString.end(), std::back_inserter(output));
+
+ return output;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ std::basic_string<uint16> String::ToUtf16() const
+ {
+ // Prepare the output string
+ std::basic_string<uint16> output;
+ output.reserve(mString.length());
+
+ // Convert
+ Utf32::ToUtf16(mString.begin(), mString.end(), std::back_inserter(output));
+
+ return output;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ std::basic_string<uint32> String::ToUtf32() const
+ {
+ return mString;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String& String::operator =(const String& right)
+ {
+ mString = right.mString;
+ return *this;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String& String::operator +=(const String& right)
+ {
+ mString += right.mString;
+ return *this;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ uint32 String::operator [](std::size_t index) const
+ {
+ return mString[index];
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ uint32& String::operator [](std::size_t index)
+ {
+ return mString[index];
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ void String::Clear()
+ {
+ mString.clear();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ std::size_t String::GetSize() const
+ {
+ return mString.size();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ bool String::IsEmpty() const
+ {
+ return mString.empty();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ void String::Erase(std::size_t position, std::size_t count)
+ {
+ mString.erase(position, count);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ void String::Insert(std::size_t position, const String& str)
+ {
+ mString.insert(position, str.mString);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ std::size_t String::Find(const String& str, std::size_t start) const
+ {
+ return mString.find(str.mString, start);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ void String::Replace(std::size_t position, std::size_t length, const String& replaceWith)
+ {
+ mString.replace(position, length, replaceWith.mString);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ void String::Replace(const String& searchFor, const String& replaceWith)
+ {
+ std::size_t step = replaceWith.GetSize();
+ std::size_t len = searchFor.GetSize();
+ std::size_t pos = Find(searchFor);
+
+ // Replace each occurrence of search
+ while (pos != InvalidPos)
+ {
+ Replace(pos, len, replaceWith);
+ pos = Find(searchFor, pos + step);
+ }
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String String::Substring(std::size_t position, std::size_t length) const
+ {
+ return mString.substr(position, length);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ const uint32* String::GetData() const
+ {
+ return mString.c_str();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::Iterator String::Begin()
+ {
+ return mString.begin();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::ConstIterator String::Begin() const
+ {
+ return mString.begin();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::Iterator String::End()
+ {
+ return mString.end();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String::ConstIterator String::End() const
+ {
+ return mString.end();
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ bool operator ==(const String& left, const String& right)
+ {
+ return left.mString == right.mString;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ bool operator !=(const String& left, const String& right)
+ {
+ return !(left == right);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ bool operator <(const String& left, const String& right)
+ {
+ return left.mString < right.mString;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ bool operator >(const String& left, const String& right)
+ {
+ return right < left;
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ bool operator <=(const String& left, const String& right)
+ {
+ return !(right < left);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ bool operator >=(const String& left, const String& right)
+ {
+ return !(left < right);
+ }
+
+
+ ////////////////////////////////////////////////////////////
+ String operator +(const String& left, const String& right)
+ {
+ String string = left;
+ string += right;
+
+ return string;
+ }
+
+
+ }
+}
diff --git a/Source/Asura.Engine/Text/String.hpp b/Source/Asura.Engine/Text/String.hpp
new file mode 100644
index 0000000..226735b
--- /dev/null
+++ b/Source/Asura.Engine/Text/String.hpp
@@ -0,0 +1,594 @@
+#ifndef __ASURA_ENGINE_STRING_H__
+#define __ASURA_ENGINE_STRING_H__
+
+#include "Config.h"
+#include <iterator>
+#include <locale>
+#include <string>
+
+namespace AsuraEngine
+{
+ namespace Text
+ {
+
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Utility string class that automatically handles
+ /// conversions between types and encodings
+ ///
+ ////////////////////////////////////////////////////////////
+ class String
+ {
+ public:
+
+ ////////////////////////////////////////////////////////////
+ // Types
+ ////////////////////////////////////////////////////////////
+ typedef std::basic_string<uint32>::iterator Iterator; ///< Iterator type
+ typedef std::basic_string<uint32>::const_iterator ConstIterator; ///< Read-only iterator type
+
+ ////////////////////////////////////////////////////////////
+ // Static member data
+ ////////////////////////////////////////////////////////////
+ static const std::size_t InvalidPos; ///< Represents an invalid position in the string
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Default constructor
+ ///
+ /// This constructor creates an empty string.
+ ///
+ ////////////////////////////////////////////////////////////
+ String();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct from a single ANSI character and a locale
+ ///
+ /// The source character is converted to UTF-32 according
+ /// to the given locale.
+ ///
+ /// \param ansiChar ANSI character to convert
+ /// \param locale Locale to use for conversion
+ ///
+ ////////////////////////////////////////////////////////////
+ String(char ansiChar, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct from single wide character
+ ///
+ /// \param wideChar Wide character to convert
+ ///
+ ////////////////////////////////////////////////////////////
+ String(wchar_t wideChar);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct from single UTF-32 character
+ ///
+ /// \param utf32Char UTF-32 character to convert
+ ///
+ ////////////////////////////////////////////////////////////
+ String(uint utf32Char);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct from a null-terminated C-style ANSI string and a locale
+ ///
+ /// The source string is converted to UTF-32 according
+ /// to the given locale.
+ ///
+ /// \param ansiString ANSI string to convert
+ /// \param locale Locale to use for conversion
+ ///
+ ////////////////////////////////////////////////////////////
+ String(const char* ansiString, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct from an ANSI string and a locale
+ ///
+ /// The source string is converted to UTF-32 according
+ /// to the given locale.
+ ///
+ /// \param ansiString ANSI string to convert
+ /// \param locale Locale to use for conversion
+ ///
+ ////////////////////////////////////////////////////////////
+ String(const std::string& ansiString, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct from null-terminated C-style wide string
+ ///
+ /// \param wideString Wide string to convert
+ ///
+ ////////////////////////////////////////////////////////////
+ String(const wchar_t* wideString);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct from a wide string
+ ///
+ /// \param wideString Wide string to convert
+ ///
+ ////////////////////////////////////////////////////////////
+ String(const std::wstring& wideString);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct from a null-terminated C-style UTF-32 string
+ ///
+ /// \param utf32String UTF-32 string to assign
+ ///
+ ////////////////////////////////////////////////////////////
+ String(const uint* utf32String);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct from an UTF-32 string
+ ///
+ /// \param utf32String UTF-32 string to assign
+ ///
+ ////////////////////////////////////////////////////////////
+ String(const std::basic_string<uint>& utf32String);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Copy constructor
+ ///
+ /// \param copy Instance to copy
+ ///
+ ////////////////////////////////////////////////////////////
+ String(const String& copy);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create a new sf::String from a UTF-8 encoded string
+ ///
+ /// \param begin Forward iterator to the beginning of the UTF-8 sequence
+ /// \param end Forward iterator to the end of the UTF-8 sequence
+ ///
+ /// \return A sf::String containing the source string
+ ///
+ /// \see fromUtf16, fromUtf32
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename T>
+ static String FromUtf8(T begin, T end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create a new sf::String from a UTF-16 encoded string
+ ///
+ /// \param begin Forward iterator to the beginning of the UTF-16 sequence
+ /// \param end Forward iterator to the end of the UTF-16 sequence
+ ///
+ /// \return A sf::String containing the source string
+ ///
+ /// \see fromUtf8, fromUtf32
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename T>
+ static String FromUtf16(T begin, T end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create a new sf::String from a UTF-32 encoded string
+ ///
+ /// This function is provided for consistency, it is equivalent to
+ /// using the constructors that takes a const sf::uint* or
+ /// a std::basic_string<sf::uint>.
+ ///
+ /// \param begin Forward iterator to the beginning of the UTF-32 sequence
+ /// \param end Forward iterator to the end of the UTF-32 sequence
+ ///
+ /// \return A sf::String containing the source string
+ ///
+ /// \see fromUtf8, fromUtf16
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename T>
+ static String FromUtf32(T begin, T end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Implicit conversion operator to std::string (ANSI string)
+ ///
+ /// The current global locale is used for conversion. If you
+ /// want to explicitly specify a locale, see toAnsiString.
+ /// Characters that do not fit in the target encoding are
+ /// discarded from the returned string.
+ /// This operator is defined for convenience, and is equivalent
+ /// to calling toAnsiString().
+ ///
+ /// \return Converted ANSI string
+ ///
+ /// \see toAnsiString, operator std::wstring
+ ///
+ ////////////////////////////////////////////////////////////
+ operator std::string() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Implicit conversion operator to std::wstring (wide string)
+ ///
+ /// Characters that do not fit in the target encoding are
+ /// discarded from the returned string.
+ /// This operator is defined for convenience, and is equivalent
+ /// to calling toWideString().
+ ///
+ /// \return Converted wide string
+ ///
+ /// \see toWideString, operator std::string
+ ///
+ ////////////////////////////////////////////////////////////
+ operator std::wstring() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert the Unicode string to an ANSI string
+ ///
+ /// The UTF-32 string is converted to an ANSI string in
+ /// the encoding defined by \a locale.
+ /// Characters that do not fit in the target encoding are
+ /// discarded from the returned string.
+ ///
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Converted ANSI string
+ ///
+ /// \see toWideString, operator std::string
+ ///
+ ////////////////////////////////////////////////////////////
+ std::string ToAnsiString(const std::locale& locale = std::locale()) const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert the Unicode string to a wide string
+ ///
+ /// Characters that do not fit in the target encoding are
+ /// discarded from the returned string.
+ ///
+ /// \return Converted wide string
+ ///
+ /// \see toAnsiString, operator std::wstring
+ ///
+ ////////////////////////////////////////////////////////////
+ std::wstring ToWideString() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert the Unicode string to a UTF-8 string
+ ///
+ /// \return Converted UTF-8 string
+ ///
+ /// \see toUtf16, toUtf32
+ ///
+ ////////////////////////////////////////////////////////////
+ std::basic_string<uint8> ToUtf8() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert the Unicode string to a UTF-16 string
+ ///
+ /// \return Converted UTF-16 string
+ ///
+ /// \see toUtf8, toUtf32
+ ///
+ ////////////////////////////////////////////////////////////
+ std::basic_string<uint16> ToUtf16() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert the Unicode string to a UTF-32 string
+ ///
+ /// This function doesn't perform any conversion, since the
+ /// string is already stored as UTF-32 internally.
+ ///
+ /// \return Converted UTF-32 string
+ ///
+ /// \see toUtf8, toUtf16
+ ///
+ ////////////////////////////////////////////////////////////
+ std::basic_string<uint> ToUtf32() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Overload of assignment operator
+ ///
+ /// \param right Instance to assign
+ ///
+ /// \return Reference to self
+ ///
+ ////////////////////////////////////////////////////////////
+ String& operator =(const String& right);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Overload of += operator to append an UTF-32 string
+ ///
+ /// \param right String to append
+ ///
+ /// \return Reference to self
+ ///
+ ////////////////////////////////////////////////////////////
+ String& operator +=(const String& right);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Overload of [] operator to access a character by its position
+ ///
+ /// This function provides read-only access to characters.
+ /// Note: the behavior is undefined if \a index is out of range.
+ ///
+ /// \param index Index of the character to get
+ ///
+ /// \return Character at position \a index
+ ///
+ ////////////////////////////////////////////////////////////
+ uint operator [](std::size_t index) const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Overload of [] operator to access a character by its position
+ ///
+ /// This function provides read and write access to characters.
+ /// Note: the behavior is undefined if \a index is out of range.
+ ///
+ /// \param index Index of the character to get
+ ///
+ /// \return Reference to the character at position \a index
+ ///
+ ////////////////////////////////////////////////////////////
+ uint& operator [](std::size_t index);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Clear the string
+ ///
+ /// This function removes all the characters from the string.
+ ///
+ /// \see isEmpty, erase
+ ///
+ ////////////////////////////////////////////////////////////
+ void Clear();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Get the size of the string
+ ///
+ /// \return Number of characters in the string
+ ///
+ /// \see isEmpty
+ ///
+ ////////////////////////////////////////////////////////////
+ std::size_t GetSize() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Check whether the string is empty or not
+ ///
+ /// \return True if the string is empty (i.e. contains no character)
+ ///
+ /// \see clear, getSize
+ ///
+ ////////////////////////////////////////////////////////////
+ bool IsEmpty() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Erase one or more characters from the string
+ ///
+ /// This function removes a sequence of \a count characters
+ /// starting from \a position.
+ ///
+ /// \param position Position of the first character to erase
+ /// \param count Number of characters to erase
+ ///
+ ////////////////////////////////////////////////////////////
+ void Erase(std::size_t position, std::size_t count = 1);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Insert one or more characters into the string
+ ///
+ /// This function inserts the characters of \a str
+ /// into the string, starting from \a position.
+ ///
+ /// \param position Position of insertion
+ /// \param str Characters to insert
+ ///
+ ////////////////////////////////////////////////////////////
+ void Insert(std::size_t position, const String& str);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Find a sequence of one or more characters in the string
+ ///
+ /// This function searches for the characters of \a str
+ /// in the string, starting from \a start.
+ ///
+ /// \param str Characters to find
+ /// \param start Where to begin searching
+ ///
+ /// \return Position of \a str in the string, or String::InvalidPos if not found
+ ///
+ ////////////////////////////////////////////////////////////
+ std::size_t Find(const String& str, std::size_t start = 0) const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Replace a substring with another string
+ ///
+ /// This function replaces the substring that starts at index \a position
+ /// and spans \a length characters with the string \a replaceWith.
+ ///
+ /// \param position Index of the first character to be replaced
+ /// \param length Number of characters to replace. You can pass InvalidPos to
+ /// replace all characters until the end of the string.
+ /// \param replaceWith String that replaces the given substring.
+ ///
+ ////////////////////////////////////////////////////////////
+ void Replace(std::size_t position, std::size_t length, const String& replaceWith);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Replace all occurrences of a substring with a replacement string
+ ///
+ /// This function replaces all occurrences of \a searchFor in this string
+ /// with the string \a replaceWith.
+ ///
+ /// \param searchFor The value being searched for
+ /// \param replaceWith The value that replaces found \a searchFor values
+ ///
+ ////////////////////////////////////////////////////////////
+ void Replace(const String& searchFor, const String& replaceWith);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Return a part of the string
+ ///
+ /// This function returns the substring that starts at index \a position
+ /// and spans \a length characters.
+ ///
+ /// \param position Index of the first character
+ /// \param length Number of characters to include in the substring (if
+ /// the string is shorter, as many characters as possible
+ /// are included). \ref InvalidPos can be used to include all
+ /// characters until the end of the string.
+ ///
+ /// \return String object containing a substring of this object
+ ///
+ ////////////////////////////////////////////////////////////
+ String Substring(std::size_t position, std::size_t length = InvalidPos) const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Get a pointer to the C-style array of characters
+ ///
+ /// This functions provides a read-only access to a
+ /// null-terminated C-style representation of the string.
+ /// The returned pointer is temporary and is meant only for
+ /// immediate use, thus it is not recommended to store it.
+ ///
+ /// \return Read-only pointer to the array of characters
+ ///
+ ////////////////////////////////////////////////////////////
+ const uint* GetData() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Return an iterator to the beginning of the string
+ ///
+ /// \return Read-write iterator to the beginning of the string characters
+ ///
+ /// \see end
+ ///
+ ////////////////////////////////////////////////////////////
+ Iterator Begin();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Return an iterator to the beginning of the string
+ ///
+ /// \return Read-only iterator to the beginning of the string characters
+ ///
+ /// \see end
+ ///
+ ////////////////////////////////////////////////////////////
+ ConstIterator Begin() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Return an iterator to the end of the string
+ ///
+ /// The end iterator refers to 1 position past the last character;
+ /// thus it represents an invalid character and should never be
+ /// accessed.
+ ///
+ /// \return Read-write iterator to the end of the string characters
+ ///
+ /// \see begin
+ ///
+ ////////////////////////////////////////////////////////////
+ Iterator End();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Return an iterator to the end of the string
+ ///
+ /// The end iterator refers to 1 position past the last character;
+ /// thus it represents an invalid character and should never be
+ /// accessed.
+ ///
+ /// \return Read-only iterator to the end of the string characters
+ ///
+ /// \see begin
+ ///
+ ////////////////////////////////////////////////////////////
+ ConstIterator End() const;
+
+ private:
+
+ friend bool operator ==(const String& left, const String& right);
+ friend bool operator <(const String& left, const String& right);
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ std::basic_string<uint> mString; ///< Internal string of UTF-32 characters
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// \relates String
+ /// \brief Overload of == operator to compare two UTF-32 strings
+ ///
+ /// \param left Left operand (a string)
+ /// \param right Right operand (a string)
+ ///
+ /// \return True if both strings are equal
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator ==(const String& left, const String& right);
+
+ ////////////////////////////////////////////////////////////
+ /// \relates String
+ /// \brief Overload of != operator to compare two UTF-32 strings
+ ///
+ /// \param left Left operand (a string)
+ /// \param right Right operand (a string)
+ ///
+ /// \return True if both strings are different
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator !=(const String& left, const String& right);
+
+ ////////////////////////////////////////////////////////////
+ /// \relates String
+ /// \brief Overload of < operator to compare two UTF-32 strings
+ ///
+ /// \param left Left operand (a string)
+ /// \param right Right operand (a string)
+ ///
+ /// \return True if \a left is lexicographically before \a right
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <(const String& left, const String& right);
+
+ ////////////////////////////////////////////////////////////
+ /// \relates String
+ /// \brief Overload of > operator to compare two UTF-32 strings
+ ///
+ /// \param left Left operand (a string)
+ /// \param right Right operand (a string)
+ ///
+ /// \return True if \a left is lexicographically after \a right
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator >(const String& left, const String& right);
+
+ ////////////////////////////////////////////////////////////
+ /// \relates String
+ /// \brief Overload of <= operator to compare two UTF-32 strings
+ ///
+ /// \param left Left operand (a string)
+ /// \param right Right operand (a string)
+ ///
+ /// \return True if \a left is lexicographically before or equivalent to \a right
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <=(const String& left, const String& right);
+
+ ////////////////////////////////////////////////////////////
+ /// \relates String
+ /// \brief Overload of >= operator to compare two UTF-32 strings
+ ///
+ /// \param left Left operand (a string)
+ /// \param right Right operand (a string)
+ ///
+ /// \return True if \a left is lexicographically after or equivalent to \a right
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator >=(const String& left, const String& right);
+
+ ////////////////////////////////////////////////////////////
+ /// \relates String
+ /// \brief Overload of binary + operator to concatenate two strings
+ ///
+ /// \param left Left operand (a string)
+ /// \param right Right operand (a string)
+ ///
+ /// \return Concatenated string
+ ///
+ ////////////////////////////////////////////////////////////
+ String operator +(const String& left, const String& right);
+
+ #include "String.inl"
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/Source/Asura.Engine/Text/String.inl b/Source/Asura.Engine/Text/String.inl
new file mode 100644
index 0000000..ef18228
--- /dev/null
+++ b/Source/Asura.Engine/Text/String.inl
@@ -0,0 +1,29 @@
+
+////////////////////////////////////////////////////////////
+template <typename T>
+String String::fromUtf8(T begin, T end)
+{
+ String string;
+ Utf8::toUtf32(begin, end, std::back_inserter(string.m_string));
+ return string;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename T>
+String String::fromUtf16(T begin, T end)
+{
+ String string;
+ Utf16::toUtf32(begin, end, std::back_inserter(string.m_string));
+ return string;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename T>
+String String::fromUtf32(T begin, T end)
+{
+ String string;
+ string.m_string.assign(begin, end);
+ return string;
+}
diff --git a/Source/Asura.Engine/Text/TrueTypeFont.cpp b/Source/Asura.Engine/Text/TrueTypeFont.cpp
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/Asura.Engine/Text/TrueTypeFont.cpp
diff --git a/Source/Asura.Engine/Text/TrueTypeFont.h b/Source/Asura.Engine/Text/TrueTypeFont.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Source/Asura.Engine/Text/TrueTypeFont.h
diff --git a/Source/Asura.Engine/Text/Utf.hpp b/Source/Asura.Engine/Text/Utf.hpp
new file mode 100644
index 0000000..2e04ee4
--- /dev/null
+++ b/Source/Asura.Engine/Text/Utf.hpp
@@ -0,0 +1,720 @@
+#ifndef __ASURA_UTF_HPP__
+#define __ASURA_UTF_HPP__
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <algorithm>
+#include <locale>
+#include <string>
+#include <cstdlib>
+
+namespace AsuraEngine
+{
+ namespace Text
+ {
+
+ template <unsigned int N>
+ class Utf;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Specialization of the Utf template for UTF-8
+ ///
+ ////////////////////////////////////////////////////////////
+ template <>
+ class Utf<8>
+ {
+ public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single UTF-8 character
+ ///
+ /// Decoding a character means finding its unique 32-bits
+ /// code (called the codepoint) in the Unicode standard.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Codepoint of the decoded UTF-8 character
+ /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-8 character
+ ///
+ /// Encoding a character means converting a unique 32-bits
+ /// code (called the codepoint) in the target encoding, UTF-8.
+ ///
+ /// \param input Codepoint to encode as UTF-8
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to UTF-8 (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out Encode(Uint32 input, Out output, Uint8 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Advance to the next UTF-8 character
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Next(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Count the number of characters of a UTF-8 sequence
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element, thus the
+ /// total size can be different from (begin - end).
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static std::size_t Count(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an ANSI characters range to UTF-8
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a wide characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromWide(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromLatin1(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-8 characters range to ANSI characters
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-8 characters range to wide characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-8 characters range to latin-1 (ISO-5589-1) characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToLatin1(In begin, In end, Out output, char replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-8 characters range to UTF-8
+ ///
+ /// This functions does nothing more than a direct copy;
+ /// it is defined only to provide the same interface as other
+ /// specializations of the sf::Utf<> template, and allow
+ /// generic code to be written on top of it.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf8(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-8 characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf16(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-8 characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf32(In begin, In end, Out output);
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Specialization of the Utf template for UTF-16
+ ///
+ ////////////////////////////////////////////////////////////
+ template <>
+ class Utf<16>
+ {
+ public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single UTF-16 character
+ ///
+ /// Decoding a character means finding its unique 32-bits
+ /// code (called the codepoint) in the Unicode standard.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Codepoint of the decoded UTF-16 character
+ /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-16 character
+ ///
+ /// Encoding a character means converting a unique 32-bits
+ /// code (called the codepoint) in the target encoding, UTF-16.
+ ///
+ /// \param input Codepoint to encode as UTF-16
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to UTF-16 (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out Encode(Uint32 input, Out output, Uint16 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Advance to the next UTF-16 character
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Next(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Count the number of characters of a UTF-16 sequence
+ ///
+ /// This function is necessary for multi-elements encodings, as
+ /// a single character may use more than 1 storage element, thus the
+ /// total size can be different from (begin - end).
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static std::size_t Count(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an ANSI characters range to UTF-16
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a wide characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromWide(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromLatin1(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to ANSI characters
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to wide characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToLatin1(In begin, In end, Out output, char replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-16 characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf8(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-16 characters range to UTF-16
+ ///
+ /// This functions does nothing more than a direct copy;
+ /// it is defined only to provide the same interface as other
+ /// specializations of the sf::Utf<> template, and allow
+ /// generic code to be written on top of it.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf16(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-16 characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf32(In begin, In end, Out output);
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Specialization of the Utf template for UTF-32
+ ///
+ ////////////////////////////////////////////////////////////
+ template <>
+ class Utf<32>
+ {
+ public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single UTF-32 character
+ ///
+ /// Decoding a character means finding its unique 32-bits
+ /// code (called the codepoint) in the Unicode standard.
+ /// For UTF-32, the character value is the same as the codepoint.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Codepoint of the decoded UTF-32 character
+ /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-32 character
+ ///
+ /// Encoding a character means converting a unique 32-bits
+ /// code (called the codepoint) in the target encoding, UTF-32.
+ /// For UTF-32, the codepoint is the same as the character value.
+ ///
+ /// \param input Codepoint to encode as UTF-32
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to UTF-32 (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out Encode(Uint32 input, Out output, Uint32 replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Advance to the next UTF-32 character
+ ///
+ /// This function is trivial for UTF-32, which can store
+ /// every character in a single storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static In Next(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Count the number of characters of a UTF-32 sequence
+ ///
+ /// This function is trivial for UTF-32, which can store
+ /// every character in a single storage element.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ ///
+ /// \return Iterator pointing to one past the last read element of the input sequence
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static std::size_t Count(In begin, In end);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an ANSI characters range to UTF-32
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a wide characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromWide(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-32
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out FromLatin1(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-32 characters range to ANSI characters
+ ///
+ /// The current global locale will be used by default, unless you
+ /// pass a custom one in the \a locale parameter.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-32 characters range to wide characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToWide(In begin, In end, Out output, wchar_t replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToLatin1(In begin, In end, Out output, char replacement = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-32 characters range to UTF-8
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf8(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-32 characters range to UTF-16
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf16(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a UTF-32 characters range to UTF-32
+ ///
+ /// This functions does nothing more than a direct copy;
+ /// it is defined only to provide the same interface as other
+ /// specializations of the sf::Utf<> template, and allow
+ /// generic code to be written on top of it.
+ ///
+ /// \param begin Iterator pointing to the beginning of the input sequence
+ /// \param end Iterator pointing to the end of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In, typename Out>
+ static Out ToUtf32(In begin, In end, Out output);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single ANSI character to UTF-32
+ ///
+ /// This function does not exist in other specializations
+ /// of sf::Utf<>, it is defined for convenience (it is used by
+ /// several other conversion functions).
+ ///
+ /// \param input Input ANSI character
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Converted character
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static Uint32 DecodeAnsi(In input, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Decode a single wide character to UTF-32
+ ///
+ /// This function does not exist in other specializations
+ /// of sf::Utf<>, it is defined for convenience (it is used by
+ /// several other conversion functions).
+ ///
+ /// \param input Input wide character
+ ///
+ /// \return Converted character
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename In>
+ static Uint32 DecodeWide(In input);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-32 character to ANSI
+ ///
+ /// This function does not exist in other specializations
+ /// of sf::Utf<>, it is defined for convenience (it is used by
+ /// several other conversion functions).
+ ///
+ /// \param codepoint Iterator pointing to the beginning of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement if the input character is not convertible to ANSI (use 0 to skip it)
+ /// \param locale Locale to use for conversion
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out EncodeAnsi(Uint32 codepoint, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Encode a single UTF-32 character to wide
+ ///
+ /// This function does not exist in other specializations
+ /// of sf::Utf<>, it is defined for convenience (it is used by
+ /// several other conversion functions).
+ ///
+ /// \param codepoint Iterator pointing to the beginning of the input sequence
+ /// \param output Iterator pointing to the beginning of the output sequence
+ /// \param replacement Replacement if the input character is not convertible to wide (use 0 to skip it)
+ ///
+ /// \return Iterator to the end of the output sequence which has been written
+ ///
+ ////////////////////////////////////////////////////////////
+ template <typename Out>
+ static Out EncodeWide(Uint32 codepoint, Out output, wchar_t replacement = 0);
+ };
+
+#include "Utf.inl"
+
+ // Make typedefs to get rid of the template syntax
+ typedef Utf<8> Utf8;
+ typedef Utf<16> Utf16;
+ typedef Utf<32> Utf32;
+
+ } // namespace sf
+
+}
+
+
+#endif // SFML_UTF_HPP
diff --git a/Source/Asura.Engine/Text/Utf.inl b/Source/Asura.Engine/Text/Utf.inl
new file mode 100644
index 0000000..69a523b
--- /dev/null
+++ b/Source/Asura.Engine/Text/Utf.inl
@@ -0,0 +1,752 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2019 Laurent Gomila (laurent@sfml-dev.org)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+// References:
+//
+// https://www.unicode.org/
+// https://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c
+// https://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.h
+// https://people.w3.org/rishida/scripts/uniview/conversion
+//
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<8>::Decode(In begin, In end, Uint32& output, Uint32 replacement)
+{
+ // Some useful precomputed data
+ static const int trailing[256] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
+ };
+ static const Uint32 offsets[6] =
+ {
+ 0x00000000, 0x00003080, 0x000E2080, 0x03C82080, 0xFA082080, 0x82082080
+ };
+
+ // decode the character
+ int trailingBytes = trailing[static_cast<Uint8>(*begin)];
+ if (begin + trailingBytes < end)
+ {
+ output = 0;
+ switch (trailingBytes)
+ {
+ case 5: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 4: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 3: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 2: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 1: output += static_cast<Uint8>(*begin++); output <<= 6;
+ case 0: output += static_cast<Uint8>(*begin++);
+ }
+ output -= offsets[trailingBytes];
+ }
+ else
+ {
+ // Incomplete character
+ begin = end;
+ output = replacement;
+ }
+
+ return begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<8>::Encode(Uint32 input, Out output, Uint8 replacement)
+{
+ // Some useful precomputed data
+ static const Uint8 firstBytes[7] =
+ {
+ 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
+ };
+
+ // encode the character
+ if ((input > 0x0010FFFF) || ((input >= 0xD800) && (input <= 0xDBFF)))
+ {
+ // Invalid character
+ if (replacement)
+ *output++ = replacement;
+ }
+ else
+ {
+ // Valid character
+
+ // Get the number of bytes to write
+ std::size_t bytestoWrite = 1;
+ if (input < 0x80) bytestoWrite = 1;
+ else if (input < 0x800) bytestoWrite = 2;
+ else if (input < 0x10000) bytestoWrite = 3;
+ else if (input <= 0x0010FFFF) bytestoWrite = 4;
+
+ // Extract the bytes to write
+ Uint8 bytes[4];
+ switch (bytestoWrite)
+ {
+ case 4: bytes[3] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
+ case 3: bytes[2] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
+ case 2: bytes[1] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
+ case 1: bytes[0] = static_cast<Uint8> (input | firstBytes[bytestoWrite]);
+ }
+
+ // Add them to the output
+ output = std::copy(bytes, bytes + bytestoWrite, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<8>::Next(In begin, In end)
+{
+ Uint32 codepoint;
+ return Decode(begin, end, codepoint);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+std::size_t Utf<8>::Count(In begin, In end)
+{
+ std::size_t length = 0;
+ while (begin < end)
+ {
+ begin = Next(begin, end);
+ ++length;
+ }
+
+ return length;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::FromAnsi(In begin, In end, Out output, const std::locale& locale)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint = Utf<32>::DecodeAnsi(*begin++, locale);
+ output = Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::FromWide(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint = Utf<32>::DecodeWide(*begin++);
+ output = Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::FromLatin1(In begin, In end, Out output)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while (begin < end)
+ output = Encode(*begin++, output);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<32>::EncodeAnsi(codepoint, output, replacement, locale);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToWide(In begin, In end, Out output, wchar_t replacement)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<32>::EncodeWide(codepoint, output, replacement);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToLatin1(In begin, In end, Out output, char replacement)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ *output++ = codepoint < 256 ? static_cast<char>(codepoint) : replacement;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToUtf8(In begin, In end, Out output)
+{
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToUtf16(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<16>::Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::ToUtf32(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ *output++ = codepoint;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<16>::Decode(In begin, In end, Uint32& output, Uint32 replacement)
+{
+ Uint16 first = *begin++;
+
+ // If it's a surrogate pair, first convert to a single UTF-32 character
+ if ((first >= 0xD800) && (first <= 0xDBFF))
+ {
+ if (begin < end)
+ {
+ Uint32 second = *begin++;
+ if ((second >= 0xDC00) && (second <= 0xDFFF))
+ {
+ // The second element is valid: convert the two elements to a UTF-32 character
+ output = ((first - 0xD800) << 10) + (second - 0xDC00) + 0x0010000;
+ }
+ else
+ {
+ // Invalid character
+ output = replacement;
+ }
+ }
+ else
+ {
+ // Invalid character
+ begin = end;
+ output = replacement;
+ }
+ }
+ else
+ {
+ // We can make a direct copy
+ output = first;
+ }
+
+ return begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<16>::Encode(Uint32 input, Out output, Uint16 replacement)
+{
+ if (input <= 0xFFFF)
+ {
+ // The character can be copied directly, we just need to check if it's in the valid range
+ if ((input >= 0xD800) && (input <= 0xDFFF))
+ {
+ // Invalid character (this range is reserved)
+ if (replacement)
+ *output++ = replacement;
+ }
+ else
+ {
+ // Valid character directly convertible to a single UTF-16 character
+ *output++ = static_cast<Uint16>(input);
+ }
+ }
+ else if (input > 0x0010FFFF)
+ {
+ // Invalid character (greater than the maximum Unicode value)
+ if (replacement)
+ *output++ = replacement;
+ }
+ else
+ {
+ // The input character will be converted to two UTF-16 elements
+ input -= 0x0010000;
+ *output++ = static_cast<Uint16>((input >> 10) + 0xD800);
+ *output++ = static_cast<Uint16>((input & 0x3FFUL) + 0xDC00);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<16>::Next(In begin, In end)
+{
+ Uint32 codepoint;
+ return Decode(begin, end, codepoint);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+std::size_t Utf<16>::Count(In begin, In end)
+{
+ std::size_t length = 0;
+ while (begin < end)
+ {
+ begin = Next(begin, end);
+ ++length;
+ }
+
+ return length;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::FromAnsi(In begin, In end, Out output, const std::locale& locale)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint = Utf<32>::DecodeAnsi(*begin++, locale);
+ output = Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::FromWide(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint = Utf<32>::DecodeWide(*begin++);
+ output = Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::FromLatin1(In begin, In end, Out output)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<32>::EncodeAnsi(codepoint, output, replacement, locale);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToWide(In begin, In end, Out output, wchar_t replacement)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<32>::EncodeWide(codepoint, output, replacement);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToLatin1(In begin, In end, Out output, char replacement)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while (begin < end)
+ {
+ *output++ = *begin < 256 ? static_cast<char>(*begin) : replacement;
+ begin++;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToUtf8(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ output = Utf<8>::Encode(codepoint, output);
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToUtf16(In begin, In end, Out output)
+{
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::ToUtf32(In begin, In end, Out output)
+{
+ while (begin < end)
+ {
+ Uint32 codepoint;
+ begin = Decode(begin, end, codepoint);
+ *output++ = codepoint;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<32>::Decode(In begin, In /*end*/, Uint32& output, Uint32 /*replacement*/)
+{
+ output = *begin++;
+ return begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<32>::Encode(Uint32 input, Out output, Uint32 /*replacement*/)
+{
+ *output++ = input;
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<32>::Next(In begin, In /*end*/)
+{
+ return ++begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+std::size_t Utf<32>::Count(In begin, In end)
+{
+ return begin - end;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::FromAnsi(In begin, In end, Out output, const std::locale& locale)
+{
+ while (begin < end)
+ *output++ = DecodeAnsi(*begin++, locale);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::FromWide(In begin, In end, Out output)
+{
+ while (begin < end)
+ *output++ = DecodeWide(*begin++);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::FromLatin1(In begin, In end, Out output)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
+{
+ while (begin < end)
+ output = EncodeAnsi(*begin++, output, replacement, locale);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToWide(In begin, In end, Out output, wchar_t replacement)
+{
+ while (begin < end)
+ output = EncodeWide(*begin++, output, replacement);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToLatin1(In begin, In end, Out output, char replacement)
+{
+ // Latin-1 is directly compatible with Unicode encodings,
+ // and can thus be treated as (a sub-range of) UTF-32
+ while (begin < end)
+ {
+ *output++ = *begin < 256 ? static_cast<char>(*begin) : replacement;
+ begin++;
+ }
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToUtf8(In begin, In end, Out output)
+{
+ while (begin < end)
+ output = Utf<8>::Encode(*begin++, output);
+
+ return output;
+}
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToUtf16(In begin, In end, Out output)
+{
+ while (begin < end)
+ output = Utf<16>::Encode(*begin++, output);
+
+ return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::ToUtf32(In begin, In end, Out output)
+{
+ return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+Uint32 Utf<32>::DecodeAnsi(In input, const std::locale& locale)
+{
+ // On Windows, GCC's standard library (glibc++) has almost
+ // no support for Unicode stuff. As a consequence, in this
+ // context we can only use the default locale and ignore
+ // the one passed as parameter.
+
+ #if defined(SFML_SYSTEM_WINDOWS) && /* if Windows ... */ \
+ (defined(__GLIBCPP__) || defined (__GLIBCXX__)) && /* ... and standard library is glibc++ ... */ \
+ !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) /* ... and STLPort is not used on top of it */
+
+ (void)locale; // to avoid warnings
+
+ wchar_t character = 0;
+ mbtowc(&character, &input, 1);
+ return static_cast<Uint32>(character);
+
+ #else
+
+ // Get the facet of the locale which deals with character conversion
+ const std::ctype<wchar_t>& facet = std::use_facet< std::ctype<wchar_t> >(locale);
+
+ // Use the facet to convert each character of the input string
+ return static_cast<Uint32>(facet.widen(input));
+
+ #endif
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+Uint32 Utf<32>::DecodeWide(In input)
+{
+ // The encoding of wide characters is not well defined and is left to the system;
+ // however we can safely assume that it is UCS-2 on Windows and
+ // UCS-4 on Unix systems.
+ // In both cases, a simple copy is enough (UCS-2 is a subset of UCS-4,
+ // and UCS-4 *is* UTF-32).
+
+ return input;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<32>::EncodeAnsi(Uint32 codepoint, Out output, char replacement, const std::locale& locale)
+{
+ // On Windows, gcc's standard library (glibc++) has almost
+ // no support for Unicode stuff. As a consequence, in this
+ // context we can only use the default locale and ignore
+ // the one passed as parameter.
+
+ #if defined(SFML_SYSTEM_WINDOWS) && /* if Windows ... */ \
+ (defined(__GLIBCPP__) || defined (__GLIBCXX__)) && /* ... and standard library is glibc++ ... */ \
+ !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) /* ... and STLPort is not used on top of it */
+
+ (void)locale; // to avoid warnings
+
+ char character = 0;
+ if (wctomb(&character, static_cast<wchar_t>(codepoint)) >= 0)
+ *output++ = character;
+ else if (replacement)
+ *output++ = replacement;
+
+ return output;
+
+ #else
+
+ // Get the facet of the locale which deals with character conversion
+ const std::ctype<wchar_t>& facet = std::use_facet< std::ctype<wchar_t> >(locale);
+
+ // Use the facet to convert each character of the input string
+ *output++ = facet.narrow(static_cast<wchar_t>(codepoint), replacement);
+
+ return output;
+
+ #endif
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<32>::EncodeWide(Uint32 codepoint, Out output, wchar_t replacement)
+{
+ // The encoding of wide characters is not well defined and is left to the system;
+ // however we can safely assume that it is UCS-2 on Windows and
+ // UCS-4 on Unix systems.
+ // For UCS-2 we need to check if the source characters fits in (UCS-2 is a subset of UCS-4).
+ // For UCS-4 we can do a direct copy (UCS-4 *is* UTF-32).
+
+ switch (sizeof(wchar_t))
+ {
+ case 4:
+ {
+ *output++ = static_cast<wchar_t>(codepoint);
+ break;
+ }
+
+ default:
+ {
+ if ((codepoint <= 0xFFFF) && ((codepoint < 0xD800) || (codepoint > 0xDFFF)))
+ {
+ *output++ = static_cast<wchar_t>(codepoint);
+ }
+ else if (replacement)
+ {
+ *output++ = replacement;
+ }
+ break;
+ }
+ }
+
+ return output;
+}
diff --git a/Source/Asura.Engine/Type.h b/Source/Asura.Engine/Type.h
index a956a4b..88848d5 100644
--- a/Source/Asura.Engine/Type.h
+++ b/Source/Asura.Engine/Type.h
@@ -6,19 +6,6 @@
namespace AsuraEngine
{
- typedef int8_t int8;
- typedef uint8_t uint8;
- typedef uint8 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;
-
}
#endif \ No newline at end of file
diff --git a/Source/Asura.Framework/scripts/ai/state_graph.lua b/Source/Asura.Framework/scripts/ai/state_graph.lua
index a699e76..4f563dc 100644
--- a/Source/Asura.Framework/scripts/ai/state_graph.lua
+++ b/Source/Asura.Framework/scripts/ai/state_graph.lua
@@ -1,4 +1,4 @@
-local StateGraph = AsuraEngine.Asset.Sub("StateGraph")
+local StateGraph = AsuraEngine.Asset.Extend("StateGraph")
AsuraEngine.StateGraph = StateGraph
diff --git a/Source/Asura.Framework/scripts/audio/sound.lua b/Source/Asura.Framework/scripts/audio/sound.lua
index 71def66..d7dea4f 100644
--- a/Source/Asura.Framework/scripts/audio/sound.lua
+++ b/Source/Asura.Framework/scripts/audio/sound.lua
@@ -1,4 +1,4 @@
-AsuraEngine.Sound = AsuraEngine.Asset.Sub("Sound")
+AsuraEngine.Sound = AsuraEngine.Asset.Extend("Sound")
local Sound = AsuraEngine.Sound
diff --git a/Source/Asura.Framework/scripts/audio/source.lua b/Source/Asura.Framework/scripts/audio/source.lua
index 8269842..7dec511 100644
--- a/Source/Asura.Framework/scripts/audio/source.lua
+++ b/Source/Asura.Framework/scripts/audio/source.lua
@@ -1,5 +1,5 @@
-- Audio Source
-AsuraEngine.Source = AsuraEngine.Component.Sub("SoundPlayer")
+AsuraEngine.Source = AsuraEngine.Component.Extend("SoundPlayer")
local Source = AsuraEngine.Source
diff --git a/Source/Asura.Framework/scripts/class.lua b/Source/Asura.Framework/scripts/class.lua
index d5ed5cd..6392483 100644
--- a/Source/Asura.Framework/scripts/class.lua
+++ b/Source/Asura.Framework/scripts/class.lua
@@ -3,7 +3,7 @@ AsuraEngine.Class = {}
local Class = AsuraEngine.Class
Class.__index = Class
-function Class.Sub(base, classname)
+function Class.Extend(base, classname)
local subclass = {}
base.__index = base
setmetatable(subclass, base)
diff --git a/Source/Asura.Framework/scripts/component.lua b/Source/Asura.Framework/scripts/component.lua
index 0eb7fc1..9306f3b 100644
--- a/Source/Asura.Framework/scripts/component.lua
+++ b/Source/Asura.Framework/scripts/component.lua
@@ -5,7 +5,7 @@ local Component = AsuraEngine.Component
-- Component要显示在inspector的变量
Component.gameobject = AsuraEngine.Type.GameObject
-function Component.Sub(cname)
+function Component.Extend(cname)
self.base(cname)
assert(Component.components[cname] == nil)
diff --git a/Source/Asura.Framework/scripts/gameobject.lua b/Source/Asura.Framework/scripts/gameobject.lua
index fb287fb..a2d20ef 100644
--- a/Source/Asura.Framework/scripts/gameobject.lua
+++ b/Source/Asura.Framework/scripts/gameobject.lua
@@ -3,13 +3,13 @@
--
require "transform"
-AsuraEngine.GameObject = AsuraEngine.Asset.Sub("GameObject")
+AsuraEngine.GameObject = AsuraEngine.Asset.Extend("GameObject")
local GameObject = AsuraEngine.GameObject
function GameObject:Ctor()
self.transform = AsuraEngine.Transform.New()
- self.subentities = {} -- Sub node entities
+ self.subentities = {} -- Extend node entities
end
function GameObject:AddChild(gameobject)
diff --git a/Source/Asura.Framework/scripts/graphics/animation.lua b/Source/Asura.Framework/scripts/graphics/animation.lua
index b6673c6..285adaa 100644
--- a/Source/Asura.Framework/scripts/graphics/animation.lua
+++ b/Source/Asura.Framework/scripts/graphics/animation.lua
@@ -1,4 +1,4 @@
-AsuraEngine.Animation = AsuraEngine.Asset.Sub("Animation")
+AsuraEngine.Animation = AsuraEngine.Asset.Extend("Animation")
local Animation = AsuraEngine.Animation
diff --git a/Source/Asura.Framework/scripts/graphics/animator.lua b/Source/Asura.Framework/scripts/graphics/animator.lua
index 5c77adc..c019dfa 100644
--- a/Source/Asura.Framework/scripts/graphics/animator.lua
+++ b/Source/Asura.Framework/scripts/graphics/animator.lua
@@ -1,6 +1,6 @@
local Component = AsuraEngine.Framework.Require("component")
-AsuraEngine.Animator = Component.Sub("Animator")
+AsuraEngine.Animator = Component.Extend("Animator")
local Animator = AsuraEngine.Animator
diff --git a/Source/Asura.Framework/scripts/graphics/camera.lua b/Source/Asura.Framework/scripts/graphics/camera.lua
index 383c328..a989de6 100644
--- a/Source/Asura.Framework/scripts/graphics/camera.lua
+++ b/Source/Asura.Framework/scripts/graphics/camera.lua
@@ -1,4 +1,4 @@
-AsuraEngine.Camera = AsuraEngine.Component.Sub("Camera")
+AsuraEngine.Camera = AsuraEngine.Component.Extend("Camera")
local Camera = AsuraEngine.Camera
diff --git a/Source/Asura.Framework/scripts/graphics/canvas.lua b/Source/Asura.Framework/scripts/graphics/canvas.lua
index 11e71f3..ce2ca20 100644
--- a/Source/Asura.Framework/scripts/graphics/canvas.lua
+++ b/Source/Asura.Framework/scripts/graphics/canvas.lua
@@ -1,4 +1,4 @@
-AsuraEngine.Canvas = AsuraEngine.Component.Sub("Canvas")
+AsuraEngine.Canvas = AsuraEngine.Component.Extend("Canvas")
local Canvas = AsuraEngine.Canvas
diff --git a/Source/Asura.Framework/scripts/graphics/image.lua b/Source/Asura.Framework/scripts/graphics/image.lua
index dcdb4c3..f5ebaa2 100644
--- a/Source/Asura.Framework/scripts/graphics/image.lua
+++ b/Source/Asura.Framework/scripts/graphics/image.lua
@@ -1,5 +1,5 @@
-- 图片资源
-AsuraEngine.Image = AsuraEngine.Asset.Sub("Image")
+AsuraEngine.Image = AsuraEngine.Asset.Extend("Image")
local Image = AsuraEngine.Image
diff --git a/Source/Asura.Framework/scripts/graphics/material.lua b/Source/Asura.Framework/scripts/graphics/material.lua
index 64d70f7..5a6e5bd 100644
--- a/Source/Asura.Framework/scripts/graphics/material.lua
+++ b/Source/Asura.Framework/scripts/graphics/material.lua
@@ -1,5 +1,5 @@
--material是shader的代理
-AsuraEngine.Material = AsuraEngine.Asset.Sub("Material")
+AsuraEngine.Material = AsuraEngine.Asset.Extend("Material")
local Material = AsuraEngine.Material
diff --git a/Source/Asura.Framework/scripts/graphics/mesh2d.lua b/Source/Asura.Framework/scripts/graphics/mesh2d.lua
index 13b270a..05b2e2e 100644
--- a/Source/Asura.Framework/scripts/graphics/mesh2d.lua
+++ b/Source/Asura.Framework/scripts/graphics/mesh2d.lua
@@ -1,4 +1,4 @@
-AsuraEngine.Mesh2D = AsuraEngine.Asset.Sub("Mesh2D")
+AsuraEngine.Mesh2D = AsuraEngine.Asset.Extend("Mesh2D")
local Mesh2D = AsuraEngine.Mesh2D
diff --git a/Source/Asura.Framework/scripts/graphics/mesh2d_renderer.lua b/Source/Asura.Framework/scripts/graphics/mesh2d_renderer.lua
index ca97283..09c8c98 100644
--- a/Source/Asura.Framework/scripts/graphics/mesh2d_renderer.lua
+++ b/Source/Asura.Framework/scripts/graphics/mesh2d_renderer.lua
@@ -1,4 +1,4 @@
-AsuraEngine.Mesh2DRenderer = AsuraEngine.Renderer.Sub("Mesh2DRenderer")
+AsuraEngine.Mesh2DRenderer = AsuraEngine.Renderer.Extend("Mesh2DRenderer")
local Mesh2DRenderer = AsuraEngine.Mesh2DRenderer
diff --git a/Source/Asura.Framework/scripts/graphics/particle_system.lua b/Source/Asura.Framework/scripts/graphics/particle_system.lua
index a2e3c26..8de3258 100644
--- a/Source/Asura.Framework/scripts/graphics/particle_system.lua
+++ b/Source/Asura.Framework/scripts/graphics/particle_system.lua
@@ -1,6 +1,6 @@
require "graphics.sprite_renderer"
-AsuraEngine.ParticleSystem = AsuraEngine.Component.Sub("ParticleSystem")
+AsuraEngine.ParticleSystem = AsuraEngine.Component.Extend("ParticleSystem")
local ParticleSystem = AsuraEngine.ParticleSystem
diff --git a/Source/Asura.Framework/scripts/graphics/renderer.lua b/Source/Asura.Framework/scripts/graphics/renderer.lua
index 189c9d1..92a6409 100644
--- a/Source/Asura.Framework/scripts/graphics/renderer.lua
+++ b/Source/Asura.Framework/scripts/graphics/renderer.lua
@@ -1,4 +1,4 @@
-local Renderer = AsuraEngine.Component.Sub("Renderer")
+local Renderer = AsuraEngine.Component.Extend("Renderer")
AsuraEngine.Renderer = Renderer
function Renderer.Ctor(self)
diff --git a/Source/Asura.Framework/scripts/graphics/shader.lua b/Source/Asura.Framework/scripts/graphics/shader.lua
index 1bbf1fa..c411619 100644
--- a/Source/Asura.Framework/scripts/graphics/shader.lua
+++ b/Source/Asura.Framework/scripts/graphics/shader.lua
@@ -1,4 +1,4 @@
-AsuraEngine.Shader = AsuraEngine.Asset.Sub("Shader")
+AsuraEngine.Shader = AsuraEngine.Asset.Extend("Shader")
local helper = AsuraEngine.Framework.Require("graphics/shaderHelper")
diff --git a/Source/Asura.Framework/scripts/graphics/shape.lua b/Source/Asura.Framework/scripts/graphics/shape.lua
index 6d737f0..51ea8c3 100644
--- a/Source/Asura.Framework/scripts/graphics/shape.lua
+++ b/Source/Asura.Framework/scripts/graphics/shape.lua
@@ -1,7 +1,7 @@
--
-- 2D图形
--
-AsuraEngine.Shape = AsuraEngine.Asset.Sub("Shape")
+AsuraEngine.Shape = AsuraEngine.Asset.Extend("Shape")
local Shape = AsuraEngine.Shape
diff --git a/Source/Asura.Framework/scripts/graphics/shape_renderer.lua b/Source/Asura.Framework/scripts/graphics/shape_renderer.lua
index 8c002a2..80b48b8 100644
--- a/Source/Asura.Framework/scripts/graphics/shape_renderer.lua
+++ b/Source/Asura.Framework/scripts/graphics/shape_renderer.lua
@@ -1,4 +1,4 @@
-AsuraEngine.ShapeRenderer = AsuraEngine.Component.Sub("ShapeRenderer")
+AsuraEngine.ShapeRenderer = AsuraEngine.Component.Extend("ShapeRenderer")
local ShapeRenderer = AsuraEngine.ShapeRenderer
diff --git a/Source/Asura.Framework/scripts/graphics/sprite.lua b/Source/Asura.Framework/scripts/graphics/sprite.lua
index da116fc..9bf05f4 100644
--- a/Source/Asura.Framework/scripts/graphics/sprite.lua
+++ b/Source/Asura.Framework/scripts/graphics/sprite.lua
@@ -1,4 +1,4 @@
-local Sprite = AsuraEngine.Asset.Sub("Sprite")
+local Sprite = AsuraEngine.Asset.Extend("Sprite")
AsuraEngine.Sprite = Sprite
function Sprite.Ctor(self, image)
diff --git a/Source/Asura.Framework/scripts/graphics/sprite_batch_renderer.lua b/Source/Asura.Framework/scripts/graphics/sprite_batch_renderer.lua
index 9621bce..9ec73d2 100644
--- a/Source/Asura.Framework/scripts/graphics/sprite_batch_renderer.lua
+++ b/Source/Asura.Framework/scripts/graphics/sprite_batch_renderer.lua
@@ -1,4 +1,4 @@
-AsuraEngine.SpriteBatchRenderer = AsuraEngine.Component.Sub("SpriteBatchRenderer")
+AsuraEngine.SpriteBatchRenderer = AsuraEngine.Component.Extend("SpriteBatchRenderer")
local SpriteBatchRenderer = AsuraEngine.SpriteBatchRenderer
diff --git a/Source/Asura.Framework/scripts/graphics/sprite_renderer.lua b/Source/Asura.Framework/scripts/graphics/sprite_renderer.lua
index 5ceafd2..0a41e08 100644
--- a/Source/Asura.Framework/scripts/graphics/sprite_renderer.lua
+++ b/Source/Asura.Framework/scripts/graphics/sprite_renderer.lua
@@ -1,6 +1,6 @@
require "graphics.renderer"
-local SpriteRenderer = AsuraEngine.Renderer.Sub("Spriterenderer")
+local SpriteRenderer = AsuraEngine.Renderer.Extend("Spriterenderer")
AsuraEngine.SpriteRenderer = SpriteRenderer
function SpriteRenderer.Ctor(self)
diff --git a/Source/Asura.Framework/scripts/gui/button.lua b/Source/Asura.Framework/scripts/gui/button.lua
index 67d0943..b122931 100644
--- a/Source/Asura.Framework/scripts/gui/button.lua
+++ b/Source/Asura.Framework/scripts/gui/button.lua
@@ -1,4 +1,4 @@
-AsuraEngine.Button = AsuraEngine.Component.Sub("Button")
+AsuraEngine.Button = AsuraEngine.Component.Extend("Button")
local Button = AsuraEngine.Button
diff --git a/Source/Asura.Framework/scripts/scene.lua b/Source/Asura.Framework/scripts/scene.lua
index 2adbf53..3036ce1 100644
--- a/Source/Asura.Framework/scripts/scene.lua
+++ b/Source/Asura.Framework/scripts/scene.lua
@@ -1,12 +1,13 @@
--
-- Scene是一系列gameobject的集合。
--
-AsuraEngine.Scene = AsuraEngine.Asset.Sub("Scene")
+AsuraEngine.Scene = AsuraEngine.Asset.Extend("Scene")
local Scene = AsuraEngine.Scene
function Scene.Ctor(self)
self.rootGameObjects = {} --当前场景的所有root gameobject
+ self.super.Ctor(self)
end
--获取当前的场景
diff --git a/Source/Asura.Runner/Runner.cpp b/Source/Asura.Runner/Runner.cpp
new file mode 100644
index 0000000..47f44ec
--- /dev/null
+++ b/Source/Asura.Runner/Runner.cpp
@@ -0,0 +1,10 @@
+#include "Asura.h"
+#include "Runner.h"
+
+void Runner::Run(int argc, char* args[])
+{
+
+
+}
+
+ASURA_RUN(Runner); \ No newline at end of file
diff --git a/Source/Asura.Runner/Runner.h b/Source/Asura.Runner/Runner.h
index 45d9028..8d1bc49 100644
--- a/Source/Asura.Runner/Runner.h
+++ b/Source/Asura.Runner/Runner.h
@@ -9,6 +9,7 @@ class Runner : public Application
{
public:
+ void Run(int argc, char* args[]) override;
};
diff --git a/Source/Asura.Runner/main.cpp b/Source/Asura.Runner/main.cpp
deleted file mode 100644
index 3947f65..0000000
--- a/Source/Asura.Runner/main.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "Runner.h"
-
-// ϷᱻһԴļrunnerȡݣϷ
-// RunnerֻܶȡpackerϷļeditorֱϷassetsRunnerһСл
-int main()
-{
- Runner runner;
- runner.Init();
- runner.Run();
- runner.Exit();
- return 0;
-} \ No newline at end of file
diff --git a/Source/Samples/LuaxTest/header.h b/Source/Samples/LuaxTest/header.h
new file mode 100644
index 0000000..386ae71
--- /dev/null
+++ b/Source/Samples/LuaxTest/header.h
@@ -0,0 +1,60 @@
+
+#ifndef ASSERT
+#ifdef NDEBUG
+#define ASSERT(x) { false ? (void)(x) : (void)0; }
+#else
+#ifdef _WIN32
+#define ASURA_DEBUG_BREAK() __debugbreak()
+#else
+#define ASURA_DEBUG_BREAK() raise(SIGTRAP)
+#endif
+#define ASSERT(x) do { const volatile bool asura_assert_b____ = !(x); if(asura_assert_b____) ASURA_DEBUG_BREAK(); } while (false)
+#endif
+#endif
+
+///
+/// ̳Singletonڵһʵʱʵ֮ٴʵᱨ
+///
+template<class T>
+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<T*>(this);
+ };
+
+ virtual ~Singleton() {};
+
+ static T* instance;
+
+private:
+
+ Singleton(const Singleton& singleton);
+
+ Singleton& operator = (const Singleton& singleton);
+
+};
+
+template<class T>
+T* Singleton<T>::instance = nullptr;
diff --git a/Source/Samples/LuaxTest/main.cpp b/Source/Samples/LuaxTest/main.cpp
new file mode 100644
index 0000000..828b427
--- /dev/null
+++ b/Source/Samples/LuaxTest/main.cpp
@@ -0,0 +1,190 @@
+///
+/// Scripting with Lua.
+///
+extern "C"{
+#include "Lua51/lua.h"
+#include "Lua51/lauxlib.h"
+}
+#include "Luax/luax.h"
+#include "header.h"
+
+#include <iostream>
+#include <string>
+
+using namespace std;
+using namespace Luax;
+
+//----------------------------------------------------------------------------------------------------------------
+
+class School : Singleton<School>
+{
+public:
+
+ School() : mName("Koko") {}
+
+private:
+
+ const char* mName;
+
+public:
+
+ LUAX_DECL_SINGLETON(School);
+
+ LUAX_DECL_METHOD(l_GetName);
+
+};
+
+int School::l_GetName(lua_State* L)
+{
+ LuaxState state(L);
+
+ School* school = Get();
+
+ state.Push(school->mName);
+ return 1;
+}
+
+void School::RegisterLuaxClass(LuaxState& state)
+{
+ state.SetField(-1, "Region", "Block 1"); // 101
+
+ luaL_Reg regTable[] = {
+ { "GetName", l_GetName },
+ { NULL, NULL }
+ };
+
+ state.Register(regTable);
+
+}
+
+//----------------------------------------------------------------------------------------------------------------
+
+class Boy : public LuaxClass
+{
+public:
+
+ Boy(int age) : mAge(age) {}
+
+private:
+
+ int mAge;
+
+public:
+
+ LUAX_DECL_FACTORY(SimBoy);
+
+ // member methods
+ LUAX_DECL_METHOD(l_New);
+ LUAX_DECL_METHOD(l_GetAge);
+
+ // class method
+ LUAX_DECL_METHOD(l_GetGender);
+
+};
+
+int Boy::l_New(lua_State* L)
+{
+ LuaxState state(L);
+
+ int age = state.GetValue(1, 0);
+
+ Boy* boy = new Boy(age);
+ boy->PushLuaUserdata(state);
+
+ return 1;
+}
+
+int Boy::l_GetAge(lua_State* L)
+{
+ LUAX_SETUP(L, "U");
+
+ return 1;
+}
+
+int Boy::l_GetGender(lua_State* L)
+{
+ LUAX_SETUP(L, "*");
+ state.Push("male student!");
+ return 1;
+}
+
+void Boy::RegisterLuaxClass(LuaxState& state)
+{
+ state.SetField(-1, "Class", 101); // 101
+ state.SetField(-1, "Gender", "Male"); // 101
+
+ luaL_Reg regTable[] = {
+ {"GetGender", l_GetGender},
+ {NULL, NULL}
+ };
+
+ state.Register(regTable);
+}
+
+void Boy::RegisterLuaxInterface(LuaxState& state)
+{
+ luaL_Reg regTable[] = {
+ {"New", l_New},
+ {NULL, NULL}
+ };
+
+ state.Register(regTable);
+}
+
+//----------------------------------------------------------------------------------------------------------------
+
+string script = R"(
+function main()
+ local a = 19
+ print(Asura.version)
+ print(Asura.author.name)
+ print("ok")
+ print(Asura.author.func())
+-- local boy = Asura.SimBoy.New("I am peter!", 19)
+-- boy:Say()
+-- print(Asura.SimSchool.GetName())
+ print(Asura.SimBoy.Class)
+ print(Asura.SimBoy.Gender)
+ print(Asura.SimBoy.GetGender())
+ print(Asura.SimBoy.GetClassName())
+ print(Asura.School.GetName())
+ print(Asura.School.Region)
+end
+function err(msg)
+ print(msg)
+end
+xpcall(main, err)
+)";
+
+//----------------------------------------------------------------------------------------------------------------
+
+int func(lua_State* L)
+{
+ LUAX_SETUP(L, "*");
+ state.Push("func ok");
+ return 1;
+}
+
+int main()
+{
+ lua_State* L = lua_open();
+ Luax::LuaxState state(L);
+ state.OpenLibs();
+ state.PushNamespace("Asura");
+ state.PushNamespace("author");
+ state.SetField(-1, "name", "chai");
+ state.SetField(-1, "func", func);
+ state.PopNamespace(); // Asura.author
+ state.SetField(-1, "version", 100);
+ cout << state.GetField<float>(-1, "version", 0);
+
+ state.RegisterSingleton<School>();
+ state.RegisterFactory<Boy>();
+
+ state.PopNamespace(); // Asura
+ state.DoString(script);
+
+ lua_close(L);
+
+ getchar();
+} \ No newline at end of file