aboutsummaryrefslogtreecommitdiff
path: root/src/libjin-lua/modules
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2018-12-20 18:34:50 +0800
committerchai <chaifix@163.com>2018-12-20 18:34:50 +0800
commitee8ef0433e36bf354a717bd4af679a0a5af2e6be (patch)
tree2fc748510200f8bc24928d1938300eecc0604deb /src/libjin-lua/modules
parent7ae40127f15f8f2cb963a7efeb018f7887ebc1ea (diff)
*修改文件结构
Diffstat (limited to 'src/libjin-lua/modules')
-rw-r--r--src/libjin-lua/modules/ai/je_lua_ai.cpp13
-rw-r--r--src/libjin-lua/modules/ai/je_lua_ai.h17
-rw-r--r--src/libjin-lua/modules/ai/je_lua_behavior_tree.cpp11
-rw-r--r--src/libjin-lua/modules/ai/je_lua_behavior_tree.h14
-rw-r--r--src/libjin-lua/modules/ai/je_lua_state_machine.cpp25
-rw-r--r--src/libjin-lua/modules/ai/je_lua_state_machine.h14
-rw-r--r--src/libjin-lua/modules/audio/je_lua_audio.cpp132
-rw-r--r--src/libjin-lua/modules/audio/je_lua_audio.h16
-rw-r--r--src/libjin-lua/modules/audio/je_lua_source.cpp114
-rw-r--r--src/libjin-lua/modules/audio/je_lua_source.h16
-rw-r--r--src/libjin-lua/modules/bit/je_lua_bit.cpp86
-rw-r--r--src/libjin-lua/modules/bit/je_lua_bit.h14
-rw-r--r--src/libjin-lua/modules/core/je_lua_core.cpp46
-rw-r--r--src/libjin-lua/modules/core/je_lua_core.h14
-rw-r--r--src/libjin-lua/modules/event/je_lua_event.cpp130
-rw-r--r--src/libjin-lua/modules/event/je_lua_event.h14
-rw-r--r--src/libjin-lua/modules/filesystem/je_lua_filesystem.cpp140
-rw-r--r--src/libjin-lua/modules/filesystem/je_lua_filesystem.h14
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_animation.cpp122
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_animation.h24
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_animator.cpp163
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_animator.h23
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_bitmap.cpp110
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_bitmap.h16
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_canvas.cpp63
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_canvas.h16
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_graphics.cpp1048
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_graphics.h14
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_page.cpp66
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_page.h22
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_particle_system.cpp422
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_particle_system.h21
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_shader.cpp132
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_shader.h16
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_sprite.cpp66
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_sprite.h24
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_spritesheet.cpp118
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_spritesheet.h21
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_text.cpp31
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_text.h16
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_texture.cpp63
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_texture.h16
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_texture_font.cpp63
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_texture_font.h16
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_ttf.cpp63
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_ttf.h16
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_ttf_data.cpp49
-rw-r--r--src/libjin-lua/modules/graphics/je_lua_ttf_data.h21
-rw-r--r--src/libjin-lua/modules/je_lua_modules.h19
-rw-r--r--src/libjin-lua/modules/joypad/je_lua_joypad.cpp21
-rw-r--r--src/libjin-lua/modules/joypad/je_lua_joypad.h14
-rw-r--r--src/libjin-lua/modules/keyboard/je_lua_keyboard.cpp17
-rw-r--r--src/libjin-lua/modules/keyboard/je_lua_keyboard.h14
-rw-r--r--src/libjin-lua/modules/math/je_lua_math.cpp30
-rw-r--r--src/libjin-lua/modules/math/je_lua_math.h14
-rw-r--r--src/libjin-lua/modules/mouse/je_lua_mouse.cpp42
-rw-r--r--src/libjin-lua/modules/mouse/je_lua_mouse.h14
-rw-r--r--src/libjin-lua/modules/net/je_lua_buffer.cpp136
-rw-r--r--src/libjin-lua/modules/net/je_lua_buffer.h102
-rw-r--r--src/libjin-lua/modules/net/je_lua_net.cpp79
-rw-r--r--src/libjin-lua/modules/net/je_lua_net.h14
-rw-r--r--src/libjin-lua/modules/net/je_lua_socket.cpp123
-rw-r--r--src/libjin-lua/modules/net/je_lua_socket.h16
-rw-r--r--src/libjin-lua/modules/thread/je_lua_thread.cpp240
-rw-r--r--src/libjin-lua/modules/thread/je_lua_thread.h95
-rw-r--r--src/libjin-lua/modules/time/je_lua_time.cpp70
-rw-r--r--src/libjin-lua/modules/time/je_lua_time.h14
-rw-r--r--src/libjin-lua/modules/time/je_lua_timer.cpp132
-rw-r--r--src/libjin-lua/modules/time/je_lua_timer.h20
69 files changed, 4917 insertions, 0 deletions
diff --git a/src/libjin-lua/modules/ai/je_lua_ai.cpp b/src/libjin-lua/modules/ai/je_lua_ai.cpp
new file mode 100644
index 0000000..4afd625
--- /dev/null
+++ b/src/libjin-lua/modules/ai/je_lua_ai.cpp
@@ -0,0 +1,13 @@
+#include "libjin/jin.h"
+
+using namespace JinEngine::AI;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+
+
+ }
+} \ No newline at end of file
diff --git a/src/libjin-lua/modules/ai/je_lua_ai.h b/src/libjin-lua/modules/ai/je_lua_ai.h
new file mode 100644
index 0000000..9e1a8ae
--- /dev/null
+++ b/src/libjin-lua/modules/ai/je_lua_ai.h
@@ -0,0 +1,17 @@
+#ifndef __JE_LUA_AI_H__
+#define __JE_LUA_AI_H__
+
+#include "je_lua_behavior_tree.h"
+#include "je_lua_state_machine.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_ai(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/ai/je_lua_behavior_tree.cpp b/src/libjin-lua/modules/ai/je_lua_behavior_tree.cpp
new file mode 100644
index 0000000..20e8e55
--- /dev/null
+++ b/src/libjin-lua/modules/ai/je_lua_behavior_tree.cpp
@@ -0,0 +1,11 @@
+#include "libjin/jin.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_BehaviorTree = "Texture";
+
+ }
+} \ No newline at end of file
diff --git a/src/libjin-lua/modules/ai/je_lua_behavior_tree.h b/src/libjin-lua/modules/ai/je_lua_behavior_tree.h
new file mode 100644
index 0000000..083d12b
--- /dev/null
+++ b/src/libjin-lua/modules/ai/je_lua_behavior_tree.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_BEHAVIOR_TREE_H__
+#define __JE_LUA_BEHAVIOR_TREE_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_BehaviorTree;
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/ai/je_lua_state_machine.cpp b/src/libjin-lua/modules/ai/je_lua_state_machine.cpp
new file mode 100644
index 0000000..06338b8
--- /dev/null
+++ b/src/libjin-lua/modules/ai/je_lua_state_machine.cpp
@@ -0,0 +1,25 @@
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+using namespace JinEngine::AI;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_StateMachine = "StateMachine";
+
+ LUA_IMPLEMENT int l_addEnterCallback(lua_State* L)
+ {
+ //StateMachine* sm;
+ //sm->addEnterListener("", [](void* p) -> void{
+
+ //
+ //});
+
+ return 0;
+ }
+
+ }
+} \ No newline at end of file
diff --git a/src/libjin-lua/modules/ai/je_lua_state_machine.h b/src/libjin-lua/modules/ai/je_lua_state_machine.h
new file mode 100644
index 0000000..3c78f75
--- /dev/null
+++ b/src/libjin-lua/modules/ai/je_lua_state_machine.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_STATE_MACHINE_H__
+#define __JE_LUA_STATE_MACHINE_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_StateMachine;
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/audio/je_lua_audio.cpp b/src/libjin-lua/modules/audio/je_lua_audio.cpp
new file mode 100644
index 0000000..f5ef31f
--- /dev/null
+++ b/src/libjin-lua/modules/audio/je_lua_audio.cpp
@@ -0,0 +1,132 @@
+#include "common/je_lua.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+#include "je_lua_source.h"
+
+using namespace JinEngine::Audio;
+using namespace JinEngine::Audio::SDL;
+using namespace JinEngine::Filesystem;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ typedef SDLAudio Audio;
+ typedef SDLSource Source;
+
+ struct
+ {
+ bool initialized = false;
+ } context;
+
+ LUA_IMPLEMENT int l_init(lua_State* L)
+ {
+ if (context.initialized)
+ {
+ // Already initialized.
+ luax_pushboolean(L, true);
+ return 1;
+ }
+ Audio::Setting setting;
+ setting.samplerate = 44100;
+ setting.samples = 44100;
+ Audio* audio = Audio::get();
+ context.initialized = audio->start(&setting);
+ if (!context.initialized)
+ {
+ luax_error(L, "could not init audio");
+ luax_pushboolean(L, false);
+ return 1;
+ }
+ luax_pushboolean(L, true);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_play(lua_State* L)
+ {
+ Audio::get()->play();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_stop(lua_State* L)
+ {
+ Audio::get()->stop();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_pause(lua_State* L)
+ {
+ Audio::get()->pause();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_resume(lua_State* L)
+ {
+ Audio::get()->resume();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setVolume(lua_State* L)
+ {
+ float volume = luax_checknumber(L, 1);
+ Audio::get()->setVolume(volume);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_newSource(lua_State* L)
+ {
+ AssetDatabase* fs = AssetDatabase::get();
+ const char* f = luax_checkstring(L, 1);
+ Buffer b;
+ try
+ {
+ if (!fs->exists(f))
+ throw Exception("No such source file %s.", f);
+ fs->read(f, b);
+ }
+ catch (Exception& e)
+ {
+ error(L, "Failed to read source file %s", f);
+ luax_pushnil(L);
+ return 1;
+ }
+ Source* src = new SDLSource((void*)&b, b.size());
+ if (src == nullptr)
+ {
+ error(L, "Failed to decode source file %s", f);
+ luax_pushnil(L);
+ return 1;
+ }
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Source, new Shared(src));
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_destroy(lua_State* L)
+ {
+ Audio* audio = Audio::get();
+ audio->quit();
+ return 0;
+ }
+
+ LUA_EXPORT int luaopen_audio(lua_State* L)
+ {
+ luaopen_Source(L);
+
+ luaL_Reg methods[] = {
+ { "init", l_init },
+ { "play", l_play },
+ { "stop", l_stop },
+ { "pause", l_pause },
+ { "resume", l_resume },
+ { "setVolume", l_setVolume },
+ { "newSource", l_newSource },
+ { "destroy", l_destroy },
+ { 0, 0 }
+ };
+ luax_newlib(L, methods);
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/audio/je_lua_audio.h b/src/libjin-lua/modules/audio/je_lua_audio.h
new file mode 100644
index 0000000..6b4669a
--- /dev/null
+++ b/src/libjin-lua/modules/audio/je_lua_audio.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_AUDIO_H__
+#define __JE_LUA_AUDIO_H__
+
+#include "je_lua_audio.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_audio(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/audio/je_lua_source.cpp b/src/libjin-lua/modules/audio/je_lua_source.cpp
new file mode 100644
index 0000000..8c9e247
--- /dev/null
+++ b/src/libjin-lua/modules/audio/je_lua_source.cpp
@@ -0,0 +1,114 @@
+#include "libjin/jin.h"
+#include "common/je_lua.h"
+#include "common/je_lua_common.h"
+
+using namespace JinEngine::Audio;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Source = "Source";
+
+ LUA_IMPLEMENT inline Source* checkSource(lua_State* L)
+ {
+ LuaObject* luaObj = luax_checkobject(L, 1, Jin_Lua_Source);
+ Source* source = luaObj->getObject<Source>();
+ return source;
+ }
+
+ LUA_IMPLEMENT int l_play(lua_State* L)
+ {
+ Source* source = checkSource(L);
+ source->play();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_stop(lua_State* L)
+ {
+ Source* source = checkSource(L);
+ source->stop();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_pause(lua_State* L)
+ {
+ Source* source = checkSource(L);
+ source->pause();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_rewind(lua_State* L)
+ {
+ Source* source = checkSource(L);
+ source->rewind();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_resume(lua_State* L)
+ {
+ Source* source = checkSource(L);
+ source->resume();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_isStop(lua_State* L)
+ {
+ Source* source = checkSource(L);
+ bool isStop = source->isStopped();
+ luax_pushboolean(L, isStop);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_isPaused(lua_State* L)
+ {
+ Source* source = checkSource(L);
+ bool isPaused = source->isPaused();
+ luax_pushboolean(L, isPaused);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_setVolume(lua_State* L)
+ {
+ Source* source = checkSource(L);
+ float volume = luax_checknumber(L, 2);
+ source->setVolume(volume);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setLoop(lua_State* L)
+ {
+ Source* source = checkSource(L);
+ bool loop = luax_checkbool(L, 2);
+ source->setLoop(loop);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Source);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_Source(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "play", l_play },
+ { "stop", l_stop },
+ { "pause", l_pause },
+ { "resume", l_resume },
+ { "rewind", l_rewind },
+ { "isStop", l_isStop },
+ { "isPaused", l_isPaused },
+ { "setVolume", l_setVolume },
+ { "setLoop", l_setLoop },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Source, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/audio/je_lua_source.h b/src/libjin-lua/modules/audio/je_lua_source.h
new file mode 100644
index 0000000..f7e6b48
--- /dev/null
+++ b/src/libjin-lua/modules/audio/je_lua_source.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_SOURCE_H__
+#define __JE_LUA_SOURCE_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Source;
+
+ void luaopen_Source(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/bit/je_lua_bit.cpp b/src/libjin-lua/modules/bit/je_lua_bit.cpp
new file mode 100644
index 0000000..9484743
--- /dev/null
+++ b/src/libjin-lua/modules/bit/je_lua_bit.cpp
@@ -0,0 +1,86 @@
+#include "common/je_lua_common.h"
+#include "common/je_lua.h"
+#include "libjin/jin.h"
+
+#include <cstdlib>
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ LUA_IMPLEMENT int l_and(lua_State* L)
+ {
+ int a = luax_checkinteger(L, 1);
+ int b = luax_checkinteger(L, 2);
+ luax_pushinteger(L, a & b);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_or(lua_State* L)
+ {
+ int a = luax_checkinteger(L, 1);
+ int b = luax_checkinteger(L, 2);
+ luax_pushinteger(L, a | b);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_xor(lua_State* L)
+ {
+ int a = luax_checkinteger(L, 1);
+ int b = luax_checkinteger(L, 2);
+ luax_pushinteger(L, a ^ b);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_not(lua_State* L)
+ {
+ int n = luax_checkinteger(L, 1);
+ luax_pushinteger(L, ~n);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_lshift(lua_State* L)
+ {
+ int a = luax_checkinteger(L, 1);
+ int b = luax_checkinteger(L, 2);
+ luax_pushinteger(L, a << b);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_rshift(lua_State* L)
+ {
+ int a = luax_checkinteger(L, 1);
+ int b = luax_checkinteger(L, 2);
+ luax_pushinteger(L, a >> b);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_include(lua_State* L)
+ {
+ int a = luax_checkinteger(L, 1);
+ int b = luax_checkinteger(L, 2);
+ luax_pushboolean(L, (a & b) == b);
+ return 1;
+ }
+
+ LUA_EXPORT int luaopen_bit(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "bAnd", l_and },
+ { "bOr" , l_or },
+ { "bXor", l_xor },
+ { "bNot", l_not },
+ { "bLs", l_lshift },
+ { "bRs", l_rshift },
+ { "bInc", l_include },
+ { 0, 0 }
+ };
+
+ luax_newlib(L, methods);
+
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/bit/je_lua_bit.h b/src/libjin-lua/modules/bit/je_lua_bit.h
new file mode 100644
index 0000000..21cf064
--- /dev/null
+++ b/src/libjin-lua/modules/bit/je_lua_bit.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_BIT_H__
+#define __JE_LUA_BIT_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_bit(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/core/je_lua_core.cpp b/src/libjin-lua/modules/core/je_lua_core.cpp
new file mode 100644
index 0000000..956ffbe
--- /dev/null
+++ b/src/libjin-lua/modules/core/je_lua_core.cpp
@@ -0,0 +1,46 @@
+#include "common/je_lua_common.h"
+#include "common/je_lua.h"
+#include "libjin/jin.h"
+
+using namespace JinEngine::Game;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ LUA_IMPLEMENT int l_running(lua_State* L)
+ {
+ static Application* app = Application::get();
+ bool running = app->running();
+ luax_pushboolean(L, running);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_stop(lua_State* L)
+ {
+ Application::get()->stop();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_quit(lua_State* L)
+ {
+ Application::get()->quit();
+ return 0;
+ }
+
+ LUA_EXPORT int luaopen_core(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "running", l_running },
+ { "stop", l_stop },
+ { "quit", l_quit },
+ { 0, 0 }
+ };
+ luax_newlib(L, methods);
+
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/core/je_lua_core.h b/src/libjin-lua/modules/core/je_lua_core.h
new file mode 100644
index 0000000..037ac4b
--- /dev/null
+++ b/src/libjin-lua/modules/core/je_lua_core.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_CORE_H__
+#define __JE_LUA_CORE_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_core(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/event/je_lua_event.cpp b/src/libjin-lua/modules/event/je_lua_event.cpp
new file mode 100644
index 0000000..8a550d6
--- /dev/null
+++ b/src/libjin-lua/modules/event/je_lua_event.cpp
@@ -0,0 +1,130 @@
+/**
+* Event module
+*/
+#include "common/je_lua_common.h"
+#include "common/je_lua.h"
+#include "libjin/jin.h"
+
+using namespace JinEngine;
+using namespace JinEngine::Input;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ /**
+ * Load event poll, return a iterator(a table).
+ */
+ LUA_IMPLEMENT int l_event_poll(lua_State *L)
+ {
+ /* table to store events */
+ luax_newtable(L);
+ static Event e;
+ int i = 1;
+ poll:
+ while (pollEvent(&e))
+ {
+ /**
+ * TODO: ڴСıʱҪtransform
+ *
+ */
+ luax_newtable(L);
+ switch (e.type)
+ {
+ case EventType::QUIT:
+ luax_setfieldstring(L, "type", "Quit");
+ break;
+
+ case EventType::KEY_DOWN:
+ case EventType::KEY_UP:
+ luax_setfieldstring(L, "type", e.type == EventType::KEY_DOWN ? "KeyDown" : "KeyUp");
+ luax_setfieldstring(L, "key", getKeyName(e.key.keysym.sym));
+ break;
+
+ case EventType::MOUSE_MOTION:
+ luax_setfieldstring(L, "type", "MouseMotion");
+ luax_setfieldnumber(L, "x", e.motion.x);
+ luax_setfieldnumber(L, "y", e.motion.y);
+ break;
+
+ case EventType::MOUSE_BUTTON_DOWN:
+ case EventType::MOUSE_BUTTON_UP:
+ luax_setfieldstring(L, "type", e.type == EventType::MOUSE_BUTTON_DOWN ? "MouseButtonDown" : "MouseButtonUp");
+ luax_setfieldstring(L, "button", getButtonName(e.button.button));
+ luax_setfieldnumber(L, "x", e.button.x);
+ luax_setfieldnumber(L, "y", e.button.y);
+ break;
+
+ case EventType::MOUSE_WHEEL:
+ luax_setfieldstring(L, "type", "Wheel");
+ if(e.wheel.x == -1)
+ luax_setfieldstring(L, "x", "Left");
+ else if(e.wheel.x == 1)
+ luax_setfieldstring(L, "x", "Right");
+ else
+ luax_setfieldstring(L, "x", "None");
+ if (e.wheel.y == -1)
+ luax_setfieldstring(L, "y", "Near");
+ else if (e.wheel.y == 1)
+ luax_setfieldstring(L, "y", "Far");
+ else
+ luax_setfieldstring(L, "y", "None");
+ break;
+
+ case EventType::JOYBUTTONDOWN:
+ case EventType::JOYBUTTONUP:
+ luax_setfieldstring(L, "type", e.type == EventType::JOYBUTTONDOWN ? "JoyButtonDown" : "JoyButtonUp");
+ luax_setfieldinteger(L, "which", e.jbutton.which);
+ luax_setfieldstring(L, "button", Input::getJoyButtonName(e.jbutton.button));
+ break;
+
+ case EventType::JOYAXISMOTION:
+ luax_setfieldstring(L, "type", "JoyAxisMotion");
+ luax_setfieldinteger(L, "which", e.jaxis.which);
+ luax_setfieldfstring(L, "axis", Input::getJoyAxisName(e.jaxis.axis));
+ break;
+
+ case EventType::JOYBALLMOTION:
+ case EventType::JOYHATMOTION:
+
+ case EventType::JOYDEVICEADDED:
+ case EventType::JOYDEVICEREMOVED:
+ luax_setfieldfstring(L, "type", e.type == EventType::JOYDEVICEADDED ? "JoyDeviceAdded" : "JoyDeviceRemoved");
+ luax_setfieldinteger(L, "which", e.jdevice.which);
+ break;
+
+ //https://stackoverflow.com/questions/50022316/what-is-sdl-joystick-and-what-is-sdl-gamecontroller-what-are-the-relationships
+ case EventType::CONTROLLERBUTTONDOWN:
+ case EventType::CONTROLLERBUTTONUP:
+
+
+ case EventType::CONTROLLERAXISMOTION:
+
+ default:
+ // Ignore oter events and pop up the event table.
+ luax_pop(L, 1);
+ goto poll;
+ break;
+ }
+ luax_rawseti(L, -2, i++);
+ }
+ return 1;
+ }
+
+ /**
+ * load event module
+ */
+ LUA_EXPORT int luaopen_event(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "poll", l_event_poll },
+ { 0, 0 }
+ };
+ luax_newlib(L, methods);
+
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/event/je_lua_event.h b/src/libjin-lua/modules/event/je_lua_event.h
new file mode 100644
index 0000000..7a75459
--- /dev/null
+++ b/src/libjin-lua/modules/event/je_lua_event.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_EVENT_H__
+#define __JE_LUA_EVENT_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_event(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/filesystem/je_lua_filesystem.cpp b/src/libjin-lua/modules/filesystem/je_lua_filesystem.cpp
new file mode 100644
index 0000000..e73d1ad
--- /dev/null
+++ b/src/libjin-lua/modules/filesystem/je_lua_filesystem.cpp
@@ -0,0 +1,140 @@
+#include "common/je_lua_common.h"
+#include "common/je_lua.h"
+#include "libjin/jin.h"
+#include <string>
+
+using namespace JinEngine::Filesystem;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ LUA_IMPLEMENT struct
+ {
+ AssetDatabase* fs;
+ } context;
+
+ LUA_IMPLEMENT int l_init(lua_State* L)
+ {
+ context.fs = AssetDatabase::get();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_mount(lua_State* L)
+ {
+ const char* path = luax_checkstring(L, 1);
+ context.fs->mount(path);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_exist(lua_State * L)
+ {
+ const char* path = luax_checkstring(L, 1);
+ int r = context.fs->exists(path);
+ luax_pushboolean(L, r);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_isDir(lua_State* L)
+ {
+ const char* path = luax_checkstring(L, 1);
+ int r = context.fs->isDir(path);
+ luax_pushboolean(L, r);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_isFile(lua_State* L)
+ {
+ const char* path = luax_checkstring(L, 1);
+ int r = context.fs->isFile(path);
+ luax_pushboolean(L, r);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int loadbuffer(lua_State* L)
+ {
+ const char* filename = lua_tostring(L, -1);
+ Buffer bf;
+ context.fs->read(filename, bf);
+ luax_loadbuffer(L, (const char*)&bf, bf.size(), filename);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int loader(lua_State* L)
+ {
+ const char * filename = lua_tostring(L, -1);
+
+ std::string tmp(filename);
+ tmp += ".lua";
+
+ int size = tmp.size();
+
+ for (int i = 0; i<size - 4; ++i)
+ {
+ if (tmp[i] == '.')
+ {
+ tmp[i] = '/';
+ }
+ }
+
+ if (context.fs->exists(tmp.c_str()))
+ {
+ lua_pop(L, 1);
+ lua_pushstring(L, tmp.c_str());
+ return loadbuffer(L);
+ }
+
+ tmp = filename;
+ size = tmp.size();
+ for (int i = 0; i<size; ++i)
+ {
+ if (tmp[i] == '.')
+ tmp[i] = '/';
+ }
+
+ if (context.fs->isDir(tmp.c_str()))
+ {
+ tmp += "/init.lua";
+ if (context.fs->exists(tmp.c_str()))
+ {
+ lua_pop(L, 1);
+ lua_pushstring(L, tmp.c_str());
+ return loadbuffer(L);
+ }
+ }
+
+ lua_pushfstring(L, "\n\tno file \"%s\" in jin game directories.\n", (tmp + ".lua").c_str());
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_read(lua_State* L)
+ {
+ AssetDatabase* fs = context.fs;
+ const char* file = luax_checkstring(L, 1);
+ unsigned int len;
+ Buffer buffer;
+ fs->read(file, buffer);
+ luax_pushstring(L, (char*)&buffer);
+ luax_pushinteger(L, buffer.size());
+ return 2;
+ }
+
+ LUA_EXPORT int luaopen_filesystem(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "init", l_init },
+ { "mount", l_mount },
+ { "isDirectory", l_isDir },
+ { "isFile", l_isFile },
+ { "exist", l_exist },
+ { "read", l_read },
+ { 0, 0 }
+ };
+ luax_newlib(L, methods);
+ luax_registersearcher(L, loader, 1);
+ return 0;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/filesystem/je_lua_filesystem.h b/src/libjin-lua/modules/filesystem/je_lua_filesystem.h
new file mode 100644
index 0000000..1e1ff23
--- /dev/null
+++ b/src/libjin-lua/modules/filesystem/je_lua_filesystem.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_FILESYSTEM_H__
+#define __JE_LUA_FILESYSTEM_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_filesystem(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_animation.cpp b/src/libjin-lua/modules/graphics/je_lua_animation.cpp
new file mode 100644
index 0000000..5cd3b1f
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_animation.cpp
@@ -0,0 +1,122 @@
+#include "libjin/jin.h"
+
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+
+#include "je_lua_sprite.h"
+#include "je_lua_canvas.h"
+#include "je_lua_texture.h"
+#include "je_lua_shader.h"
+#include "je_lua_animation.h"
+
+using namespace JinEngine::Math;
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Shaders;
+using namespace JinEngine::Graphics::Animations;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+ const char* Jin_Lua_Animation = "Animation";
+
+ LUA_IMPLEMENT inline Animation* checkAnimation(lua_State* L)
+ {
+ LuaObject* luaObj = luax_checkobject(L, 1, Jin_Lua_Animation);
+ return luaObj->getObject<Animation>();
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animation);
+ p->release();
+ return 0;
+ }
+
+ // addFrame(frame)
+ LUA_IMPLEMENT int l_addFrame(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animation);
+ Animation* animation = luaObj->getObject<Animation>();
+ LuaObject* luaSprite = (LuaObject*)luax_checktype(L, 2, Jin_Lua_Sprite);
+ Sprite* sprite = luaSprite->getObject<Sprite>();
+ animation->addFrame(sprite);
+ int i = animation->getFrameCount() - 1;
+ luaObj->setDependency((int)AnimationDependency::DEP_SPRITES + i, luaSprite);
+ return 0;
+ }
+
+ // addFrames(frames table)
+ LUA_IMPLEMENT int l_addFrames(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animation);
+ Animation* shrAnimation = luaObj->getObject<Animation>();
+ if (!luax_istable(L, 2))
+ {
+ luax_typerror(L, 2, "sprites table");
+ return 1;
+ }
+ int n = luax_tableidxlen(L, 2);
+ for (int i = 1; i <= n; ++i)
+ {
+ luax_rawgeti(L, 2, i);
+ LuaObject* luaSprite = (LuaObject*)luax_checktype(L, -1, Jin_Lua_Sprite);
+ Sprite* sprite = luaSprite->getObject<Sprite>();
+ shrAnimation->addFrame(sprite);
+ int index = shrAnimation->getFrameCount() - 1;
+ luaObj->setDependency((int)AnimationDependency::DEP_SPRITES + index, luaSprite);
+ }
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_isLoop(lua_State* L)
+ {
+ Animation* shrAnimation = checkAnimation(L);
+ bool loop = shrAnimation->isLoop();
+ luax_pushboolean(L, loop);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getSpeed(lua_State* L)
+ {
+ Animation* shrAnimation = checkAnimation(L);
+ float speed = shrAnimation->getSpeed();
+ luax_pushnumber(L, speed);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getFrame(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animation);
+ Animation* shrAnimation = luaObj->getObject<Animation>();
+ int i = luax_checkinteger(L, 2);
+ LuaObject* frame = luaObj->getDependency((int)AnimationDependency::DEP_SPRITES + i);
+ luax_getobject(L, frame);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int getFrameCount(lua_State* L)
+ {
+ Animation* shrAnimation = checkAnimation(L);
+ int n = shrAnimation->getFrameCount();
+ luax_pushinteger(L, n);
+ return 1;
+ }
+
+ LUA_EXPORT void luaopen_Animation(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "addFrame", l_addFrame },
+ { "addFrames", l_addFrames },
+ { "isLoop", l_isLoop },
+ { "getSpeed", l_getSpeed },
+ { "getFrameCount", getFrameCount },
+ { "getFrame", l_getFrame },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Animation, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_animation.h b/src/libjin-lua/modules/graphics/je_lua_animation.h
new file mode 100644
index 0000000..1b32ec3
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_animation.h
@@ -0,0 +1,24 @@
+#ifndef __JE_LUA_ANIMATION_H__
+#define __JE_LUA_ANIMATION_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Animation;
+
+ ///
+ ///
+ ///
+ enum class AnimationDependency
+ {
+ DEP_SPRITES = 1 ///< Index from 1
+ };
+
+ void luaopen_Animation(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_animator.cpp b/src/libjin-lua/modules/graphics/je_lua_animator.cpp
new file mode 100644
index 0000000..94c61b5
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_animator.cpp
@@ -0,0 +1,163 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+#include "je_lua_sprite.h"
+#include "je_lua_canvas.h"
+#include "je_lua_texture.h"
+#include "je_lua_shader.h"
+#include "je_lua_animator.h"
+#include "je_lua_animation.h"
+
+using namespace JinEngine::Math;
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Shaders;
+using namespace JinEngine::Graphics::Animations;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+ const char* Jin_Lua_Animator = "Animator";
+
+ LUA_IMPLEMENT inline Animator* checkAnimator(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animator);
+ return luaObj->getObject<Animator>();
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* obj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animation);
+ obj->release();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_update(lua_State* L)
+ {
+ Animator* animator = checkAnimator(L);
+ float dt = luax_checknumber(L, 2);
+ animator->update(dt);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_play(lua_State* L)
+ {
+ Animator* animator = checkAnimator(L);
+ animator->play();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_pause(lua_State* L)
+ {
+ Animator* animator = checkAnimator(L);
+ animator->pause();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_resume(lua_State* L)
+ {
+ Animator* animator = checkAnimator(L);
+ animator->resume();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_rewind(lua_State* L)
+ {
+ Animator* animator = checkAnimator(L);
+ animator->rewind();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_render(lua_State* L)
+ {
+ Animator* animator = checkAnimator(L);
+ float x = luax_checknumber(L, 2);
+ float y = luax_checknumber(L, 3);
+ float sx = luax_checknumber(L, 4);
+ float sy = luax_checknumber(L, 5);
+ float r = luax_checknumber(L, 6);
+ animator->render(x, y, sx, sy, r);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setAnimation(lua_State* L)
+ {
+ LuaObject* luaAnimator = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animator);
+ Animator* animator = luaAnimator->getObject<Animator>();
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animation);
+ luaAnimator->setDependency((int)AnimatorDependency::DEP_ANIMATION, luaObj);
+ animator->setAnimation(luaObj->getObject<Animation>());
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_forceToFrame(lua_State* L)
+ {
+ Animator* shrAnimator = checkAnimator(L);
+ int index = luax_checkinteger(L, 2);
+ shrAnimator->forceToFrame(index);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setSpeed(lua_State* L)
+ {
+ Animator* shrAnimator = checkAnimator(L);
+ float fps = luax_checknumber(L, 2);
+ shrAnimator->setSpeed(fps);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setDefaultSpeed(lua_State* L)
+ {
+ Animator* shrAnimator = checkAnimator(L);
+ shrAnimator->setDefaultSpeed();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setLoop(lua_State* L)
+ {
+ Animator* shrAnimator = checkAnimator(L);
+ bool loop = luax_checkbool(L, 2);
+ shrAnimator->setLoop(loop);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setDefaultLoop(lua_State* L)
+ {
+ Animator* shrAnimator = checkAnimator(L);
+ shrAnimator->setDefaultLoop();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_getSpeed(lua_State* L)
+ {
+ Animator* shrAnimator = checkAnimator(L);
+ float speed = shrAnimator->getSpeed();
+ luax_pushnumber(L, speed);
+ return 1;
+ }
+
+ LUA_EXPORT void luaopen_Animator(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "update", l_update },
+ { "play", l_play },
+ { "pause", l_pause },
+ { "resume", l_resume },
+ { "rewind", l_rewind },
+ { "render", l_render },
+ { "setAnimation", l_setAnimation },
+ { "forceToFrame", l_forceToFrame },
+ { "setSpeed", l_setSpeed },
+ { "setDefaultSpeed", l_setDefaultSpeed },
+ { "setLoop", l_setLoop },
+ { "setDefaultLoop", l_setDefaultLoop },
+ { "getSpeed", l_getSpeed },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Animator, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_animator.h b/src/libjin-lua/modules/graphics/je_lua_animator.h
new file mode 100644
index 0000000..0292a77
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_animator.h
@@ -0,0 +1,23 @@
+#ifndef __JE_LUA_ANIMATOR_H__
+#define __JE_LUA_ANIMATOR_H__
+
+#include "libjin/jin.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Animator;
+
+ enum class AnimatorDependency
+ {
+ DEP_ANIMATION = 1
+ };
+
+ void luaopen_Animator(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_bitmap.cpp b/src/libjin-lua/modules/graphics/je_lua_bitmap.cpp
new file mode 100644
index 0000000..553c786
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_bitmap.cpp
@@ -0,0 +1,110 @@
+#include "common/je_lua_common.h"
+#include "common/je_lua_object.h"
+
+#include "libjin/jin.h"
+#include "je_lua_bitmap.h"
+
+using namespace JinEngine::Graphics;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Bitmap = "Bitmap";
+
+ LUA_IMPLEMENT inline Bitmap* checkBitmap(lua_State* L)
+ {
+ LuaObject* luaObj = luax_checkobject(L, 1, Jin_Lua_Bitmap);
+ return luaObj->getObject<Bitmap>();
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Bitmap);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_getWidth(lua_State* L)
+ {
+ Bitmap* bitmap = checkBitmap(L);
+ int w = bitmap->getWidth();
+ luax_pushinteger(L, w);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getHeight(lua_State* L)
+ {
+ Bitmap* bitmap = checkBitmap(L);
+ int h = bitmap->getHeight();
+ luax_pushinteger(L, h);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getSize(lua_State* L)
+ {
+ Bitmap* bitmap = checkBitmap(L);
+ int w = bitmap->getWidth();
+ int h = bitmap->getHeight();
+ luax_pushinteger(L, w);
+ luax_pushinteger(L, h);
+ return 2;
+ }
+
+ LUA_IMPLEMENT int l_getPixel(lua_State* L)
+ {
+ Bitmap* bitmap = checkBitmap(L);
+ int x = luax_checkinteger(L, 2);
+ int y = luax_checkinteger(L, 3);
+ Color col = bitmap->getPixel(x, y);
+ luax_pushinteger(L, col.r);
+ luax_pushinteger(L, col.g);
+ luax_pushinteger(L, col.b);
+ luax_pushinteger(L, col.a);
+ return 4;
+ }
+
+ LUA_IMPLEMENT int l_setPixel(lua_State* L)
+ {
+ Bitmap* bitmap = checkBitmap(L);
+ int x = luax_checkinteger(L, 2);
+ int y = luax_checkinteger(L, 3);
+ if (!luax_istable(L, 4))
+ {
+ luax_typerror(L, 4, "table");
+ return 1;
+ }
+ unsigned int r = luax_rawgetnumber(L, 4, 1);
+ unsigned int g = luax_rawgetnumber(L, 4, 2);
+ unsigned int b = luax_rawgetnumber(L, 4, 3);
+ unsigned int a = luax_rawgetnumber(L, 4, 4);
+ bitmap->setPixel(Color(r, g, b, a), x, y);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_clone(lua_State* L)
+ {
+ Bitmap* bitmap = checkBitmap(L);
+ Bitmap* b = bitmap->clone();
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Bitmap, new Shared(b));
+ return 1;
+ }
+
+ LUA_EXPORT void luaopen_Bitmap(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "getWidth", l_getWidth },
+ { "getHeight", l_getHeight },
+ { "getSize", l_getSize },
+ { "getPixel", l_getPixel },
+ { "setPixel", l_setPixel },
+ { "clone", l_clone },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Bitmap, methods);
+ }
+
+ } // namespace Graphics
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_bitmap.h b/src/libjin-lua/modules/graphics/je_lua_bitmap.h
new file mode 100644
index 0000000..b463d83
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_bitmap.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_BITMAP_H__
+#define __JE_LUA_BITMAP_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Bitmap;
+
+ void luaopen_Bitmap(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_canvas.cpp b/src/libjin-lua/modules/graphics/je_lua_canvas.cpp
new file mode 100644
index 0000000..97b3c96
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_canvas.cpp
@@ -0,0 +1,63 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+#include "je_lua_canvas.h"
+
+using namespace JinEngine::Graphics;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Canvas = "Canvas";
+
+ LUA_IMPLEMENT inline Canvas* checkCanvas(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Canvas);
+ return luaObj->getObject<Canvas>();
+ }
+
+ LUA_IMPLEMENT int l_getWidth(lua_State* L)
+ {
+ Canvas* canvas = checkCanvas(L);
+ luax_pushnumber(L, canvas->getWidth());
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getHeight(lua_State* L)
+ {
+ Canvas* canvas = checkCanvas(L);
+ luax_pushnumber(L, canvas->getHeight());
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getSize(lua_State* L)
+ {
+ Canvas* canvas = checkCanvas(L);
+ luax_pushnumber(L, canvas->getWidth());
+ luax_pushnumber(L, canvas->getHeight());
+ return 2;
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Canvas);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_Canvas(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "getWidth", l_getWidth },
+ { "getHeight", l_getHeight },
+ { "getSize", l_getSize },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Canvas, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_canvas.h b/src/libjin-lua/modules/graphics/je_lua_canvas.h
new file mode 100644
index 0000000..d1fa885
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_canvas.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_CANVAS_H__
+#define __JE_LUA_CANVAS_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Canvas;
+
+ void luaopen_Canvas(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_graphics.cpp b/src/libjin-lua/modules/graphics/je_lua_graphics.cpp
new file mode 100644
index 0000000..fba77d7
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_graphics.cpp
@@ -0,0 +1,1048 @@
+#include <iostream>
+#include <fstream>
+
+#include "libjin/jin.h"
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+
+#include "je_lua_canvas.h"
+#include "je_lua_sprite.h"
+#include "je_lua_spritesheet.h"
+#include "je_lua_bitmap.h"
+#include "je_lua_ttf.h"
+#include "je_lua_ttf_data.h"
+#include "je_lua_texture.h"
+#include "je_lua_shader.h"
+#include "je_lua_text.h"
+#include "je_lua_texture_font.h"
+#include "je_lua_page.h"
+#include "je_lua_sprite.h"
+#include "je_lua_animation.h"
+#include "je_lua_animator.h"
+#include "je_lua_particle_system.h"
+
+using namespace std;
+using namespace JinEngine;
+using namespace JinEngine::Math;
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Fonts;
+using namespace JinEngine::Graphics::Shaders;
+using namespace JinEngine::Graphics::Animations;
+using namespace JinEngine::Graphics::Particles;
+using namespace JinEngine::Filesystem;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ #include "../../resources/font.ttf.h"
+
+ static struct
+ {
+ Color curRenderColor;
+ Color curClearColor;
+ Font* defaultFont = nullptr;
+ bool initialized = false;
+ } context;
+
+ LUA_IMPLEMENT int l_init(lua_State* L)
+ {
+ if (context.initialized)
+ {
+ luax_pushboolean(L, true);
+ return 1;
+ }
+
+ Window* wnd = Window::get();
+ Window::Setting setting;
+ setting.width = luax_getfieldinteger(L, 1, "width");
+ setting.height = luax_getfieldinteger(L, 1, "height");
+ setting.title = luax_getfieldstring(L, 1, "title");
+ setting.icon = luax_getfieldstring(L, 1, "icon");
+ setting.vsync = luax_getfieldbool(L, 1, "vsync");
+ setting.fullscreen = luax_getfieldbool(L, 1, "fullscreen");
+ setting.resizable = luax_getfieldbool(L, 1, "resizable");
+ context.initialized = wnd->start(&setting);
+ if (!context.initialized)
+ {
+ luax_pushboolean(L, context.initialized);
+ return 1;
+ }
+
+ /* load default font */
+ Bitmap* bitmap = new Bitmap(default_font_bitmap, sizeof(default_font_bitmap));
+ TextureFont* tf = new TextureFont(bitmap, Text(Encode::UTF8, default_charset), default_font_split, bitmap->getHeight());
+ delete bitmap;
+ context.defaultFont = tf;
+ gl.setFont(tf);
+
+ luax_pushboolean(L, context.initialized);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_setTitle(lua_State* L)
+ {
+ Window* wnd = Window::get();
+ const char* title = luax_checkstring(L, 1);
+ wnd->setTitle(title);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_destroy(lua_State* L)
+ {
+ Window* wnd = Window::get();
+ wnd->quit();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_showWindow(lua_State* L)
+ {
+ Window* wnd = Window::get();
+ wnd->show();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_hideWindow(lua_State* L)
+ {
+ Window* wnd = Window::get();
+ wnd->hide();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_getSize(lua_State* L)
+ {
+ Window* wnd = Window::get();
+ luax_pushnumber(L, wnd->getW());
+ luax_pushnumber(L, wnd->getH());
+ return 2;
+ }
+
+ LUA_IMPLEMENT int l_getWidth(lua_State* L)
+ {
+ Window* wnd = Window::get();
+ luax_pushnumber(L, wnd->getW());
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getHeight(lua_State* L)
+ {
+ Window* wnd = Window::get();
+ luax_pushnumber(L, wnd->getH());
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_newBitmap(lua_State* L)
+ {
+ Bitmap* bitmap = nullptr;
+ if (luax_gettop(L) == 2)
+ {
+ int w = luax_checkinteger(L, 1);
+ int h = luax_checkinteger(L, 2);
+ bitmap = new Bitmap(w, h);
+ }
+ else if (luax_gettop(L) == 3)
+ {
+ int w = luax_checkinteger(L, 1);
+ int h = luax_checkinteger(L, 2);
+ if (luax_istable(L, 3))
+ {
+ unsigned int r = luax_rawgetnumber(L, 3, 1);
+ unsigned int g = luax_rawgetnumber(L, 3, 2);
+ unsigned int b = luax_rawgetnumber(L, 3, 3);
+ unsigned int a = luax_rawgetnumber(L, 3, 4);
+ bitmap = new Bitmap(w, h, Color(r, g, b, a));
+ }
+ else if (luax_isfunction(L, 3))
+ {
+ std::function<Color(int, int, int, int)> drawer = [=](int w, int h, int x, int y)->Color{
+ luax_pushvalue(L, 3);
+ luax_pushnumber(L, w);
+ luax_pushnumber(L, h);
+ luax_pushnumber(L, x);
+ luax_pushnumber(L, y);
+ // Call drawer function.
+ luax_call(L, 4, 1);
+ // Get result color.
+ if (!luax_istable(L, -1))
+ luax_error(L, "Return value of bitmap drawer is wrong, should be a color table.");
+ Color c;
+ c.r = luax_rawgetnumberthenpop(L, -1, 1);
+ c.g = luax_rawgetnumberthenpop(L, -1, 2);
+ c.b = luax_rawgetnumberthenpop(L, -1, 3);
+ c.a = luax_rawgetnumberthenpop(L, -1, 4);
+ // Pop return value.
+ luax_pop(L, 1);
+ return c;
+ };
+ bitmap = new Bitmap(w, h, drawer);
+ }
+ else
+ {
+ luax_typerror(L, 3, "color table or color setter");
+ return 1;
+ }
+ }
+ else
+ {
+ const char* f = luax_checkstring(L, 1);
+ AssetDatabase* fs = AssetDatabase::get();
+ Buffer b;
+ try
+ {
+ if (!fs->exists(f))
+ throw Exception("No such image file %s.", f);
+ fs->read(f, b);
+ }
+ catch (Exception& e)
+ {
+ error(L, "Failed to read image %s", f);
+ luax_pushnil(L);
+ return 1;
+ }
+ bitmap = new Bitmap(&b, b.size());
+ if (bitmap == nullptr)
+ {
+ error(L, "Failed to decode image file %s", f);
+ luax_pushnil(L);
+ return 1;
+ }
+ }
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Bitmap, new Shared(bitmap));
+ return 1;
+ }
+
+ /* jin.graphics.newTexture(bitmap) */
+ LUA_IMPLEMENT int l_newTexture(lua_State* L)
+ {
+ Texture* texture = nullptr;
+ if (luax_istype(L, 1, Jin_Lua_Bitmap))
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Bitmap);
+ Bitmap* bitmap = luaObj->getObject<Bitmap>();
+ texture = new Texture(bitmap);
+ }
+ else if (luax_isstring(L, 1))
+ {
+ const char* path = luax_checkstring(L, 1);
+ texture = new Texture(path);
+ }
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Texture, new Shared(texture));
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_newShader(lua_State* L)
+ {
+ const char* program = luax_checkstring(L, 1);
+ Shader* jsl = new Shader(program);
+ if (jsl == nullptr)
+ {
+ error(L, "Failed to compile shader");
+ luax_pushnil(L);
+ return 1;
+ }
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Shader, new Shared(jsl));
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_newShaderf(lua_State* L)
+ {
+ const char* path = luax_checkstring(L, 1);
+ AssetDatabase* fs = AssetDatabase::get();
+ if (!fs->exists(path))
+ {
+ error(L, "No such shader file \"%s\"", path);
+ luax_pushnil(L);
+ return 1;
+ }
+ Buffer b;
+ fs->read(path, b);
+ Shader* jsl = new Shader((char*)&b);
+ if (jsl == nullptr)
+ {
+ error(L, "Failed to compile shader");
+ luax_pushnil(L);
+ return 1;
+ }
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Shader, new Shared(jsl));
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_newCanvas(lua_State* L)
+ {
+ int w = luax_checknumber(L, 1);
+ int h = luax_checknumber(L, 2);
+ Canvas* cvs = new Canvas(w, h);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Canvas, new Shared(cvs));
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_clear(lua_State* L)
+ {
+ glClear(GL_COLOR_BUFFER_BIT);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setClearColor(lua_State* L)
+ {
+ if (luax_gettop(L) == 0)
+ {
+ glClearColor(0, 0, 0, 1);
+ return 0;
+ }
+
+ context.curClearColor.r = luax_checknumber(L, 1);
+ context.curClearColor.g = luax_checknumber(L, 2);
+ context.curClearColor.b = luax_checknumber(L, 3);
+ context.curClearColor.a = luax_checknumber(L, 4);
+
+ gl.setClearColor(context.curClearColor.r,
+ context.curClearColor.g,
+ context.curClearColor.b,
+ context.curClearColor.a);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_present(lua_State* L)
+ {
+ Window::get()->swapBuffers();
+ return 0;
+ }
+
+ LUA_IMPLEMENT void l_draw_texture(lua_State* L)
+ {
+ if (!luax_istype(L, 1, Jin_Lua_Texture))
+ return;
+ int x = luax_optnumber(L, 2, 0);
+ int y = luax_optnumber(L, 3, 0);
+ float sx = luax_optnumber(L, 4, 1);
+ float sy = luax_optnumber(L, 5, 1);
+ float r = luax_optnumber(L, 6, 0);
+ float ox = luax_optnumber(L, 7, 0);
+ float oy = luax_optnumber(L, 8, 0);
+ LuaObject* luaObj = (LuaObject*)luax_toudata(L, 1);
+ Texture* tex = luaObj->getObject<Texture>();
+ tex->render(x, y, sx, sy, r, ox, oy);
+ }
+
+ LUA_IMPLEMENT void l_draw_canvas(lua_State* L)
+ {
+ if (!luax_istype(L, 1, Jin_Lua_Canvas))
+ return;
+ int x = luax_optnumber(L, 2, 0);
+ int y = luax_optnumber(L, 3, 0);
+ float sx = luax_optnumber(L, 4, 1);
+ float sy = luax_optnumber(L, 5, 1);
+ float r = luax_optnumber(L, 6, 0);
+ float ox = luax_optnumber(L, 7, 0);
+ float oy = luax_optnumber(L, 8, 0);
+ LuaObject* luaObj = (LuaObject*)luax_toudata(L, 1);
+ Canvas* canvas = luaObj->getObject<Canvas>();
+ canvas->render(x, y, sx, sy, r, ox, oy);
+ }
+
+ /* jin.graphics.draw(text, font, x, y) */
+ LUA_IMPLEMENT void l_draw_text(lua_State* L)
+ {
+ if (!luax_istype(L, 1, Jin_Lua_Text))
+ return;
+ LuaObject* p = (LuaObject*)luax_toudata(L, 1);
+ Text* text = p->getObject<Text>();
+ int x = luax_optnumber(L, 3, 0);
+ int y = luax_optnumber(L, 4, 0);
+ int spacing = luax_optnumber(L, 6, 0);
+ Font* font = nullptr;
+ LuaObject* p2 = (LuaObject*)luax_toudata(L, 2);
+ if (luax_istype(L, 2, Jin_Lua_TextureFont))
+ {
+ TextureFont* tf = p2->getObject<TextureFont>();
+ font = tf;
+ }
+ else if (luax_istype(L, 2, Jin_Lua_TTF))
+ {
+ TTF* ttf = p2->getObject<TTF>();
+ font = ttf;
+ }
+ else
+ {
+ font = context.defaultFont;
+ }
+ int lineheight = luax_optnumber(L, 5, font->getFontSize());
+ font->render(*text, x, y, lineheight, spacing);
+ }
+
+ /* jin.graphics.draw(page, x, y) */
+ LUA_IMPLEMENT void l_draw_page(lua_State* L)
+ {
+ if (!luax_istype(L, 1, Jin_Lua_Page))
+ return;
+ int x = luax_optnumber(L, 2, 0);
+ int y = luax_optnumber(L, 3, 0);
+ LuaObject* p = (LuaObject*)luax_toudata(L, 1);
+ Page* page = p->getObject<Page>();
+ Font* font = page->font;
+ font->render(page, x, y);
+ }
+
+ LUA_IMPLEMENT void l_draw_sprite(lua_State* L)
+ {
+ if (!luax_istype(L, 1, Jin_Lua_Sprite))
+ return;
+ LuaObject* luaSprite = (LuaObject*)luax_toudata(L, 1);
+ Sprite* sprite = luaSprite->getObject<Sprite>();
+ float x = luax_checknumber(L, 2);
+ float y = luax_checknumber(L, 3);
+ float sx = luax_checknumber(L, 4);
+ float sy = luax_checknumber(L, 5);
+ float r = luax_checknumber(L, 6);
+ sprite->render(x, y, sx, sy, r);
+ }
+
+ LUA_IMPLEMENT int l_draw(lua_State* L)
+ {
+ if (luax_istype(L, 1, Jin_Lua_Texture))
+ l_draw_texture(L);
+ else if (luax_istype(L, 1, Jin_Lua_Canvas))
+ l_draw_canvas(L);
+ else if (luax_istype(L, 1, Jin_Lua_Text))
+ l_draw_text(L);
+ else if (luax_istype(L, 1, Jin_Lua_Page))
+ l_draw_page(L);
+ else if (luax_istype(L, 1, Jin_Lua_Sprite))
+ l_draw_sprite(L);
+ else
+ {
+ luax_typerror(L, 1, "texture or canvas");
+ return 1;
+ }
+ return 0;
+ }
+
+ // draw(tex, quad, x, y, sx, sy, r, ax, ay)
+ LUA_IMPLEMENT int l_drawq(lua_State* L)
+ {
+ if (!luax_istable(L, 2))
+ {
+ luax_typerror(L, 2, "table");
+ return 1;
+ }
+ Math::Quad q;
+ q.x = luax_rawgetnumber(L, 2, 1);
+ q.y = luax_rawgetnumber(L, 2, 2);
+ q.w = luax_rawgetnumber(L, 2, 3);
+ q.h = luax_rawgetnumber(L, 2, 4);
+ luax_pop(L, 4);
+ int x = luax_optnumber(L, 3, 0);
+ int y = luax_optnumber(L, 4, 0);
+ float sx = luax_optnumber(L, 5, 1);
+ float sy = luax_optnumber(L, 6, 1);
+ float r = luax_optnumber(L, 7, 0);
+ float ox = luax_optnumber(L, 8, 0);
+ float oy = luax_optnumber(L, 9, 0);
+
+ if (luax_istype(L, 1, Jin_Lua_Texture))
+ {
+ LuaObject* luaObj = (LuaObject*)luax_toudata(L, 1);
+ Texture* tex = luaObj->getObject<Texture>();
+ tex->render(q, x, y, sx, sy, r, ox, oy);
+ }
+ else if (luax_istype(L, 1, Jin_Lua_Canvas))
+ {
+ LuaObject* luaObj = (LuaObject*)luax_toudata(L, 1);
+ Canvas* canvas = luaObj->getObject<Canvas>();
+ canvas->render(q, x, y, sx, sy, r, ox, oy);
+ }
+ else
+ {
+ luax_typerror(L, 1, "texture or canvas");
+ }
+ }
+
+ /* print(string, x, y, lineheight, spacing) */
+ /* need set font */
+ LUA_IMPLEMENT int l_print(lua_State* L)
+ {
+ Font* font = gl.getFont();
+ if (font == nullptr)
+ return 0;
+ unsigned length;
+ const char* str = luax_checklstring(L, 1, &length);
+ Text text(Encode::UTF8, str, length);
+ int x = luax_optnumber(L, 2, 0);
+ int y = luax_optnumber(L, 3, 0);
+ int lineheight = luax_optnumber(L, 4, font->getFontSize());
+ int spacing = luax_optnumber(L, 5, 0);
+ font->render(text, x, y, lineheight, spacing);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setColor(lua_State* L)
+ {
+ if (luax_gettop(L) == 0)
+ {
+ gl.setColor(Color(255, 255, 255, 255));
+ return 0;
+ }
+
+ context.curRenderColor.r = luax_checknumber(L, 1);
+ context.curRenderColor.g = luax_checknumber(L, 2);
+ context.curRenderColor.b = luax_checknumber(L, 3);
+ if (luax_gettop(L) == 4)
+ context.curRenderColor.a = luax_checknumber(L, 4);
+ else
+ context.curRenderColor.a = 255;
+ gl.setColor(context.curRenderColor);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_getColor(lua_State * L)
+ {
+ luax_pushnumber(L, context.curRenderColor.r);
+ luax_pushnumber(L, context.curRenderColor.g);
+ luax_pushnumber(L, context.curRenderColor.b);
+ luax_pushnumber(L, context.curRenderColor.a);
+ return 4;
+ }
+
+ LUA_IMPLEMENT int l_bindCanvas(lua_State* L)
+ {
+ if (luax_gettop(L) == 0)
+ {
+ // bind to default canvas
+ gl.unbindCanvas();
+ return 0;
+ }
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Canvas);
+ Canvas* canvas = luaObj->getObject<Canvas>();
+ gl.bindCanvas(canvas);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_unbindCanvas(lua_State* L)
+ {
+ gl.unbindCanvas();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_useShader(lua_State* L)
+ {
+ if (luax_gettop(L) == 0)
+ {
+ gl.unuseShader();
+ return 0;
+ }
+ if (luax_istype(L, 1, Jin_Lua_Shader))
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Shader);
+ Shader* shader = luaObj->getObject<Shader>();
+ gl.useShader(shader);
+ }
+ else
+ {
+ luax_typerror(L, 1, "JSL shader");
+ }
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setBlend(lua_State* L)
+ {
+
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_point(lua_State* L)
+ {
+ int x = luax_checknumber(L, 1);
+ int y = luax_checknumber(L, 2);
+ JinEngine::Graphics::point(x, y);
+
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_line(lua_State* L)
+ {
+ int x1 = luax_checknumber(L, 1);
+ int y1 = luax_checknumber(L, 2);
+ int x2 = luax_checknumber(L, 3);
+ int y2 = luax_checknumber(L, 4);
+ JinEngine::Graphics::line(x1, y1, x2, y2);
+
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_rect(lua_State* L)
+ {
+ RenderMode mode = static_cast<RenderMode>(luax_checkinteger(L, 1));
+ if (mode != RenderMode::NONE)
+ {
+ int x = luax_checknumber(L, 2);
+ int y = luax_checknumber(L, 3);
+ int w = luax_checknumber(L, 4);
+ int h = luax_checknumber(L, 5);
+ rect(mode, x, y, w, h);
+ }
+ else
+ {
+ luax_typerror(L, 1, "'fill' or 'line'");
+ return 1;
+ }
+
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_circle(lua_State* L)
+ {
+ RenderMode mode = static_cast<RenderMode>(luax_checkinteger(L, 1));
+ if (mode != RenderMode::NONE)
+ {
+ int x = luax_checknumber(L, 2);
+ int y = luax_checknumber(L, 3);
+ float r = luax_checknumber(L, 4);
+ circle(mode, x, y, r);
+ }
+ else
+ {
+ luax_typerror(L, 1, "'fill' or 'line'");
+ return 1;
+ }
+
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_triangle(lua_State* L)
+ {
+ RenderMode mode = static_cast<RenderMode>(luax_checkinteger(L, 1));
+ if (mode != RenderMode::NONE)
+ {
+ int x = luax_checknumber(L, 2);
+ int y = luax_checknumber(L, 3);
+
+ int x2 = luax_checknumber(L, 3);
+ int y2 = luax_checknumber(L, 4);
+
+ int x3 = luax_checknumber(L, 5);
+ int y3 = luax_checknumber(L, 6);
+
+ triangle(mode, x, y, x2, y2, x3, y3);
+ }
+ else
+ {
+ luax_typerror(L, 1, "'fill' or 'line'");
+ return 1;
+ }
+
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_polygon(lua_State* L)
+ {
+ RenderMode mode = static_cast<RenderMode>(luax_checkinteger(L, 1));
+ int n = luax_checknumber(L, 2);
+ if (mode != RenderMode::NONE)
+ {
+ if (!luax_istable(L, 3))
+ {
+ luax_typerror(L, 3, "table");
+ return 1;
+ }
+ int tn = luax_tableidxlen(L, 3);
+ if (tn != n * 2)
+ {
+ LUA_IMPLEMENT char* emsg = \
+ "number of polygon vertices doesn't match " \
+ "provided n, expect %d numbers but get %d";
+ luax_error(L, emsg, n * 2, tn);
+ return 1;
+ }
+ float* p = (float*)alloca(2 * n * sizeof(float));
+ for (int i = 1; i <= 2 * n; ++i)
+ p[i - 1] = luax_rawgetnumber(L, 3, i);
+ polygon(mode, p, n);
+ }
+ else
+ {
+ luax_typerror(L, 1, "'fill' or 'line'");
+ return 1;
+ }
+
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_newTTFData(lua_State* L)
+ {
+ TTFData* fd = nullptr;
+ {
+ const char* path = luax_checkstring(L, 1);
+ AssetDatabase* fs = AssetDatabase::get();
+ if (!fs->exists(path))
+ {
+ error(L, "No such font \"%s\"", path);
+ luax_pushnil(L);
+ return 1;
+ }
+ Buffer b;
+ fs->read(path, b);
+ fd = new TTFData(&b, b.size());
+ }
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_TTFData, new Shared(fd));
+ return 1;
+ }
+
+ /* newText(str[, encode]) */
+ LUA_IMPLEMENT int l_newText(lua_State* L)
+ {
+ Encode encode = Encode::UTF8;
+ if (luax_gettop(L) == 2)
+ {
+ const char* e = luax_checkstring(L, 2);
+ if (strcmp(e, "UTF8") == 0) encode = Encode::UTF8;
+ //else if (strcmp(e, "UTF16") == 0) encode = Encode::UTF16;
+ else if (strcmp(e, "ASCII") == 0) encode = Encode::ASCII;
+ else
+ {
+ luax_error(L, "wrong text encode %s", e);
+ return 0;
+ }
+ }
+ unsigned length;
+ const char* data = luax_checklstring(L, 1, &length);
+ Text* text = new Text(encode, data, length);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Text, new Shared(text));
+ return 1;
+ }
+
+ // newSprite(Texture tex, Quad quad, Origin origin)
+ // newSprite(Texture tex, Quad quad, Number ox, Number oy)
+ // newSprite(Texture tex, Origin origin)
+ // newSprite(Texture tex, Number ox, Number oy)
+ LUA_IMPLEMENT int l_newSprite(lua_State* L)
+ {
+ int n = luax_gettop(L);
+ LuaObject* objGraphic = nullptr;
+ if (luax_istype(L, 1, Jin_Lua_Texture))
+ objGraphic = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Texture);
+ else if (luax_istype(L, 1, Jin_Lua_Canvas))
+ objGraphic = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Canvas);
+ Graphic* graphic = objGraphic->getObject<Graphic>();
+ if (objGraphic != nullptr)
+ {
+ if (n == 3 && luax_istable(L, 2))
+ {
+ Quad quad;
+ quad.x = luax_rawgetnumberthenpop(L, 2, 1);
+ quad.y = luax_rawgetnumberthenpop(L, 2, 2);
+ quad.w = luax_rawgetnumberthenpop(L, 2, 3);
+ quad.h = luax_rawgetnumberthenpop(L, 2, 4);
+ int o = luax_checkinteger(L, 3);
+ Origin origin = static_cast<Origin>(o);
+ LuaObject* p = luax_newinstance(L, Jin_Lua_Sprite, new Shared(new Sprite(graphic, quad, origin)));
+ p->setDependency((int)SpriteDependency::DEP_GRAPHIC, objGraphic);
+ }
+ else if (n == 4)
+ {
+ Quad quad;
+ quad.x = luax_rawgetnumberthenpop(L, 2, 1);
+ quad.y = luax_rawgetnumberthenpop(L, 2, 2);
+ quad.w = luax_rawgetnumberthenpop(L, 2, 3);
+ quad.h = luax_rawgetnumberthenpop(L, 2, 4);
+ int ox = luax_checkinteger(L, 3);
+ int oy = luax_checkinteger(L, 4);
+ LuaObject* p = luax_newinstance(L, Jin_Lua_Sprite, new Shared(new Sprite(graphic, quad, ox, oy)));
+ p->setDependency((int)SpriteDependency::DEP_GRAPHIC, objGraphic);
+ }
+ else if (n == 2)
+ {
+ int o = luax_checkinteger(L, 2);
+ Origin origin = static_cast<Origin>(o);
+ LuaObject* p = luax_newinstance(L, Jin_Lua_Sprite, new Shared(new Sprite(graphic, origin)));
+ p->setDependency((int)SpriteDependency::DEP_GRAPHIC, objGraphic);
+ }
+ else if (n == 3)
+ {
+ int ox = luax_checkinteger(L, 2);
+ int oy = luax_checkinteger(L, 3);
+ LuaObject* p = luax_newinstance(L, Jin_Lua_Sprite, new Shared(new Sprite(graphic, ox, oy)));
+ p->setDependency((int)SpriteDependency::DEP_GRAPHIC, objGraphic);
+ }
+ else
+ {
+ luax_error(L, "No matched overloaded functions.");
+ return 1;
+ }
+ }
+
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_newSpriteSheet(lua_State* L)
+ {
+ LuaObject* objGraphic = nullptr;
+ if (luax_istype(L, 1, Jin_Lua_Texture))
+ objGraphic = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Texture);
+ else if(luax_istype(L, 1, Jin_Lua_Canvas))
+ objGraphic = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Canvas);
+ if (objGraphic != nullptr)
+ {
+ Graphic* graphic = objGraphic->getObject<Graphic>();
+ Shared* shrSSheet = new Shared(new SpriteSheet(graphic));
+ LuaObject* luaSSheet = luax_newinstance(L, Jin_Lua_SpriteSheet, shrSSheet);
+ luaSSheet->setDependency((int)SpriteSheetDependency::DEP_GRAPHIC, objGraphic);
+ return 1;
+ }
+ else
+ return 0;
+ }
+
+ // newAnimation([frames table, loop, speed])
+ LUA_IMPLEMENT int l_newAnimation(lua_State* L)
+ {
+ int argc = luax_gettop(L);
+ Animation* animation = new Animation();
+ Shared* shrAnimation = new Shared(animation);
+ LuaObject* luaAnimation = luax_newinstance(L, Jin_Lua_Animation, shrAnimation);
+ if (argc >= 3)
+ {
+ if (!luax_istable(L, 1))
+ {
+ luax_typerror(L, 1, "frames table");
+ return 1;
+ }
+ bool loop = luax_checkbool(L, 2);
+ float speed = luax_checknumber(L, 3);
+ int n = luax_tableidxlen(L, 1);
+ for (int i = 1; i <= n; ++i)
+ {
+ luax_rawgeti(L, 1, i);
+ LuaObject* luaSprite = (LuaObject*)luax_checktype(L, -1, Jin_Lua_Sprite);
+ animation->addFrame(luaSprite->getObject<Sprite>());
+ int index = animation->getFrameCount() - 1;
+ luaAnimation->setDependency((int)AnimationDependency::DEP_SPRITES + index, luaSprite);
+ }
+ animation->setLoop(loop);
+ animation->setSpeed(speed);
+ }
+ luax_pushvalue(L, argc + 1);
+ return 1;
+ }
+
+ // newAnimator([animation])
+ LUA_IMPLEMENT int l_newAnimator(lua_State* L)
+ {
+ int argc = luax_gettop(L);
+ Animator* animator = new Animator();
+ Shared* shrAniamtor = new Shared(animator);
+ if (argc >= 1)
+ {
+ LuaObject* animation = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Animation);
+ animator->setAnimation(animation->getObject<Animation>());
+ LuaObject* luaAnimator = luax_newinstance(L, Jin_Lua_Animator, shrAniamtor);
+ luaAnimator->setDependency((int)AnimatorDependency::DEP_ANIMATION, animation);
+ return 1;
+ }
+ LuaObject* luaAnimator = luax_newinstance(L, Jin_Lua_Animator, shrAniamtor);
+ return 1;
+ }
+
+ /* newTextureFont(bitmap, text, color | cellw, cellh) */
+ LUA_IMPLEMENT int l_newTextureFont(lua_State* L)
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Bitmap);
+ Bitmap* bitmap = p->getObject<Bitmap>();
+ Text* text;
+ if (luax_istype(L, 2, Jin_Lua_Text))
+ {
+ LuaObject* pt = (LuaObject*)luax_checktype(L, 2, Jin_Lua_Text);
+ text = pt->getObject<Text>();
+ }
+ else if (luax_isstring(L, 2))
+ {
+ unsigned len;
+ const char* str = luax_checklstring(L, 2, &len);
+ text = new Text(Encode::UTF8, str, len);
+ }
+ else
+ {
+ luax_typerror(L, 2, "Text or string");
+ return 1;
+ }
+ float cellh = luax_checknumber(L, 4);
+ TextureFont* textureFont = nullptr;
+ if (luax_istable(L, 3))
+ {
+ unsigned int r = luax_rawgetnumber(L, 3, 1);
+ unsigned int g = luax_rawgetnumber(L, 3, 2);
+ unsigned int b = luax_rawgetnumber(L, 3, 3);
+ unsigned int a = luax_rawgetnumber(L, 3, 4);
+ textureFont = new TextureFont(bitmap, *text, Color(r, g, b, a), cellh);
+ }
+ else if (luax_isnumber(L, 3))
+ {
+ float cellw = luax_checknumber(L, 3);
+ textureFont = new TextureFont(bitmap, *text, cellw, cellh);
+ }
+ else
+ {
+ luax_error(L, "bad arguments #3 to 'newTextureFont', need to be table or number");
+ return 0;
+ }
+ if (luax_isstring(L, 2))
+ {
+ // Delete temporary text.
+ delete text;
+ }
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_TextureFont, new Shared(textureFont));
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_newParticleSystem(lua_State* L)
+ {
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_ParticleSystem, new Shared(new ParticleSystem()));
+ return 1;
+ }
+
+ /* setFont(font) */
+ LUA_IMPLEMENT int l_setFont(lua_State* L)
+ {
+ if (luax_istype(L, 1, Jin_Lua_TTF))
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TTF);
+ TTF* ttf = p->getObject<TTF>();
+ gl.setFont(ttf);
+ }
+ else if (luax_istype(L, 1, Jin_Lua_TextureFont))
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TextureFont);
+ TextureFont* tf = p->getObject<TextureFont>();
+ gl.setFont(tf);
+ }
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_unsetFont(lua_State* L)
+ {
+ gl.setFont(context.defaultFont);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_clearMatrix(lua_State* L)
+ {
+ gl.clearMatrix();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_pushMatrix(lua_State* L)
+ {
+ gl.pushMatrix();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_popMatrix(lua_State* L)
+ {
+ gl.popMatrix();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_scale(lua_State* L)
+ {
+ float sx = luax_checknumber(L, 1);
+ float sy = luax_checknumber(L, 2);
+ gl.scale(sx, sy);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_translate(lua_State* L)
+ {
+ float x = luax_checknumber(L, 1);
+ float y = luax_checknumber(L, 2);
+ gl.translate(x, y);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_rotate(lua_State* L)
+ {
+ float r = luax_checknumber(L, 1);
+ gl.rotate(r);
+ return 0;
+ }
+
+ LUA_EXPORT int luaopen_graphics(lua_State* L)
+ {
+ luaopen_Bitmap(L);
+ luaopen_Texture(L);
+ luaopen_Canvas(L);
+ luaopen_TTFData(L);
+ luaopen_TTF(L);
+ luaopen_Text(L);
+ luaopen_TextureFont(L);
+ luaopen_Page(L);
+ luaopen_Shader(L);
+ luaopen_Sprite(L);
+ luaopen_SpriteSheet(L);
+ luaopen_Animation(L);
+ luaopen_Animator(L);
+ luaopen_ParticleSystem(L);
+
+ luaL_Reg methods[] = {
+ /* window */
+ { "init", l_init },
+ { "setTitle", l_setTitle },
+ { "getSize", l_getSize },
+ { "getWidth", l_getWidth },
+ { "getHeight", l_getHeight },
+ { "destroy", l_destroy },
+ { "hideWindow", l_hideWindow },
+ { "showWindow", l_showWindow },
+ /* creators */
+ { "newBitmap", l_newBitmap },
+ { "newTexture", l_newTexture },
+ { "newShader", l_newShader },
+ { "newShaderf", l_newShaderf },
+ { "newCanvas", l_newCanvas },
+ { "newTTFData", l_newTTFData },
+ { "newText", l_newText },
+ { "newTextureFont", l_newTextureFont },
+ { "newSprite", l_newSprite },
+ { "newSpriteSheet", l_newSpriteSheet },
+ { "newAnimation", l_newAnimation },
+ { "newAnimator", l_newAnimator },
+ { "newParticleSystem", l_newParticleSystem },
+ /* render */
+ { "setClearColor", l_setClearColor },
+ { "clear", l_clear },
+ { "draw", l_draw },
+ { "print", l_print },
+ { "drawq", l_drawq },
+ { "setColor", l_setColor },
+ { "getColor", l_getColor },
+ { "present", l_present },
+ /* canvas */
+ { "bindCanvas", l_bindCanvas },
+ { "unbindCanvas", l_unbindCanvas },
+ /* shader */
+ { "useShader", l_useShader },
+ /* shapes */
+ { "point", l_point },
+ { "line", l_line },
+ { "rect", l_rect },
+ { "circle", l_circle },
+ { "triangle", l_triangle },
+ { "polygon", l_polygon },
+ /* font */
+ { "setFont", l_setFont },
+ { "unsetFont", l_unsetFont },
+ /* transform */
+ { "pushMatrix", l_pushMatrix },
+ { "clearMatrix", l_clearMatrix },
+ { "popMatrix", l_popMatrix },
+ { "translate", l_translate },
+ { "rotate", l_rotate },
+ { "scale", l_scale },
+ { 0, 0 }
+ };
+ // Load whole lib.
+ luax_newlib(L, methods);
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_graphics.h b/src/libjin-lua/modules/graphics/je_lua_graphics.h
new file mode 100644
index 0000000..02a2c63
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_graphics.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_GRAPHICS_H__
+#define __JE_LUA_GRAPHICS_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_graphics(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_page.cpp b/src/libjin-lua/modules/graphics/je_lua_page.cpp
new file mode 100644
index 0000000..5a312e2
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_page.cpp
@@ -0,0 +1,66 @@
+#include <iostream>
+
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Fonts;
+using namespace JinEngine::Graphics::Shaders;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Page = "Page";
+
+ Page* getPage(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Page);
+ return luaObj->getObject<Page>();
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Page);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_getSize(lua_State* L)
+ {
+ Page* page = getPage(L);
+ luax_pushinteger(L, page->size.w);
+ luax_pushinteger(L, page->size.h);
+ return 2;
+ }
+
+ LUA_IMPLEMENT int l_getWidth(lua_State* L)
+ {
+ Page* page = getPage(L);
+ luax_pushinteger(L, page->size.w);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getHeight(lua_State* L)
+ {
+ Page* page = getPage(L);
+ luax_pushinteger(L, page->size.h);
+ return 1;
+ }
+
+ LUA_EXPORT void luaopen_Page(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "getSize", l_getSize },
+ { "getWidth", l_getWidth },
+ { "getHeight", l_getHeight },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Page, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_page.h b/src/libjin-lua/modules/graphics/je_lua_page.h
new file mode 100644
index 0000000..e4a21a3
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_page.h
@@ -0,0 +1,22 @@
+#ifndef __JE_LUA_PAGE_H__
+#define __JE_LUA_PAGE_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ enum class PageDependency
+ {
+ DEP_TTF = 1,
+ DEP_TEXTURE_FONT = 2,
+ };
+
+ extern const char* Jin_Lua_Page;
+
+ void luaopen_Page(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_particle_system.cpp b/src/libjin-lua/modules/graphics/je_lua_particle_system.cpp
new file mode 100644
index 0000000..0c42209
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_particle_system.cpp
@@ -0,0 +1,422 @@
+#include <vector>
+
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+#include "je_lua_sprite.h"
+#include "je_lua_particle_system.h"
+
+using namespace std;
+using namespace JinEngine::Math;
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Particles;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_ParticleSystem = "ParticleSystem";
+
+ LUA_IMPLEMENT inline ParticleSystem* checkPS(lua_State* L)
+ {
+ LuaObject* luaObj = luax_checkobject(L, 1, Jin_Lua_ParticleSystem);
+ return luaObj->getObject<ParticleSystem>();
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = luax_checkobject(L, 1, Jin_Lua_ParticleSystem);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_update(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ float dt = luax_checknumber(L, 2);
+ ps->update(dt);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_render(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ ps->render();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setPosition(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ float x = luax_checknumber(L, 2);
+ float y = luax_checknumber(L, 3);
+ ps->setPosition(x, y);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setScale(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ float sx = luax_checknumber(L, 2);
+ float sy = luax_checknumber(L, 3);
+ //ps->setScale(sx, sy);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_pause(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ bool b = luax_checkbool(L, 2);
+ //ps->pause(b);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_clear(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ //ps->clear();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setEmitRate(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ if (luax_gettop(L) >= 3)
+ {
+ float floor = luax_checknumber(L, 2);
+ float ceil = luax_checknumber(L, 3);
+ ps->setEmitRate(floor, ceil);
+ }
+ else if (luax_gettop(L) >= 2)
+ {
+ float n = luax_checknumber(L, 2);
+ ps->setEmitRate(n);
+ }
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setEmitForce(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ if (luax_gettop(L) >= 3)
+ {
+ float floor = luax_checknumber(L, 2);
+ float ceil = luax_checknumber(L, 3);
+ ps->setEmitForce(floor, ceil);
+ }
+ else if (luax_gettop(L) >= 2)
+ {
+ float n = luax_checknumber(L, 2);
+ ps->setEmitForce(n);
+ }
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setEmitDirection(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ if (luax_gettop(L) >= 3)
+ {
+ float floor = luax_checknumber(L, 2);
+ float ceil = luax_checknumber(L, 3);
+ ps->setEmitDirection(floor, ceil);
+ }
+ else if (luax_gettop(L) >= 2)
+ {
+ float n = luax_checknumber(L, 2);
+ ps->setEmitDirection(n);
+ }
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setEmitPosition(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ if (luax_gettop(L) >= 3)
+ {
+ if (!luax_istable(L, 2))
+ {
+ luax_typerror(L, 2, "table");
+ return 1;
+ }
+ if (!luax_istable(L, 3))
+ {
+ luax_typerror(L, 3, "table");
+ return 1;
+ }
+ Vector2<float> floor, ceil;
+ floor.x = luax_rawgetnumber(L, 2, 1);
+ floor.y = luax_rawgetnumber(L, 2, 2);
+ ceil.x = luax_rawgetnumber(L, 3, 1);
+ ceil.y = luax_rawgetnumber(L, 3, 2);
+ ps->setEmitPosition(floor, ceil);
+ }
+ else if (luax_gettop(L) >= 2)
+ {
+ if (!luax_istable(L, 2))
+ {
+ luax_typerror(L, 2, "table");
+ return 1;
+ }
+ Vector2<float> pos;
+ pos.x = luax_rawgetnumber(L, 2, 1);
+ pos.y = luax_rawgetnumber(L, 2, 2);
+ ps->setEmitPosition(pos);
+ }
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setParticleLife(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ if (luax_gettop(L) >= 3)
+ {
+ float floor = luax_checknumber(L, 2);
+ float ceil = luax_checknumber(L, 3);
+ ps->setParticleLife(floor, ceil);
+ }
+ else if (luax_gettop(L) >= 2)
+ {
+ float n = luax_checknumber(L, 2);
+ ps->setParticleLife(n);
+ }
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setParticleLinearAccelaration(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ if (!luax_istable(L, 2))
+ {
+ luax_typerror(L, 2, "table");
+ return 1;
+ }
+ Vector2<float> ac;
+ ac.x = luax_rawgetnumber(L, 2, 1);
+ ac.y = luax_rawgetnumber(L, 2, 2);
+ ps->setParticleLinearAccelaration(ac);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setParticleRadialAccelaration(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ float ra = luax_checknumber(L, 2);
+ ps->setParticleRadialAccelaration(ra);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setParticleAngularSpeed(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ if (luax_gettop(L) >= 3)
+ {
+ float floor = luax_checknumber(L, 2);
+ float ceil = luax_checknumber(L, 3);
+ ps->setParticleAngularSpeed(floor, ceil);
+ }
+ else if (luax_gettop(L) >= 2)
+ {
+ float n = luax_checknumber(L, 2);
+ ps->setParticleAngularSpeed(n);
+ }
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setParticleSpritesMode(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ int n = luax_checkinteger(L, 2);
+ SpriteMode mode = static_cast<SpriteMode>(n);
+ ps->setParticleSpritesMode(mode);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_addParticleSprite(lua_State* L)
+ {
+ LuaObject* obj = luax_checkobject(L, 1, Jin_Lua_ParticleSystem);
+ ParticleSystem* ps = obj->getObject<ParticleSystem>();
+ LuaObject* objSpr = luax_checkobject(L, 2, Jin_Lua_Sprite);
+ Sprite* spr = objSpr->getObject<Sprite>();
+ ps->addParticleSprite(spr);
+ int depn = (*obj).getDependenciesCount();
+ (*obj).setDependency((int)ParticleSystemDependency::DEP_SPRITES + depn, objSpr);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_addParticleSprites(lua_State* L)
+ {
+ LuaObject* obj = luax_checkobject(L, 1, Jin_Lua_ParticleSystem);
+ ParticleSystem* ps = obj->getObject<ParticleSystem>();
+ if (!luax_istable(L, 2))
+ {
+ luax_typerror(L, 2, "sprites table");
+ return 1;
+ }
+ int n = luax_tableidxlen(L, 2);
+ int depn = (*obj).getDependenciesCount();
+ for (int i = 1; i <= n; ++i)
+ {
+ luax_rawgeti(L, 2, i);
+ LuaObject* objSpr = luax_checkobject(L, -1, Jin_Lua_Sprite);
+ luax_pop(L, 1);
+ Sprite* spr = objSpr->getObject<Sprite>();
+ ps->addParticleSprite(spr);
+ (*obj).setDependency((int)ParticleSystemDependency::DEP_SPRITES + depn + i - 1, objSpr);
+ }
+ return 0;
+ }
+
+ // From 0
+ LUA_IMPLEMENT int l_removeParticleSprite(lua_State* L)
+ {
+ LuaObject* obj = luax_checkobject(L, 1, Jin_Lua_ParticleSystem);
+ ParticleSystem* ps = obj->getObject<ParticleSystem>();
+ int n = luax_checkinteger(L, 2);
+ ps->removeParticleSprite(n);
+ (*obj).removeDependency((int)ParticleSystemDependency::DEP_SPRITES + n);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_enableParticleBlendAdditive(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ bool enable = luax_checkbool(L, 2);
+ ps->enableParticleBlendAdditive(enable);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setParticleScale(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ float scale = luax_checknumber(L, 2);
+ ps->setParticleScale(scale);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_addParticleScalePoint(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ float scale = luax_checknumber(L, 2);
+ float t = luax_checknumber(L, 3);
+ ps->addParticleScalePoint(scale, t);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_removeParticleScalePoint(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ int i = luax_checkinteger(L, 2);
+ ps->removeParticleScalePoint(i);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setParticleColor(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ if (!luax_istable(L, 2))
+ {
+ luax_typerror(L, 2, "color table");
+ return 1;
+ }
+ Color c;
+ c.r = luax_rawgetnumber(L, 2, 1);
+ c.g = luax_rawgetnumber(L, 2, 2);
+ c.b = luax_rawgetnumber(L, 2, 3);
+ c.a = luax_rawgetnumber(L, 2, 4);
+ ps->setParticleColor(c);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_addParticleColorPoint(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ if (!luax_istable(L, 2))
+ {
+ luax_typerror(L, 2, "color table");
+ return 1;
+ }
+ Color c;
+ c.r = luax_rawgetnumber(L, 2, 1);
+ c.g = luax_rawgetnumber(L, 2, 2);
+ c.b = luax_rawgetnumber(L, 2, 3);
+ c.a = luax_rawgetnumber(L, 2, 4);
+ float t = luax_checknumber(L, 3);
+ ps->addParticleColorPoint(c, t);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_removeParticleColorPoint(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ int i = luax_checkinteger(L, 2);
+ ps->removeParticleColorPoint(i);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_setParticleTransparency(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ float transparency = luax_checknumber(L, 2);
+ ps->setParticleTransparency(transparency);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_addParticleTransparencyPoint(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ float transparency = luax_checknumber(L, 2);
+ float t = luax_checknumber(L, 3);
+ ps->addParticleTransparencyPoint(transparency, t);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_removeParticleTransparencyPoint(lua_State* L)
+ {
+ ParticleSystem* ps = checkPS(L);
+ int i = luax_checkinteger(L, 2);
+ ps->removeParticleTransparencyPoint(i);
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_ParticleSystem(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "update", l_update },
+ { "render", l_render },
+ { "setPosition", l_setPosition },
+ { "setScale", l_setScale },
+ { "pause", l_pause },
+ { "clear", l_clear },
+ { "setEmitRate", l_setEmitRate },
+ { "setEmitForce", l_setEmitForce },
+ { "setEmitDirection", l_setEmitDirection },
+ { "setEmitPosition", l_setEmitPosition },
+ { "setParticleLife", l_setParticleLife },
+ { "setParticleLinearAccelaration", l_setParticleLinearAccelaration },
+ { "setParticleRadialAccelaration", l_setParticleRadialAccelaration },
+ { "setParticleAngularSpeed", l_setParticleAngularSpeed },
+ { "setParticleSpritesMode", l_setParticleSpritesMode },
+ { "addParticleSprite", l_addParticleSprite },
+ { "addParticleSprites", l_addParticleSprites },
+ { "removeParticleSprite", l_removeParticleSprite },
+ { "enableParticleBlendAdditive", l_enableParticleBlendAdditive },
+ { "setParticleScale", l_setParticleScale },
+ { "addParticleScalePoint", l_addParticleScalePoint },
+ { "removeParticleScalePoint", l_removeParticleScalePoint },
+ { "setParticleColor", l_setParticleColor },
+ { "addParticleColorPoint", l_addParticleColorPoint },
+ { "removeParticleColorPoint", l_removeParticleColorPoint },
+ { "setParticleTransparency", l_setParticleTransparency },
+ { "addParticleTransparencyPoint", l_addParticleTransparencyPoint },
+ { "removeParticleTransparencyPoint", l_removeParticleTransparencyPoint },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_ParticleSystem, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_particle_system.h b/src/libjin-lua/modules/graphics/je_lua_particle_system.h
new file mode 100644
index 0000000..b75b569
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_particle_system.h
@@ -0,0 +1,21 @@
+#ifndef __JE_LUA_PARTICLESYSTEM_H__
+#define __JE_LUA_PARTICLESYSTEM_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ enum class ParticleSystemDependency
+ {
+ DEP_SPRITES = 1,
+ };
+
+ extern const char* Jin_Lua_ParticleSystem;
+
+ void luaopen_ParticleSystem(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_shader.cpp b/src/libjin-lua/modules/graphics/je_lua_shader.cpp
new file mode 100644
index 0000000..9505444
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_shader.cpp
@@ -0,0 +1,132 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+#include "je_lua_shader.h"
+#include "je_lua_canvas.h"
+#include "je_lua_texture.h"
+
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Shaders;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Shader = "Shader";
+
+ static inline Shader* checkShader(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Shader);
+ return luaObj->getObject<Shader>();
+ }
+
+ /**
+ * jsl:sendNumber("variable", 0.1)
+ */
+ LUA_IMPLEMENT int l_sendNumber(lua_State* L)
+ {
+ Shader* shader = checkShader(L);
+ const char* variable = luax_checkstring(L, 2);
+ float number = luax_checknumber(L, 3);
+ shader->sendFloat(variable, number);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_sendTexture(lua_State* L)
+ {
+ Shader* shader = checkShader(L);
+ const char* variable = luax_checkstring(L, 2);
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 3, Jin_Lua_Texture);
+ shader->sendTexture(variable, luaObj->getObject<Texture>());
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_sendCanvas(lua_State* L)
+ {
+ Shader* shader = checkShader(L);
+ const char* variable = luax_checkstring(L, 2);
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 3, Jin_Lua_Canvas);
+ shader->sendCanvas(variable, luaObj->getObject<Canvas>());
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_sendVec2(lua_State* L)
+ {
+ Shader* shader = checkShader(L);
+ const char* variable = luax_checkstring(L, 2);
+ if (!luax_istable(L, 3))
+ {
+ luax_typerror(L, 3, "table");
+ return 1;
+ }
+ float x = luax_rawgetnumber(L, 3, 1);
+ float y = luax_rawgetnumber(L, 3, 2);
+ shader->sendVec2(variable, x, y);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_sendVec3(lua_State* L)
+ {
+ Shader* shader = checkShader(L);
+ const char* variable = luax_checkstring(L, 2);
+ if (!luax_istable(L, 3))
+ {
+ luax_typerror(L, 3, "table");
+ return 1;
+ }
+ float x = luax_rawgetnumber(L, 3, 1);
+ float y = luax_rawgetnumber(L, 3, 2);
+ float z = luax_rawgetnumber(L, 3, 3);
+ shader->sendVec3(variable, x, y, z);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_sendVec4(lua_State* L)
+ {
+ Shader* shader = checkShader(L);
+ const char* variable = luax_checkstring(L, 2);
+ if (!luax_istable(L, 3))
+ {
+ luax_typerror(L, 3, "table");
+ return 1;
+ }
+ float x = luax_rawgetnumber(L, 3, 1);
+ float y = luax_rawgetnumber(L, 3, 2);
+ float z = luax_rawgetnumber(L, 3, 3);
+ float w = luax_rawgetnumber(L, 3, 4);
+ shader->sendVec4(variable, x, y, z, w);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_sendColor(lua_State* L)
+ {
+ return l_sendVec4(L);
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Shader);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_Shader(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "sendNumber", l_sendNumber },
+ { "sendTexture", l_sendTexture },
+ { "sendCanvas", l_sendCanvas },
+ { "sendVec2", l_sendVec2 },
+ { "sendVec3", l_sendVec3 },
+ { "sendVec4", l_sendVec4 },
+ { "sendColor", l_sendColor },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Shader, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_shader.h b/src/libjin-lua/modules/graphics/je_lua_shader.h
new file mode 100644
index 0000000..5a84372
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_shader.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_SHDER_H__
+#define __JE_LUA_SHDER_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Shader;
+
+ void luaopen_Shader(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_sprite.cpp b/src/libjin-lua/modules/graphics/je_lua_sprite.cpp
new file mode 100644
index 0000000..f1bc6aa
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_sprite.cpp
@@ -0,0 +1,66 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+#include "je_lua_sprite.h"
+#include "je_lua_canvas.h"
+#include "je_lua_texture.h"
+#include "je_lua_shader.h"
+
+using namespace JinEngine::Math;
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Shaders;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+ const char* Jin_Lua_Sprite = "Sprite";
+
+ LUA_IMPLEMENT inline Sprite* checkSprite(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Sprite);
+ return luaObj->getObject<Sprite>();
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Sprite);
+ p->release();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_render(lua_State* L)
+ {
+ Sprite* sprite = checkSprite(L);
+ float x = luax_checknumber(L, 2);
+ float y = luax_checknumber(L, 3);
+ float sx = luax_checknumber(L, 4);
+ float sy = luax_checknumber(L, 5);
+ float r = luax_checknumber(L, 6);
+ sprite->render(x, y, sx, sy, r);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_getSize(lua_State* L)
+ {
+ Sprite* sprite = checkSprite(L);
+ Vector2<int> size = sprite->getSize();
+ luax_pushinteger(L, size.x);
+ luax_pushinteger(L, size.y);
+ return 1;
+ }
+
+ LUA_EXPORT void luaopen_Sprite(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "render", l_render },
+ { "getSize", l_getSize },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Sprite, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_sprite.h b/src/libjin-lua/modules/graphics/je_lua_sprite.h
new file mode 100644
index 0000000..02c44bf
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_sprite.h
@@ -0,0 +1,24 @@
+#ifndef __JE_LUA_SPRITE_H__
+#define __JE_LUA_SPRITE_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ // Sprite dependency slots.
+ enum class SpriteDependency
+ {
+ DEP_GRAPHIC = 1,
+ DEP_SHADER = 2,
+ DEP_SPRITESHEET = 3
+ };
+
+ extern const char* Jin_Lua_Sprite;
+
+ void luaopen_Sprite(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_spritesheet.cpp b/src/libjin-lua/modules/graphics/je_lua_spritesheet.cpp
new file mode 100644
index 0000000..a1a2c59
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_spritesheet.cpp
@@ -0,0 +1,118 @@
+#include <vector>
+
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+#include "je_lua_sprite.h"
+#include "je_lua_spritesheet.h"
+
+using namespace std;
+using namespace JinEngine::Math;
+using namespace JinEngine::Graphics;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_SpriteSheet = "SpriteSheet";
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaSSheet = (LuaObject*)luax_checktype(L, 1, Jin_Lua_SpriteSheet);
+ luaSSheet->release();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_newSprite(lua_State* L)
+ {
+ LuaObject* luaSSheet = (LuaObject*)luax_checktype(L, 1, Jin_Lua_SpriteSheet);
+ SpriteSheet* sheet = luaSSheet->getObject<SpriteSheet>();
+ Quad quad;
+ quad.x = luax_rawgetnumberthenpop(L, 2, 1);
+ quad.y = luax_rawgetnumberthenpop(L, 2, 2);
+ quad.w = luax_rawgetnumberthenpop(L, 2, 3);
+ quad.h = luax_rawgetnumberthenpop(L, 2, 4);
+ Sprite* spr = nullptr;
+ if (luax_gettop(L) >= 4)
+ {
+ float ox = luax_checknumber(L, 3);
+ float oy = luax_checknumber(L, 4);
+ spr = sheet->createSprite(quad, ox, oy);
+ }
+ else if (luax_gettop(L) == 3)
+ {
+ int o = luax_checkinteger(L, 3);
+ Origin origin;
+ origin = static_cast<Origin>(o);
+ spr = sheet->createSprite(quad, origin);
+ }
+ Shared* shrSprite = new Shared(spr);
+ LuaObject* luaSprite = luax_newinstance(L, Jin_Lua_Sprite, shrSprite);
+ luaSprite->setDependency((int)SpriteDependency::DEP_SPRITESHEET, luaSSheet);
+ return 1;
+ }
+
+ // {} = newSprites
+ LUA_IMPLEMENT int l_newSprites(lua_State* L)
+ {
+ LuaObject* luaSS = (LuaObject*)luax_checktype(L, 1, Jin_Lua_SpriteSheet);
+ SpriteSheet* ss = luaSS->getObject<SpriteSheet>();
+ int count = luax_checkinteger(L, 2);
+ int r = luax_checkinteger(L, 3);
+ int c = luax_checkinteger(L, 4);
+ int w = luax_checkinteger(L, 5);
+ int h = luax_checkinteger(L, 6);
+ vector<Sprite*> sprs;
+ int argc = luax_gettop(L);
+ if (argc == 6)
+ {
+ sprs = ss->createSprites(count, r, c, w, h, Origin::TOPLEFT);
+ }
+ else if (argc >= 8)
+ {
+ int ox = luax_checkinteger(L, 7);
+ int oy = luax_checkinteger(L, 8);
+ int offx = luax_optinteger(L, 9, 0);
+ int offy = luax_optinteger(L, 10, 0);
+ sprs = ss->createSprites(count, r, c, w, h, ox, oy, offx, offy);
+ }
+ else if (argc >= 7)
+ {
+ int o = luax_checkinteger(L, 7);
+ Origin origin = static_cast<Origin>(o);
+ int offx = luax_optinteger(L, 8, 0);
+ int offy = luax_optinteger(L, 9, 0);
+ sprs = ss->createSprites(count, r, c, w, h, origin, offx, offy);
+ }
+ else
+ {
+ luax_error(L, "No matched override function.");
+ return 1;
+ }
+ luax_newtable(L);
+ LuaObject* graphic = luaSS->getDependency((int)SpriteSheetDependency::DEP_GRAPHIC);
+ for (int i = 0; i < sprs.size(); ++i)
+ {
+ Sprite* spr = sprs[i];
+ Shared* shrSpr = new Shared(spr);
+ LuaObject* luaSpr = (LuaObject*)luax_newinstance(L, Jin_Lua_Sprite, shrSpr);
+ luaSpr->setDependency((int)SpriteDependency::DEP_GRAPHIC, graphic);
+ luax_rawseti(L, -2, i + 1);
+ }
+ return 1;
+ }
+
+ LUA_EXPORT void luaopen_SpriteSheet(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "newSprite", l_newSprite },
+ { "newSprites", l_newSprites },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_SpriteSheet, methods);
+ }
+
+ }
+} \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_spritesheet.h b/src/libjin-lua/modules/graphics/je_lua_spritesheet.h
new file mode 100644
index 0000000..bcae60b
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_spritesheet.h
@@ -0,0 +1,21 @@
+#ifndef __JE_LUA_SPRITE_SHEET_H__
+#define __JE_LUA_SPRITE_SHEET_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ enum class SpriteSheetDependency
+ {
+ DEP_GRAPHIC = 1
+ };
+
+ extern const char* Jin_Lua_SpriteSheet;
+
+ void luaopen_SpriteSheet(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_text.cpp b/src/libjin-lua/modules/graphics/je_lua_text.cpp
new file mode 100644
index 0000000..0afbceb
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_text.cpp
@@ -0,0 +1,31 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+using namespace JinEngine::Graphics;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Text = "Text";
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Text);
+ p->release();
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_Text(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Text, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_text.h b/src/libjin-lua/modules/graphics/je_lua_text.h
new file mode 100644
index 0000000..dfcc9cc
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_text.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_TEXT_H__
+#define __JE_LUA_TEXT_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Text;
+
+ void luaopen_Text(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_texture.cpp b/src/libjin-lua/modules/graphics/je_lua_texture.cpp
new file mode 100644
index 0000000..b03b999
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_texture.cpp
@@ -0,0 +1,63 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+#include "je_lua_texture.h"
+
+using namespace JinEngine::Graphics;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Texture = "Texture";
+
+ LUA_IMPLEMENT inline Texture* checkTexture(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Texture);
+ return luaObj->getObject<Texture>();
+ }
+
+ LUA_IMPLEMENT int l_getWidth(lua_State* L)
+ {
+ Texture* shared = checkTexture(L);
+ luax_pushnumber(L, shared->getWidth());
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getHeight(lua_State *L)
+ {
+ Texture* shared = checkTexture(L);
+ luax_pushnumber(L, shared->getHeight());
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getSize(lua_State* L)
+ {
+ Texture* shared = checkTexture(L);
+ luax_pushnumber(L, shared->getWidth());
+ luax_pushnumber(L, shared->getHeight());
+ return 2;
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Texture);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_Texture(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "getWidth", l_getWidth },
+ { "getHeight", l_getHeight },
+ { "getSize", l_getSize },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Texture, methods);
+ }
+
+ }// namespace Lua
+}// namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_texture.h b/src/libjin-lua/modules/graphics/je_lua_texture.h
new file mode 100644
index 0000000..c8bb71c
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_texture.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_TEXTURE_H__
+#define __JE_LUA_TEXTURE_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Texture;
+
+ void luaopen_Texture(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_texture_font.cpp b/src/libjin-lua/modules/graphics/je_lua_texture_font.cpp
new file mode 100644
index 0000000..6cbf7ca
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_texture_font.cpp
@@ -0,0 +1,63 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+#include "je_lua_page.h"
+#include "je_lua_text.h"
+
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Fonts;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_TextureFont = "TextureFont";
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TextureFont);
+ luaObj->release();
+ return 0;
+ }
+
+ /* typeset(Text | string, lineheight, spacing) */
+ LUA_IMPLEMENT int l_typeset(lua_State* L)
+ {
+ LuaObject* luaTexFont = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TextureFont);
+ TextureFont* tf = luaTexFont->getObject<TextureFont>();
+ int lineheight = luax_checkinteger(L, 3);
+ int spacing = luax_optnumber(L, 4, 0);
+ Page* page = nullptr;
+ if (luax_isstring(L, 2))
+ {
+ unsigned length;
+ const char* str = luax_checklstring(L, 2, &length);
+ Text text(Encode::UTF8, str, length);
+ page = tf->typeset(text, lineheight, spacing);
+ }
+ else if (luax_istype(L, 2, Jin_Lua_Text))
+ {
+ LuaObject* p2 = (LuaObject*)luax_checktype(L, 2, Jin_Lua_Text);
+ Text* text = p2->getObject<Text>();
+ page = tf->typeset(*text, lineheight, spacing);
+ }
+ Shared* shrPage = new Shared(page);
+ LuaObject* luaPage = luax_newinstance(L, Jin_Lua_Page, shrPage);
+ luaPage->setDependency((int)PageDependency::DEP_TEXTURE_FONT, luaTexFont);
+ return 1;
+ }
+
+ LUA_EXPORT void luaopen_TextureFont(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "typeset", l_typeset },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_TextureFont, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_texture_font.h b/src/libjin-lua/modules/graphics/je_lua_texture_font.h
new file mode 100644
index 0000000..d1fffe5
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_texture_font.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_TEXTURE_FONT_H__
+#define __JE_LUA_TEXTURE_FONT_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_TextureFont;
+
+ void luaopen_TextureFont(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_ttf.cpp b/src/libjin-lua/modules/graphics/je_lua_ttf.cpp
new file mode 100644
index 0000000..ead46de
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_ttf.cpp
@@ -0,0 +1,63 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+#include "je_lua_page.h"
+#include "je_lua_text.h"
+
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Fonts;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_TTF = "TTF";
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TTF);
+ luaObj->release();
+ return 0;
+ }
+
+ /* typeset(Text | string, lineheight, spacing) */
+ LUA_IMPLEMENT int l_typeset(lua_State* L)
+ {
+ LuaObject* luaTTF = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TTF);
+ TTF* ttf = luaTTF->getObject<TTF>();
+ int lineheight = luax_optnumber(L, 3, ttf->getFontSize());
+ int spacing = luax_optnumber(L, 4, 0);
+ Page* page = nullptr;
+ if (luax_isstring(L, 2))
+ {
+ unsigned length;
+ const char* str = luax_checklstring(L, 2, &length);
+ Text text(Encode::UTF8, str, length);
+ page = ttf->typeset(text, lineheight, spacing);
+ }
+ else if (luax_istype(L, 2, Jin_Lua_Text))
+ {
+ LuaObject* luaText = (LuaObject*)luax_checktype(L, 2, Jin_Lua_Text);
+ Text* text = luaText->getObject<Text>();
+ page = ttf->typeset(*text, lineheight, spacing);
+ }
+ Shared* refPage = new Shared(page);
+ LuaObject* luaPage = luax_newinstance(L, Jin_Lua_Page, refPage);
+ luaPage->setDependency((int)PageDependency::DEP_TTF, luaTTF);
+ return 1;
+ }
+
+ LUA_EXPORT void luaopen_TTF(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "typeset", l_typeset },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_TTF, methods);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_ttf.h b/src/libjin-lua/modules/graphics/je_lua_ttf.h
new file mode 100644
index 0000000..bfe503d
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_ttf.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_TTF_H__
+#define __JE_LUA_TTF_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_TTF;
+
+ void luaopen_TTF(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_ttf_data.cpp b/src/libjin-lua/modules/graphics/je_lua_ttf_data.cpp
new file mode 100644
index 0000000..e251ac8
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_ttf_data.cpp
@@ -0,0 +1,49 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+#include "je_lua_ttf.h"
+#include "je_lua_ttf_data.h"
+
+using namespace JinEngine::Graphics;
+using namespace JinEngine::Graphics::Fonts;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_TTFData = "TTFData";
+
+ LUA_IMPLEMENT int l_newTTF(lua_State* L)
+ {
+ LuaObject* luaTTFData = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TTFData);
+ int fontsize = luax_checkinteger(L, 2);
+ TTFData* fontData = luaTTFData->getObject<TTFData>();
+ TTF* font = fontData->createTTF(fontsize);
+ Shared* shrTTF = new Shared(font);
+ LuaObject* luaTTF = luax_newinstance(L, Jin_Lua_TTF, shrTTF);
+ luaTTF->setDependency((int)TTFDependency::DEP_TTFDATA, luaTTFData);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_TTFData);
+ p->release();
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_TTFData(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "newTTF", l_newTTF },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_TTFData, methods);
+
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/graphics/je_lua_ttf_data.h b/src/libjin-lua/modules/graphics/je_lua_ttf_data.h
new file mode 100644
index 0000000..1fd832d
--- /dev/null
+++ b/src/libjin-lua/modules/graphics/je_lua_ttf_data.h
@@ -0,0 +1,21 @@
+#ifndef __JE_LUA_TTFDATA_H__
+#define __JE_LUA_TTFDATA_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ enum class TTFDependency
+ {
+ DEP_TTFDATA = 1,
+ };
+
+ extern const char* Jin_Lua_TTFData;
+
+ void luaopen_TTFData(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/je_lua_modules.h b/src/libjin-lua/modules/je_lua_modules.h
new file mode 100644
index 0000000..afe0a82
--- /dev/null
+++ b/src/libjin-lua/modules/je_lua_modules.h
@@ -0,0 +1,19 @@
+#ifndef __JE_LUA_MODULES_H__
+#define __JE_LUA_MODULES_H__
+
+#include "ai/je_lua_ai.h"
+#include "audio/je_lua_audio.h"
+#include "bit/je_lua_bit.h"
+#include "core/je_lua_core.h"
+#include "event/je_lua_event.h"
+#include "filesystem/je_lua_filesystem.h"
+#include "graphics/je_lua_graphics.h"
+#include "joypad/je_lua_joypad.h"
+#include "keyboard/je_lua_keyboard.h"
+#include "math/je_lua_math.h"
+#include "mouse/je_lua_mouse.h"
+#include "net/je_lua_net.h"
+#include "thread/je_lua_thread.h"
+#include "time/je_lua_time.h"
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/joypad/je_lua_joypad.cpp b/src/libjin-lua/modules/joypad/je_lua_joypad.cpp
new file mode 100644
index 0000000..a3623ae
--- /dev/null
+++ b/src/libjin-lua/modules/joypad/je_lua_joypad.cpp
@@ -0,0 +1,21 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ LUA_EXPORT int luaopen_joypad(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { 0, 0 }
+ };
+ luax_newlib(L, methods);
+
+ return 1;
+ }
+ /*SDL_JoystickGetButton*/
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/joypad/je_lua_joypad.h b/src/libjin-lua/modules/joypad/je_lua_joypad.h
new file mode 100644
index 0000000..ec0e20f
--- /dev/null
+++ b/src/libjin-lua/modules/joypad/je_lua_joypad.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_JOYPAD_H__
+#define __JE_LUA_JOYPAD_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_joypad(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/keyboard/je_lua_keyboard.cpp b/src/libjin-lua/modules/keyboard/je_lua_keyboard.cpp
new file mode 100644
index 0000000..93a62bd
--- /dev/null
+++ b/src/libjin-lua/modules/keyboard/je_lua_keyboard.cpp
@@ -0,0 +1,17 @@
+#include "common/je_lua_common.h"
+#include "common/je_lua_object.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+ //https://wiki.libsdl.org/SDL_Keycode
+
+ LUA_EXPORT int luaopen_keyboard(lua_State* L)
+ {
+ luax_newlib(L, 0);
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/keyboard/je_lua_keyboard.h b/src/libjin-lua/modules/keyboard/je_lua_keyboard.h
new file mode 100644
index 0000000..bf00f83
--- /dev/null
+++ b/src/libjin-lua/modules/keyboard/je_lua_keyboard.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_KEYBOARD_H__
+#define __JE_LUA_KEYBOARD_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_keyboard(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/math/je_lua_math.cpp b/src/libjin-lua/modules/math/je_lua_math.cpp
new file mode 100644
index 0000000..5b320ff
--- /dev/null
+++ b/src/libjin-lua/modules/math/je_lua_math.cpp
@@ -0,0 +1,30 @@
+#include "common/je_lua_common.h"
+#include "common/je_lua_object.h"
+#include "libjin/jin.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ LUA_IMPLEMENT int l_mod(lua_State* L)
+ {
+ int n = luax_checkinteger(L, 1);
+ int m = luax_checkinteger(L, 2);
+ int mod = n % m;
+ luax_pushinteger(L, mod);
+ return 1;
+ }
+
+ LUA_EXPORT int luaopen_math(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "mod", l_mod },
+ { 0, 0 }
+ };
+ luax_newlib(L, methods);
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/math/je_lua_math.h b/src/libjin-lua/modules/math/je_lua_math.h
new file mode 100644
index 0000000..2e7010c
--- /dev/null
+++ b/src/libjin-lua/modules/math/je_lua_math.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_MATH_H__
+#define __JE_LUA_MATH_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_math(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/mouse/je_lua_mouse.cpp b/src/libjin-lua/modules/mouse/je_lua_mouse.cpp
new file mode 100644
index 0000000..222f596
--- /dev/null
+++ b/src/libjin-lua/modules/mouse/je_lua_mouse.cpp
@@ -0,0 +1,42 @@
+#include "common/je_lua_common.h"
+#include "common/je_lua_object.h"
+#include "libjin/jin.h"
+
+using namespace JinEngine::Input;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ LUA_IMPLEMENT int l_pos(lua_State* L)
+ {
+ static Mouse* mouse = Mouse::get();
+ int x, y;
+ mouse->getState(&x, &y);
+ luax_pushnumber(L, x);
+ luax_pushnumber(L, y);
+ return 2;
+ }
+
+ LUA_IMPLEMENT int l_setVisible(lua_State* L)
+ {
+ bool visible = luax_checkbool(L, 1);
+ Mouse* mouse = Mouse::get();
+ mouse->setVisible(visible);
+ return 0;
+ }
+
+ LUA_EXPORT int luaopen_mouse(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "getPosition", l_pos },
+ { "setVisible", l_setVisible },
+ { 0, 0 }
+ };
+ luax_newlib(L, methods);
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/mouse/je_lua_mouse.h b/src/libjin-lua/modules/mouse/je_lua_mouse.h
new file mode 100644
index 0000000..09738f5
--- /dev/null
+++ b/src/libjin-lua/modules/mouse/je_lua_mouse.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_MOUSE_H__
+#define __JE_LUA_MOUSE_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_mouse(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/net/je_lua_buffer.cpp b/src/libjin-lua/modules/net/je_lua_buffer.cpp
new file mode 100644
index 0000000..10e7143
--- /dev/null
+++ b/src/libjin-lua/modules/net/je_lua_buffer.cpp
@@ -0,0 +1,136 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+#include "je_lua_buffer.h"
+
+using namespace JinEngine::Lua::Net;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Buffer = "Buffer";
+
+ static inline Net::Buffer* checkNetBuffer(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Buffer);
+ return luaObj->getObject<Net::Buffer>();
+ }
+
+ // net.Buffer:append(value) -> value_length
+ LUA_IMPLEMENT int l_append(lua_State* L)
+ {
+ Buffer* buffer = checkNetBuffer(L);
+ const int vp = 2;
+ if (luax_isintegerstrict(L, vp))
+ {
+ int n = luax_checkinteger(L, vp);
+ int size = sizeof(n);
+ buffer->append(&n, size);
+ luax_pushinteger(L, size);
+ return 1;
+ }
+ else if (luax_isfloatstrict(L, vp))
+ {
+ float n = luax_checknumber(L, vp);
+ int size = sizeof(n);
+ buffer->append(&n, size);
+ luax_pushinteger(L, size);
+ return 1;
+ }
+ else if (luax_isbooleanstrict(L, vp))
+ {
+ bool n = luax_checkbool(L, vp);
+ int size = sizeof(n);
+ buffer->append(&n, size);
+ luax_pushinteger(L, size);
+ return 1;
+ }
+ else if (luax_isstringstrict(L, vp))
+ {
+ const char* str = luax_checkstring(L, vp);
+ int size = strlen(str) + 1;
+ buffer->append(str, size);
+ luax_pushinteger(L, size);
+ return 1;
+ }
+ else
+ {
+ luax_typerror(L, vp, "number, bool or string");
+ return 0;
+ }
+ }
+
+ // net.Buffer:grabString(offset) -> string, length
+ LUA_IMPLEMENT int l_grabString(lua_State* L)
+ {
+ Buffer* buffer = checkNetBuffer(L);
+ int offset = luax_checkinteger(L, 2);
+ unsigned int len;
+ char* data = buffer->grabString(&len, offset);
+ Array<char> str;
+ str.bind(data, len);
+ luax_pushstring(L, &str);
+ luax_pushinteger(L, str.count());
+ return 2;
+ }
+
+ // net.Buffer:grabInteger(offset) -> integer, length
+ LUA_IMPLEMENT int l_grabInteger(lua_State* L)
+ {
+ Buffer* buffer = checkNetBuffer(L);
+ int offset = luax_checkinteger(L, 2);
+ int len;
+ int integer = buffer->grabInteger(&len, offset);
+ luax_pushinteger(L, integer);
+ luax_pushinteger(L, len);
+ return 2;
+ }
+
+ LUA_IMPLEMENT int l_grabFloat(lua_State* L)
+ {
+ Buffer* buffer = checkNetBuffer(L);
+ int offset = luax_checkinteger(L, 2);
+ int len;
+ float floatv = buffer->grabFloat(&len, offset);
+ luax_pushnumber(L, floatv);
+ luax_pushinteger(L, len);
+ return 2;
+ }
+
+ LUA_IMPLEMENT int l_grabBoolean(lua_State* L)
+ {
+ Buffer* buffer = checkNetBuffer(L);
+ int offset = luax_checkinteger(L, 2);
+ int len;
+ bool boolean = buffer->grabBoolean(&len, offset);
+ luax_pushboolean(L, boolean);
+ luax_pushinteger(L, len);
+ return 2;
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Buffer);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_Buffer(lua_State* L)
+ {
+ luaL_Reg netbuffer_function[] = {
+ { "__gc", l_gc },
+ { "append", l_append },
+ { "grabString", l_grabString },
+ { "grabInteger", l_grabInteger },
+ { "grabBoolean", l_grabBoolean },
+ { "grabFloat", l_grabFloat },
+ { 0, 0 }
+ };
+
+ luax_newtype(L, Jin_Lua_Buffer, netbuffer_function);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/net/je_lua_buffer.h b/src/libjin-lua/modules/net/je_lua_buffer.h
new file mode 100644
index 0000000..974e23a
--- /dev/null
+++ b/src/libjin-lua/modules/net/je_lua_buffer.h
@@ -0,0 +1,102 @@
+#ifndef __JIN_LUA_NET_NETBUFFER_H
+#define __JIN_LUA_NET_NETBUFFER_H
+
+#include <cstring>
+#include <cstdlib>
+#include "common/je_lua_common.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Buffer;
+
+ void luaopen_Buffer(lua_State* L);
+
+ namespace Net
+ {
+
+ class Buffer : public Object
+ {
+ public:
+ Buffer(size_t s = 0)
+ : size(s)
+ {
+ buffer = new char[size];
+ memset(buffer, 0, size);
+ }
+
+ Buffer(const char* data, size_t s)
+ : size(s)
+ {
+ buffer = new char[size];
+ memcpy(buffer, data, size);
+ }
+
+ ~Buffer()
+ {
+ if (buffer != nullptr)
+ {
+ delete[] buffer;
+ buffer = nullptr;
+ size = 0;
+ }
+ }
+
+ void append(const void* data, size_t s)
+ {
+ if (data == nullptr)
+ return;
+ char* buf = buffer;
+ buffer = new char[size + s];
+ memcpy(buffer, buf, size);
+ memcpy(buffer + size, data, s);
+ delete[] buf;
+ size += s;
+ return;
+ }
+
+ /* grab and create a string */
+ char* grabString(unsigned int* length, int offset = 0)
+ {
+ int l = offset;
+ for (; l < size; ++l)
+ {
+ if (buffer[l] == 0)
+ break;
+ }
+ *length = l - offset + 1;
+ char* str = (char*)malloc(*length);
+ memcpy(str, buffer + offset, *length);
+ return str;
+ }
+
+ int grabInteger(int* length, int offset = 0)
+ {
+ *length = sizeof(int);
+ return *((int*)(buffer + offset));
+ }
+
+ float grabFloat(int* length, int offset = 0)
+ {
+ *length = sizeof(float);
+ return *((float*)(buffer + offset));
+ }
+
+ bool grabBoolean(int* length, int offset = 0)
+ {
+ *length = sizeof(bool);
+ return *((bool*)(buffer + offset));
+ }
+
+ char* buffer;
+ size_t size;
+
+ };
+
+ } // namespace Net
+ } // namespace Lua
+} // namespace JinEngine
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/net/je_lua_net.cpp b/src/libjin-lua/modules/net/je_lua_net.cpp
new file mode 100644
index 0000000..fad6fc5
--- /dev/null
+++ b/src/libjin-lua/modules/net/je_lua_net.cpp
@@ -0,0 +1,79 @@
+#include "common/je_lua_object.h"
+#include "libjin/jin.h"
+#include "common/je_lua_common.h"
+
+#include "je_lua_buffer.h"
+#include "je_lua_socket.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ using namespace JinEngine::Lua::Net;
+ using namespace JinEngine::Net;
+
+ LUA_IMPLEMENT int l_initNetwork(lua_State* L)
+ {
+ JinEngine::Net::NetManager::get()->start();
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_Socket(lua_State* L)
+ {
+ SocketInformation info = { 0 };
+ {
+ const char* socketType = luax_checkstring(L, 1);
+ if (strcmp(socketType, "TCP") == 0)
+ info.type = SocketType::TCP;
+ else if (strcmp(socketType, "UDP") == 0)
+ info.type = SocketType::UDP;
+ else
+ {
+ luax_error(L, "jin.net.Socket() first paramter wrong, must be TCP or UDP");
+ return 0;
+ }
+ // type, port
+ if (luax_gettop(L) == 2)
+ {
+ info.port = luax_checkinteger(L, 2);
+ }
+ // type, address, port
+ else if (luax_gettop(L) == 3)
+ {
+ if (luax_isstringstrict(L, 2))
+ info.address = tk_strtohl(luax_checkstring(L, 2));
+ else if (luax_isintegerstrict(L, 2))
+ info.address = luax_checkinteger(L, 2);
+ info.port = luax_checkinteger(L, 3);
+ }
+ }
+ Socket* socket = new Socket(info);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Socket, new Shared(socket));
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_Buffer(lua_State* L)
+ {
+ int size = luax_checkinteger(L, 1);
+ Net::Buffer* buffer = new Net::Buffer(size);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Buffer, new Shared(buffer));
+ return 1;
+ }
+
+ LUA_EXPORT int luaopen_net(lua_State* L)
+ {
+ luaopen_Socket(L);
+ luaopen_Buffer(L);
+ luaL_Reg methods[] = {
+ { "init", l_initNetwork },
+ { "newSocket", l_Socket },
+ { "newBuffer", l_Buffer },
+ { 0, 0 }
+ };
+ luax_newlib(L, methods);
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/net/je_lua_net.h b/src/libjin-lua/modules/net/je_lua_net.h
new file mode 100644
index 0000000..1542791
--- /dev/null
+++ b/src/libjin-lua/modules/net/je_lua_net.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_NET_H__
+#define __JE_LUA_NET_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_net(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/net/je_lua_socket.cpp b/src/libjin-lua/modules/net/je_lua_socket.cpp
new file mode 100644
index 0000000..d6cfe91
--- /dev/null
+++ b/src/libjin-lua/modules/net/je_lua_socket.cpp
@@ -0,0 +1,123 @@
+#include "common/je_lua_object.h"
+#include "common/je_lua_common.h"
+#include "libjin/jin.h"
+#include "je_lua_buffer.h"
+
+using namespace JinEngine::Net;
+using namespace JinEngine::Lua::Net;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Socket = "Socket";
+
+ const int BUFFER_SIZE = 1024;
+
+ LUA_IMPLEMENT inline Socket* checkSocket(lua_State* L, int pos = 1)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, pos, Jin_Lua_Socket);
+ return luaObj->getObject<Socket>();
+ }
+
+ LUA_IMPLEMENT inline Buffer* checkNetBuffer(lua_State* L, int pos = 1)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, pos, Jin_Lua_Buffer);
+ return luaObj->getObject<Buffer>();
+ }
+
+ // return net.Socket
+ LUA_IMPLEMENT int l_accept(lua_State* L)
+ {
+ Socket* socket = checkSocket(L);
+ Socket* client = socket->accept();
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Socket, new Shared(client));
+ return 1;
+ }
+
+ // return net.Buffer
+ LUA_IMPLEMENT int l_receive(lua_State* L)
+ {
+ Socket* socket = checkSocket(L);
+ char buffer[BUFFER_SIZE] = {0};
+ int size = socket->receive(buffer, BUFFER_SIZE);
+ Net::Buffer* netBuffer = new Net::Buffer(buffer, size);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Buffer, new Shared(netBuffer));
+ return 1;
+ }
+
+ // Socket:receiveFrom(address, port)
+ LUA_IMPLEMENT int l_receiveFrom(lua_State* L)
+ {
+ Socket* socket = checkSocket(L);
+ int address = luax_checkinteger(L, 2);
+ int port = luax_checkinteger(L, 3);
+ char buffer[BUFFER_SIZE];
+ int size = socket->receiveFrom(buffer, BUFFER_SIZE, address, port);
+ Net::Buffer* netBuffer = new Net::Buffer(buffer, size);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Buffer, new Shared(netBuffer));
+ return 1;
+ }
+
+ // Socket:send(net.Buffer) -> data_length
+ LUA_IMPLEMENT int l_send(lua_State* L)
+ {
+ Socket* socket = checkSocket(L);
+ Buffer* buffer = checkNetBuffer(L, 2);
+ int len = socket->send(buffer->buffer, buffer->size);
+ luax_pushinteger(L, len);
+ return 1;
+ }
+
+ // Socket:sendTo(address, port, net.Buffer)
+ LUA_IMPLEMENT int l_sendTo(lua_State* L)
+ {
+ Socket* socket = checkSocket(L);
+ int address = luax_checkinteger(L, 2);
+ int port = luax_checkinteger(L, 3);
+ Buffer* buffer = checkNetBuffer(L, 4);
+ socket->sendTo(buffer->buffer, buffer->size, address, port);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_close(lua_State* L)
+ {
+ Socket* socket = checkSocket(L);
+ socket->close();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_configBlocking(lua_State* L)
+ {
+ Socket* socket = checkSocket(L);
+ bool blocking = luax_checkbool(L, 2);
+ socket->configureBlocking(blocking);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Socket);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_Socket(lua_State* L)
+ {
+ luaL_Reg socket_function[] = {
+ { "__gc", l_gc },
+ { "accept", l_accept },
+ { "receive", l_receive },
+ { "receiveFrom", l_receiveFrom },
+ { "send", l_send },
+ { "sendTo", l_sendTo },
+ { "close", l_close },
+ { "configBlocking", l_configBlocking },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Socket, socket_function);
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/net/je_lua_socket.h b/src/libjin-lua/modules/net/je_lua_socket.h
new file mode 100644
index 0000000..b33fac6
--- /dev/null
+++ b/src/libjin-lua/modules/net/je_lua_socket.h
@@ -0,0 +1,16 @@
+#ifndef __JE_LUA_SOCKET_H__
+#define __JE_LUA_SOCKET_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Socket;
+
+ void luaopen_Socket(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/thread/je_lua_thread.cpp b/src/libjin-lua/modules/thread/je_lua_thread.cpp
new file mode 100644
index 0000000..2af3e53
--- /dev/null
+++ b/src/libjin-lua/modules/thread/je_lua_thread.cpp
@@ -0,0 +1,240 @@
+#include "common/je_lua_object.h"
+
+#include "libjin/jin.h"
+#include "libjin-lua/je_lua_jin.h"
+#include "common/je_lua_common.h"
+#include "je_lua_thread.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Thread = "Thread";
+
+ int luaopen_thread(lua_State* L);
+
+ static inline Thread* checkThread(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Thread);
+ return luaObj->getObject<Thread>();
+ }
+
+ LUA_IMPLEMENT int threadRunner(void* t)
+ {
+ Shared* shared = (Shared*)t;
+ Thread* thread = shared->getObject<Thread>();
+ lua_State* L = lua_open();
+ luax_openlibs(L);
+ open(L);
+ luax_getglobal(L, MODULE_NAME);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Thread, shared);
+ luax_setfield(L, -2, "_curThread");
+ luax_dostring(L, thread->code.c_str());
+ luax_close(L);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_thread_gc(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Thread);
+ luaObj->release();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_start(lua_State* L)
+ {
+ Thread* shared = checkThread(L);
+ bool result = shared->start(&shared);
+ luax_pushboolean(L, result);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_wait(lua_State* L)
+ {
+ Thread* shared = checkThread(L);
+ shared->wait();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_send(lua_State* L)
+ {
+ Thread* shared = checkThread(L);
+ int slot = luax_checkinteger(L, 2);
+ const int vp = 3;
+ if (luax_isnumberstrict(L, vp))
+ {
+ float real = luax_checknumber(L, vp);
+ shared->send(slot, real);
+ }
+ else if (luax_isbooleanstrict(L, vp))
+ {
+ bool bol = luax_checkbool(L, vp);
+ shared->send(slot, bol);
+ }
+ else if (luax_isstringstrict(L, vp))
+ {
+ const char* str = luax_checkstring(L, vp);
+ shared->send(slot, str);
+ }
+ else if (luax_isuserdata(L, vp))
+ {
+ LuaObject* luaObj = (LuaObject*)luax_touserdata(L, vp);
+ shared->send(slot, luaObj);
+ }/*
+ else if (luax_islightuserdata(L, vp))
+ {
+ void* p = luax_tolightuserdata(L, vp);
+ shared->send(slot, p);
+ }*/
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_receive(lua_State* L)
+ {
+ Thread* shared = checkThread(L);
+ int slot = luax_checkinteger(L, 2);
+ bool result = shared->receive(slot);
+ luax_pushboolean(L, result);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_fetch(lua_State* L)
+ {
+ Thread* shared = checkThread(L);
+ int slot = luax_checkinteger(L, 2);
+ Thread::Variant v = shared->fetch(slot);
+ switch (v.type)
+ {
+ case Thread::Variant::INTERGER:
+ luax_pushinteger(L, v.integer);
+ break;
+
+ case Thread::Variant::BOOLEAN:
+ luax_pushboolean(L, v.boolean);
+ break;
+
+ case Thread::Variant::CSTRING:
+ luax_pushstring(L, v.cstring);
+ break;
+
+ case Thread::Variant::REAL:
+ luax_pushnumber(L, v.real);
+ break;
+
+ case Thread::Variant::POINTER:
+ LuaObject* p = (LuaObject*)v.pointer;
+ // Create lua object from other lua_State.
+ LuaObject* luaObj = luax_copyinstance(L, p);
+ break;
+
+ }
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_demand(lua_State* L)
+ {
+ Thread* shared = checkThread(L);
+ int slot = luax_checkinteger(L, 2);
+ Thread::Variant v = shared->demand(slot);
+ switch (v.type)
+ {
+ case Thread::Variant::INTERGER:
+ luax_pushinteger(L, v.integer);
+ break;
+
+ case Thread::Variant::BOOLEAN:
+ luax_pushboolean(L, v.boolean);
+ break;
+
+ case Thread::Variant::CSTRING:
+ luax_pushstring(L, v.cstring);
+ break;
+
+ case Thread::Variant::REAL:
+ luax_pushnumber(L, v.real);
+ break;
+
+ case Thread::Variant::POINTER:
+ LuaObject* p = (LuaObject*)v.pointer;
+ // Create lua object from other lua_State.
+ LuaObject* luaObj = luax_copyinstance(L, p);
+ break;
+
+ }
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_remove(lua_State* L)
+ {
+ Thread* shared = checkThread(L);
+ int slot = luax_checkinteger(L, 2);
+ shared->remove(slot);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_getName(lua_State* L)
+ {
+ Thread* shared = checkThread(L);
+ const char* name = shared->getName();
+ luax_pushstring(L, name);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_isRunning(lua_State* L)
+ {
+ Thread* shared = checkThread(L);
+ bool running = shared->isRunning();
+ luax_pushboolean(L, running);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int luaopen_Thread(lua_State* L)
+ {
+ luaL_Reg thread_function[] = {
+ { "__gc", l_thread_gc },
+ { "start", l_start },
+ { "wait", l_wait },
+ { "send", l_send },
+ { "receive", l_receive },
+ { "fetch", l_fetch },
+ { "demand", l_demand },
+ { "remove", l_remove },
+ { "getName", l_getName },
+ { "isRunning", l_isRunning },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Thread, thread_function);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_newThread(lua_State* L)
+ {
+ const char* name = luax_checkstring(L, 1);
+ const char* code = luax_checkstring(L, 2);
+ Thread* thread = new Thread(name, code, threadRunner);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Thread, new Shared(thread));
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getThread(lua_State* L)
+ {
+ luax_getglobal(L, MODULE_NAME);
+ luax_getfield(L, -1, "_curThread");
+ return 1;
+ }
+
+ LUA_EXPORT int luaopen_thread(lua_State* L)
+ {
+ luaopen_Thread(L);
+ luaL_Reg methods[] = {
+ { "newThread", l_newThread },
+ { "getThread", l_getThread },
+ { 0, 0 }
+ };
+ luax_newlib(L, methods);
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/thread/je_lua_thread.h b/src/libjin-lua/modules/thread/je_lua_thread.h
new file mode 100644
index 0000000..acb4c49
--- /dev/null
+++ b/src/libjin-lua/modules/thread/je_lua_thread.h
@@ -0,0 +1,95 @@
+#include "libjin/jin.h"
+#include "common/je_lua_common.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Thread;
+
+ class Thread : public Object
+ {
+ public:
+ typedef JinEngine::Threads::Thread::Variant Variant;
+ typedef JinEngine::Threads::Thread::ThreadRunner ThreadRunner;
+
+ Thread(std::string _name, std::string _code, ThreadRunner runner)
+ : name(_name)
+ , code(_code)
+ {
+ thread = new JinEngine::Threads::Thread(_name, runner);
+ }
+
+ ~Thread()
+ {
+ delete thread;
+ }
+
+ bool start(void* p)
+ {
+ return thread->start(p);
+ }
+
+ void wait()
+ {
+ thread->wait();
+ }
+
+ void send(int slot, const Variant& value)
+ {
+ thread->send(slot, value);
+ }
+
+ bool receive(int slot)
+ {
+ return thread->receive(slot);
+ }
+
+ Variant fetch(int slot)
+ {
+ return thread->fetch(slot);
+ }
+
+ Variant demand(int slot)
+ {
+ return thread->demand(slot);
+ }
+
+ void remove(int slot)
+ {
+ thread->remove(slot);
+ }
+
+ const char* getName()
+ {
+ return name.c_str();
+ }
+
+ bool isRunning()
+ {
+ return thread->isRunning();
+ }
+
+ void lock()
+ {
+ thread->lock();
+ }
+
+ void unlock()
+ {
+ thread->unlock();
+ }
+
+ const std::string name;
+ const std::string code;
+
+ private:
+ JinEngine::Threads::Thread* thread;
+
+ };
+
+ int luaopen_thread(lua_State* L);
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/time/je_lua_time.cpp b/src/libjin-lua/modules/time/je_lua_time.cpp
new file mode 100644
index 0000000..cd49978
--- /dev/null
+++ b/src/libjin-lua/modules/time/je_lua_time.cpp
@@ -0,0 +1,70 @@
+#include "SDL2/SDL.h"
+#include "common/je_lua_common.h"
+#include "common/je_lua_object.h"
+#include "libjin/jin.h"
+
+#include "je_lua_timer.h"
+
+using namespace JinEngine::Time;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ static struct
+ {
+ float previous;
+ float current;
+ } context;
+
+ LUA_IMPLEMENT int l_sec(lua_State* L)
+ {
+ luax_pushnumber(L, getSecond());
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_sleep(lua_State* L)
+ {
+ double sec = luax_checknumber(L, 1);
+ sleep(sec * 1000.0f);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_newTimer(lua_State* L)
+ {
+ Shared* shrTimer = new Shared(new Timer());
+ luax_newinstance(L, Jin_Lua_Timer, shrTimer);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_getDelta(lua_State* L)
+ {
+ luax_pushnumber(L, context.current - context.previous);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_step(lua_State* L)
+ {
+ context.previous = context.current;
+ context.current = getSecond();
+ return 0;
+ }
+
+ LUA_EXPORT int luaopen_time(lua_State* L)
+ {
+ luaopen_Timer(L);
+ luaL_Reg methods[] = {
+ { "second", l_sec },
+ { "sleep", l_sleep },
+ { "newTimer", l_newTimer },
+ { "step", l_step },
+ { "getDelta", l_getDelta },
+ { 0, 0 },
+ };
+ luax_newlib(L, methods);
+ return 1;
+ }
+
+ } // namespace Lua
+} // namespace JinEngine \ No newline at end of file
diff --git a/src/libjin-lua/modules/time/je_lua_time.h b/src/libjin-lua/modules/time/je_lua_time.h
new file mode 100644
index 0000000..3c75221
--- /dev/null
+++ b/src/libjin-lua/modules/time/je_lua_time.h
@@ -0,0 +1,14 @@
+#ifndef __JE_LUA_TIME_H__
+#define __JE_LUA_TIME_H__
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ int luaopen_time(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/src/libjin-lua/modules/time/je_lua_timer.cpp b/src/libjin-lua/modules/time/je_lua_timer.cpp
new file mode 100644
index 0000000..e30baab
--- /dev/null
+++ b/src/libjin-lua/modules/time/je_lua_timer.cpp
@@ -0,0 +1,132 @@
+#include "common/je_lua_callback.h"
+#include "common/je_lua_common.h"
+#include "je_lua_timer.h"
+
+using namespace JinEngine::Time;
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ const char* Jin_Lua_Timer = "Timer";
+
+ const char* Jin_Lua_Handler = "Handler";
+
+ static Timer::TimerCallback timerCallback = [](void* data)->void
+ {
+ LuaCallback* func = static_cast<LuaCallback*>(data);
+ func->call();
+ };
+
+ static Timer::FinishCallback finishCallback = [](void* data)->void
+ {
+ LuaCallback* func = static_cast<LuaCallback*>(data);
+ delete func;
+ };
+
+ LUA_IMPLEMENT inline Timer* checkTimer(lua_State* L)
+ {
+ LuaObject* luaObj = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Timer);
+ return luaObj->getObject<Timer>();
+ }
+
+ // timer:every(time, callback, parameter)
+ LUA_IMPLEMENT int l_every(lua_State* L)
+ {
+ int n = luax_gettop(L);
+ Timer* shared = checkTimer(L);
+ float s = luax_checknumber(L, 2);
+ LuaCallback* func = new LuaCallback(L);
+ func->setFunc(3);
+ for(int i = 4; i <= n; ++i)
+ func->pushParam(i);
+ Timer::Handler* handler = shared->every(s, timerCallback, func, finishCallback);
+ Shared* shrHandler = new Shared(handler);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Handler, shrHandler);
+ return 1;
+ }
+
+ // timer:after(time, callback, parameter)
+ LUA_IMPLEMENT int l_after(lua_State* L)
+ {
+ int n = luax_gettop(L);
+ Timer* shared = checkTimer(L);
+ float s = luax_checknumber(L, 2);
+ LuaCallback* func = new LuaCallback(L);
+ func->setFunc(3);
+ for (int i = 4; i <= n; ++i)
+ func->pushParam(i);
+ Timer::Handler* handler = shared->after(s, timerCallback, func, finishCallback);
+ Shared* shrHandler = new Shared(handler);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Handler, shrHandler);
+ return 1;
+ }
+
+ // timer:repeat(time, callback, parameter)
+ LUA_IMPLEMENT int l_repeat(lua_State* L)
+ {
+ int n = luax_gettop(L);
+ Timer* shared = checkTimer(L);
+ float s = luax_checknumber(L, 2);
+ int count = luax_checkinteger(L, 3);
+ LuaCallback* func = new LuaCallback(L);
+ func->setFunc(4);
+ for (int i = 5; i <= n; ++i)
+ func->pushParam(i);
+ Timer::Handler* handler = shared->repeat(s, count, timerCallback, func, finishCallback);
+ Shared* shrHandler = new Shared(handler);
+ LuaObject* luaObj = luax_newinstance(L, Jin_Lua_Handler, shrHandler);
+ return 1;
+ }
+
+ LUA_IMPLEMENT int l_update(lua_State* L)
+ {
+ Timer* shared = checkTimer(L);
+ float s = luax_checknumber(L, 2);
+ shared->update(s);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_cancel(lua_State* L)
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Timer);
+ Timer* timer = p->getObject<Timer>();
+ LuaObject* ph = (LuaObject*)luax_checktype(L, 2, Jin_Lua_Handler);
+ Timer::Handler* handler = ph->getObject<Timer::Handler>();
+ timer->cancel(handler);
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_cancelAll(lua_State* L)
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Timer);
+ Timer* timer = p->getObject<Timer>();
+ timer->cancelAll();
+ return 0;
+ }
+
+ LUA_IMPLEMENT int l_gc(lua_State* L)
+ {
+ LuaObject* p = (LuaObject*)luax_checktype(L, 1, Jin_Lua_Timer);
+ p->release();
+ return 0;
+ }
+
+ LUA_EXPORT void luaopen_Timer(lua_State* L)
+ {
+ luaL_Reg methods[] = {
+ { "__gc", l_gc },
+ { "every", l_every },
+ { "after", l_after },
+ { "duplicate", l_repeat },
+ { "update", l_update },
+ { "cancel", l_cancel },
+ { "cancelAll", l_cancelAll },
+ { 0, 0 }
+ };
+ luax_newtype(L, Jin_Lua_Timer, methods);
+ }
+
+ }
+} \ No newline at end of file
diff --git a/src/libjin-lua/modules/time/je_lua_timer.h b/src/libjin-lua/modules/time/je_lua_timer.h
new file mode 100644
index 0000000..35ec15d
--- /dev/null
+++ b/src/libjin-lua/modules/time/je_lua_timer.h
@@ -0,0 +1,20 @@
+#ifndef __JE_LUA_TIMER_H__
+#define __JE_LUA_TIMER_H__
+
+#include "libjin/jin.h"
+
+namespace JinEngine
+{
+ namespace Lua
+ {
+
+ extern const char* Jin_Lua_Timer;
+
+ extern const char* Jin_Lua_Handler;
+
+ void luaopen_Timer(lua_State* L);
+
+ }
+}
+
+#endif \ No newline at end of file