完整重构
分离各SDL类的包装代码. 事件分发处理全部转移至Lua Init层. C层只提供获取事件的方法. 这样有助于提高性能,以及今后Coroutine scheduler的添加.
This commit is contained in:
parent
a516ae15ec
commit
bc189b4951
6
EventDef.h
Normal file
6
EventDef.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
constexpr int ENGINE_TIMER_EVENT = 1001; // 定时器. 参数: 定时器ID
|
||||
constexpr int ENGINE_GENERAL_CALLBACK = 1002; // 只有Ticket参数的回调. 用于Lua层区分回调.
|
||||
constexpr int ENGINE_MUSIC_FINISH = 1003; // 音乐播放结束
|
||||
constexpr int ENGINE_CHANNEL_FINISH = 1004; // 频道播放结束. 参数: 频道号.
|
94
Font.cpp
Normal file
94
Font.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
#include "Font.h"
|
||||
#include "Renderer.h"
|
||||
#include "Texture.h"
|
||||
#include "Surface.h"
|
||||
#include "LuaCommon.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define setfn(cfunc, name) lua_pushcfunction(L, cfunc);lua_setfield(L, -2, name)
|
||||
|
||||
inline int Font::close(lua_State* L)
|
||||
{
|
||||
cout << "In Font::close" << endl;
|
||||
auto p = (Font*)luaL_checkudata(L, 1, "font");
|
||||
p->~Font();
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline Font::Font(TTF_Font* f) : font(f, TTF_CloseFont)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline int Font::renderText(lua_State* L)
|
||||
{
|
||||
auto p = (Font*)luaL_checkudata(L, 1, "font");
|
||||
std::shared_ptr<SDL_Renderer> r;
|
||||
const char* msg = nullptr;
|
||||
SDL_Color c;
|
||||
|
||||
if (lua_gettop(L) >= 4)
|
||||
{
|
||||
r = ((Renderer*)luaL_checkudata(L, 2, "renderer"))->rnd;
|
||||
msg = luaL_checkstring(L, 3);
|
||||
if (LuaColorToColor(L, 4, c))
|
||||
{
|
||||
return luaL_error(L, "bad argument #4. rgba expected, got %s", lua_tostring(L, -1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = luaL_checkstring(L, 2);
|
||||
if (LuaColorToColor(L, 3, c))
|
||||
{
|
||||
return luaL_error(L, "bad argument #3. rgba expected, got %s", lua_tostring(L, -1));
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Surface* surf = TTF_RenderText_Blended(p->font.get(), msg, c);
|
||||
|
||||
if (r.get())
|
||||
{
|
||||
Texture::create(L, r, SDL_CreateTextureFromSurface(r.get(), surf));
|
||||
SDL_FreeSurface(surf);
|
||||
}
|
||||
else
|
||||
{
|
||||
Surface::create(L, surf);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Font::create(lua_State* L)
|
||||
{
|
||||
cout << "In Font::create" << endl;
|
||||
const char* font = luaL_checkstring(L, 1);
|
||||
int fontsz = luaL_checkinteger(L, 2);
|
||||
|
||||
TTF_Font* ttf = TTF_OpenFont(font, fontsz);
|
||||
if (!ttf)
|
||||
{
|
||||
return LuaSDLError(L);
|
||||
}
|
||||
|
||||
Font* f = new (lua_newuserdata(L, sizeof(Font))) Font(ttf);
|
||||
|
||||
if (luaL_newmetatable(L, "font"))
|
||||
{
|
||||
// GC
|
||||
lua_pushcfunction(L, close);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
// Fields
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "font"); lua_setfield(L, -2, "type");
|
||||
setfn(close, "close");
|
||||
setfn(renderText, "renderText");
|
||||
|
||||
// Set __index of metatable.
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
17
Font.h
Normal file
17
Font.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include "LuaVM.h"
|
||||
#include "SDL2/include/SDL_ttf.h"
|
||||
#include <memory>
|
||||
|
||||
class Font
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<TTF_Font> font;
|
||||
|
||||
Font(TTF_Font* f);
|
||||
|
||||
static int renderText(lua_State* L);
|
||||
|
||||
static int close(lua_State* L);
|
||||
static int create(lua_State* L);
|
||||
};
|
|
@ -112,8 +112,8 @@ void VMRunner(VMInfo& vm, string code)
|
|||
|
||||
int CreateVM(lua_State* L)
|
||||
{
|
||||
string code(luaL_checkstring(L, 1));
|
||||
VMInfo* vm = new (lua_newuserdata(L, sizeof(VMInfo))) VMInfo;
|
||||
string code(lua_tostring(L, 1));
|
||||
vm->ptd.reset(new thread(VMRunner, *vm, code));
|
||||
vm->ptd.reset(new thread(VMRunner, ref(*vm), code));
|
||||
return 1;
|
||||
}
|
||||
|
|
173
LuaCommon.cpp
173
LuaCommon.cpp
|
@ -25,33 +25,154 @@ bool LuaCompareType(lua_State* L, int index, const char* type, bool leave)
|
|||
}
|
||||
}
|
||||
|
||||
void check(lua_State* L, const vector<int>& typearr, const vector<const char*>& userdata_type)
|
||||
int LuaRectToRect(lua_State* L, int index, SDL_Rect& rect)
|
||||
{
|
||||
int sz = typearr.size();
|
||||
int nextIndex = 0;
|
||||
int maxIndex = userdata_type.size();
|
||||
for (int i = 0; i < sz; i++)
|
||||
if (index < 0)
|
||||
{
|
||||
int thisType = lua_type(L, i + 1);
|
||||
if (thisType != typearr[i])
|
||||
{
|
||||
luaL_error(L, "Bad argument #%d. %s expected, got %s", i + 1, lua_typename(L, typearr[i]), lua_typename(L, lua_type(L, i + 1)));
|
||||
}
|
||||
if (maxIndex && thisType == LUA_TUSERDATA)
|
||||
{
|
||||
if (nextIndex < maxIndex)
|
||||
{
|
||||
if (!LuaCompareType(L, i + 1, userdata_type[nextIndex], true))
|
||||
{
|
||||
luaL_error(L, "Bad argument #%d. %s expected, got %s", i + 1, userdata_type[nextIndex], lua_tostring(L, -1));
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
nextIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
luaL_error(L, "Not enough userdata type string.");
|
||||
}
|
||||
}
|
||||
index = lua_gettop(L) + index + 1;
|
||||
}
|
||||
|
||||
if (lua_getfield(L, index, "type") != LUA_TSTRING)
|
||||
{
|
||||
int t = lua_type(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_pushstring(L, lua_typename(L, t));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp(lua_tostring(L, -1), "rect") == 0)
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "x");
|
||||
rect.x = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "y");
|
||||
rect.y = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "w");
|
||||
rect.w = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "h");
|
||||
rect.h = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaPointToPoint(lua_State* L, int index, SDL_Point& point)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
index = lua_gettop(L) + index + 1;
|
||||
}
|
||||
|
||||
if (lua_getfield(L, index, "type") != LUA_TSTRING)
|
||||
{
|
||||
int t = lua_type(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_pushstring(L, lua_typename(L, t));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp(lua_tostring(L, -1), "point") == 0)
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "x");
|
||||
point.x = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "y");
|
||||
point.y = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaColorToColor(lua_State* L, int index, SDL_Color& c)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
index = lua_gettop(L) + index + 1;
|
||||
}
|
||||
|
||||
if (lua_getfield(L, index, "type") != LUA_TSTRING)
|
||||
{
|
||||
int t = lua_type(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_pushstring(L, lua_typename(L, t));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (strcmp(lua_tostring(L, -1), "rgba") == 0)
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "r");
|
||||
c.r = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "g");
|
||||
c.g = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "b");
|
||||
c.b = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, index, "a");
|
||||
c.a = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int LuaRectPointToRect(lua_State* L, int index, SDL_Rect& r, int default_w, int default_h)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
index = lua_gettop(L) + index + 1;
|
||||
}
|
||||
|
||||
if (LuaRectToRect(L, index, r))
|
||||
{
|
||||
SDL_Point p;
|
||||
if (LuaPointToPoint(L, index, p))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
return 1;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
r.x = p.x;
|
||||
r.y = p.y;
|
||||
r.w = default_w;
|
||||
r.h = default_h;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaSDLError(lua_State* L)
|
||||
{
|
||||
return luaL_error(L, "SDLError: %s", SDL_GetError());
|
||||
}
|
||||
|
|
19
LuaCommon.h
19
LuaCommon.h
|
@ -1,6 +1,23 @@
|
|||
#pragma once
|
||||
#include "LuaVM.h"
|
||||
#include "SDL2/include/SDL.h"
|
||||
#include <vector>
|
||||
|
||||
bool LuaCompareType(lua_State* L, int index, const char* type, bool leave = false);
|
||||
void check(lua_State* L, const std::vector<int>& typearr, const std::vector<const char*>& userdata_type = std::vector<const char*>());
|
||||
|
||||
// 从Lua Rect/Point转换到SDL_Rect. 给定index类型必须是table (此方法不会校验是否为table)
|
||||
// 正确转换则返回 0
|
||||
// 出错则返回 1, 同时将 type 放在栈上. (有可能是nil)
|
||||
int LuaRectPointToRect(lua_State* L, int index, SDL_Rect& r, int default_w = 0, int default_h = 0);
|
||||
|
||||
int LuaRectToRect(lua_State* L, int index, SDL_Rect& rect);
|
||||
int LuaPointToPoint(lua_State* L, int index, SDL_Point& point);
|
||||
|
||||
// 从Lua RGBA转换到SDL_Color. 给定index类型必须是table. (此方法不会校验是否为table)
|
||||
// 正确转换则返回 0
|
||||
// 出错则返回 1, 同时将 type 放在栈上. (有可能是nil)
|
||||
int LuaColorToColor(lua_State* L, int index, SDL_Color& c);
|
||||
|
||||
// Generate SDL error on lua stack.
|
||||
// NOTE: Never actually returns. If this function is used in C++ context, you should compile Lua as C++.
|
||||
int LuaSDLError(lua_State* L);
|
||||
|
|
1785
LuaEngine.cpp
1785
LuaEngine.cpp
File diff suppressed because it is too large
Load Diff
|
@ -2,6 +2,6 @@
|
|||
#undef main
|
||||
|
||||
|
||||
int InitEngine(lua_State* L);
|
||||
int StartEngine(lua_State* L);
|
||||
int InitEngine();
|
||||
int InitLibs(lua_State* L);
|
||||
int StopEngine();
|
||||
|
|
|
@ -10,7 +10,7 @@ using namespace std;
|
|||
|
||||
|
||||
/*
|
||||
Key code generated with Python script:
|
||||
Key code generated by Python script:
|
||||
```python
|
||||
lst = filter(lambda x: True if x else False, content.replace('\r', '').split('\n'))
|
||||
|
||||
|
@ -29,7 +29,7 @@ for line in lst:
|
|||
```
|
||||
*/
|
||||
|
||||
int InitEnum(lua_State* L)
|
||||
int InitKeys(lua_State* L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
addkey(SDLK_UNKNOWN, "unknown");
|
||||
|
@ -502,6 +502,5 @@ int InitEnum(lua_State* L)
|
|||
addkey(SDLK_AUDIOREWIND, "AUDIOREWIND");
|
||||
addkey(SDLK_AUDIOFASTFORWARD, "audiofastforward");
|
||||
addkey(SDLK_AUDIOFASTFORWARD, "AUDIOFASTFORWARD");
|
||||
lua_setglobal(L, "Keys");
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
#include "LuaVM.h"
|
||||
|
||||
int InitEnum(lua_State* L);
|
||||
// create a table on top of the stack.
|
||||
int InitKeys(lua_State* L);
|
||||
|
|
4
LuaHelper.h
Normal file
4
LuaHelper.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#define setfn(cfunc, name) lua_pushcfunction(L, cfunc);lua_setfield(L, -2, name)
|
||||
#define settype(type_name) lua_pushstring(L, type_name);lua_setfield(L, -2, "type")
|
132
LuaNetwork.cpp
132
LuaNetwork.cpp
|
@ -161,7 +161,7 @@ public:
|
|||
{
|
||||
for (int i = 0; i < maxSize; i++)
|
||||
{
|
||||
workers.emplace_back(task_runner, tasks[i]);
|
||||
workers.emplace_back(task_runner, ref(tasks[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -519,132 +519,6 @@ struct ClientSocket
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class ClassWrapper
|
||||
{
|
||||
public:
|
||||
bool __destroyed;
|
||||
const char* type;
|
||||
|
||||
struct Fuck
|
||||
{
|
||||
using TMemFn = int (T::*)(lua_State*);
|
||||
TMemFn f;
|
||||
};
|
||||
|
||||
static int destroy(lua_State* L)
|
||||
{
|
||||
T* t = static_cast<T*>(lua_touserdata(L, 1));
|
||||
if (!t->__destroyed)
|
||||
{
|
||||
t->__destroyed = true;
|
||||
t->~T();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int create(lua_State* L)
|
||||
{
|
||||
T* t = new (lua_newuserdata(L, sizeof(T))) T(L);
|
||||
t->__destroyed = false;
|
||||
|
||||
char mtname[64] = { 0 };
|
||||
sprintf(mtname, "__clsw_%u_mt", typeid(T).hash_code);
|
||||
|
||||
if (lua_getfield(L, LUA_REGISTRYINDEX, mtname) != LUA_TTABLE)
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, t->type);
|
||||
lua_setfield(L, -2, "type");
|
||||
lua_pushcfunction(L, destroy);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
lua_newtable(L);
|
||||
int __chk_before = lua_gettop(L);
|
||||
t->prepare(L); // T::prepare(lua_State*) must keep stack balance!
|
||||
int __chk_after = lua_gettop(L);
|
||||
if (__chk_before != __chk_after)
|
||||
{
|
||||
return luaL_error(L, "Stack unbalance detected while initializing: %s", type);
|
||||
}
|
||||
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, mtname);
|
||||
}
|
||||
|
||||
lua_setmetatable(L, -1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int LuaCallGate(lua_State* L)
|
||||
{
|
||||
if (lua_type(L, 1) != LUA_TUSERDATA)
|
||||
{
|
||||
return luaL_error(L, "Bad argument #1. userdata expected. Got %s.", lua_typename(L, lua_type(L, 1)));
|
||||
}
|
||||
if (!lua_getmetatable(L, 1))
|
||||
{
|
||||
return luaL_error(L, "Bad argument #1. cannot get metatable.");
|
||||
}
|
||||
char mtname[64] = { 0 };
|
||||
sprintf(mtname, "__clsw_%u_mt", typeid(T).hash_code);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, mtname);
|
||||
if (!lua_rawequal(L, -1, -2))
|
||||
{
|
||||
lua_pop(L, 2);
|
||||
return luaL_error(L, "Bad argument #1. metatable mismatch.");
|
||||
}
|
||||
lua_pop(L, 2);
|
||||
|
||||
T* p = (T*)(lua_touserdata(L, 1));
|
||||
|
||||
Fuck* f = (Fuck*)(lua_touserdata(L, lua_upvalueindex(1)));
|
||||
return std::invoke(f->f, *p, L);
|
||||
}
|
||||
|
||||
void AddFunction(lua_State* L, typename Fuck::TMemFn callable)
|
||||
{
|
||||
Fuck* f = new Fuck;
|
||||
f->f = callable;
|
||||
lua_pushlightuserdata(L, f);
|
||||
lua_pushcclosure(L, LuaCallGate, 1);
|
||||
}
|
||||
};
|
||||
|
||||
class MyClass : public ClassWrapper<MyClass>
|
||||
{
|
||||
public:
|
||||
string welcome;
|
||||
|
||||
MyClass(lua_State* L)
|
||||
{
|
||||
printf("MyClass ctor.\n");
|
||||
type = "MyClass";
|
||||
welcome = lua_tostring(L, 1);
|
||||
}
|
||||
|
||||
int showit(lua_State* L)
|
||||
{
|
||||
printf("In MyClass::showit, %s", welcome.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
~MyClass()
|
||||
{
|
||||
printf("MyClass dtor.\n");
|
||||
}
|
||||
|
||||
void prepare(lua_State* L)
|
||||
{
|
||||
AddFunction(L, &MyClass::showit);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int InitNetwork(lua_State* L)
|
||||
{
|
||||
WORD wd;
|
||||
|
@ -660,3 +534,7 @@ int InitNetwork(lua_State* L)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HandleNetworkEvent(lua_State* L, const SDL_Event& e)
|
||||
{
|
||||
}
|
||||
|
|
63
LuaVM.cpp
63
LuaVM.cpp
|
@ -0,0 +1,63 @@
|
|||
#include "LuaVM.h"
|
||||
|
||||
void pushvalue(lua_State* L, int val)
|
||||
{
|
||||
lua_pushinteger(L, val);
|
||||
}
|
||||
|
||||
void pushvalue(lua_State* L, double val)
|
||||
{
|
||||
lua_pushnumber(L, val);
|
||||
}
|
||||
|
||||
void pushvalue(lua_State* L, const char* str)
|
||||
{
|
||||
lua_pushstring(L, str);
|
||||
}
|
||||
|
||||
void pushvalue(lua_State* L, const char* str, int len)
|
||||
{
|
||||
lua_pushlstring(L, str, len);
|
||||
}
|
||||
|
||||
void pushvalue(lua_State* L, const std::string& str)
|
||||
{
|
||||
lua_pushlstring(L, str.c_str(), str.size());
|
||||
}
|
||||
|
||||
void pushvalue(lua_State* L, lua_CFunction fn)
|
||||
{
|
||||
lua_pushcfunction(L, fn);
|
||||
}
|
||||
|
||||
void pushvalue(lua_State* L, lua_CFunction fn, int nup)
|
||||
{
|
||||
lua_pushcclosure(L, fn, nup);
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const char* getvalue(lua_State* L, int index) // LUA_TSTRING
|
||||
{
|
||||
return luaL_checkstring(L, index);
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string getvalue(lua_State* L, int index) // LUA_TSTRING
|
||||
{
|
||||
size_t sz;
|
||||
const char* s = luaL_checklstring(L, index, &sz);
|
||||
return std::string(s, sz);
|
||||
}
|
||||
|
||||
template<>
|
||||
int getvalue(lua_State* L, int index) // LUA_TNUMBER
|
||||
{
|
||||
return (const int)luaL_checkinteger(L, index);
|
||||
}
|
||||
|
||||
template<>
|
||||
double getvalue(lua_State* L, int index) // LUA_TNUMBER
|
||||
{
|
||||
return luaL_checknumber(L, index);
|
||||
}
|
32
LuaVM.h
32
LuaVM.h
|
@ -2,7 +2,7 @@
|
|||
#include "lua/lua.h"
|
||||
#include "lua/lualib.h"
|
||||
#include "lua/lauxlib.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class LuaVM
|
||||
{
|
||||
|
@ -35,3 +35,33 @@ private:
|
|||
lua_State* _L;
|
||||
bool _managed;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
T& getuserdata(lua_State* L, int index) // LUA_TUSERDATA
|
||||
{
|
||||
return *(T*)luaL_checkudata(L, index, T::tname);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T getvalue(lua_State* L, int index);
|
||||
|
||||
template<typename T>
|
||||
T& pushvalue(lua_State* L)
|
||||
{
|
||||
return *(T*)lua_newuserdata(L, sizeof(T));
|
||||
}
|
||||
|
||||
void pushvalue(lua_State* L, int val);
|
||||
|
||||
void pushvalue(lua_State* L, double val);
|
||||
|
||||
void pushvalue(lua_State* L, const char* str);
|
||||
|
||||
void pushvalue(lua_State* L, const char* str, int len);
|
||||
|
||||
void pushvalue(lua_State* L, const std::string& str);
|
||||
|
||||
void pushvalue(lua_State* L, lua_CFunction fn);
|
||||
|
||||
void pushvalue(lua_State* L, lua_CFunction fn, int nup);
|
||||
|
|
11
LuaYard.cpp
11
LuaYard.cpp
|
@ -5,16 +5,19 @@ using namespace std;
|
|||
|
||||
int main()
|
||||
{
|
||||
InitEngine();
|
||||
do {
|
||||
LuaVM L;
|
||||
InitEngine(L);
|
||||
InitLibs(L);
|
||||
cout << "<ENGINE> Started." << endl;
|
||||
if (luaL_dofile(L, "code/init.lua"))
|
||||
{
|
||||
cout << lua_tostring(L, -1) << endl;
|
||||
cout << "<ENGINE FATAL ERROR> " << lua_tostring(L, -1) << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "<ENGINE> Stopped normally." << endl;
|
||||
}
|
||||
StartEngine(L);
|
||||
cout << "<ENGINE> Stopped." << endl;
|
||||
} while (0);
|
||||
StopEngine();
|
||||
}
|
||||
|
|
111
Music.cpp
Normal file
111
Music.cpp
Normal file
|
@ -0,0 +1,111 @@
|
|||
#include "Music.h"
|
||||
#include "LuaCommon.h"
|
||||
#include "LuaHelper.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
Mix_Chunk* Mix_LoadWAVEx(const char* filepath)
|
||||
{
|
||||
SDL_RWops* fileData = SDL_RWFromFile(filepath, "rb");
|
||||
if (!fileData)
|
||||
{
|
||||
std::cout << "Mix_LoadWAVEx() failed to call SDL_RWFromFile().\n\t\"" << SDL_GetError() << "\"" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Mix_Chunk* chunk = Mix_LoadWAV_RW(fileData, 1);
|
||||
if (!chunk)
|
||||
{
|
||||
std::cout << "Mix_LoadWAVEx() failed to call Mix_LoadWAV_RW().\n\t\"" << SDL_GetError() << "\"" << std::endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
inline int Chunk::close(lua_State* L)
|
||||
{
|
||||
auto p = (Chunk*)luaL_checkudata(L, 1, "chunk");
|
||||
p->~Chunk();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Chunk::create(lua_State* L)
|
||||
{
|
||||
cout << "In Chunk::create" << endl;
|
||||
const char* filepath = luaL_checkstring(L, 1);
|
||||
Mix_Chunk* c = Mix_LoadWAVEx(filepath);
|
||||
if (!c)
|
||||
{
|
||||
return LuaSDLError(L);
|
||||
}
|
||||
auto p = new (lua_newuserdata(L, sizeof(Chunk))) Chunk(c);
|
||||
if (luaL_newmetatable(L, "chunk"))
|
||||
{
|
||||
// GC
|
||||
lua_pushcfunction(L, close);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
// Fields
|
||||
lua_newtable(L);
|
||||
settype("chunk");
|
||||
setfn(close, "close");
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int Chunk::setVolume(lua_State* L)
|
||||
{
|
||||
auto p = (Chunk*)luaL_checkudata(L, 1, "chunk");
|
||||
int v = luaL_checkinteger(L, 2);
|
||||
int old = Mix_VolumeChunk(p->chunk.get(), v);
|
||||
lua_pushinteger(L, old);
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline Chunk::Chunk(Mix_Chunk* c) : chunk(c, Mix_FreeChunk)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline Music::Music(Mix_Music* m) : music(m, Mix_FreeMusic)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline int Music::close(lua_State* L)
|
||||
{
|
||||
cout << "In Music::close" << endl;
|
||||
auto p = (Music*)luaL_checkudata(L, 1, "music");
|
||||
p->~Music();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Music::create(lua_State* L)
|
||||
{
|
||||
cout << "In Music::create" << endl;
|
||||
const char* filepath = luaL_checkstring(L, 1);
|
||||
Mix_Music* m = Mix_LoadMUS(filepath);
|
||||
if (!m)
|
||||
{
|
||||
return LuaSDLError(L);
|
||||
}
|
||||
auto p = new (lua_newuserdata(L, sizeof(Music))) Music(m);
|
||||
if(luaL_newmetatable(L, "music"))
|
||||
{
|
||||
// GC
|
||||
lua_pushcfunction(L, close);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
// Fields
|
||||
lua_newtable(L);
|
||||
settype("music");
|
||||
setfn(close, "close");
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
28
Music.h
Normal file
28
Music.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
#include "LuaVM.h"
|
||||
#include "SDL2/include/SDL_mixer.h"
|
||||
#include <memory>
|
||||
|
||||
class Chunk
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<Mix_Chunk> chunk;
|
||||
|
||||
Chunk(Mix_Chunk* c);
|
||||
|
||||
static int setVolume(lua_State* L);
|
||||
|
||||
static int close(lua_State* L);
|
||||
static int create(lua_State* L);
|
||||
};
|
||||
|
||||
class Music
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<Mix_Music> music;
|
||||
|
||||
Music(Mix_Music* m);
|
||||
|
||||
static int close(lua_State* L);
|
||||
static int create(lua_State* L);
|
||||
};
|
349
MusicPlayer.cpp
Normal file
349
MusicPlayer.cpp
Normal file
|
@ -0,0 +1,349 @@
|
|||
#include "MusicPlayer.h"
|
||||
#include "Music.h"
|
||||
#include "LuaCommon.h"
|
||||
#include "LuaHelper.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
inline int MusicPlayer::close(lua_State* L)
|
||||
{
|
||||
cout << "In MusicPlayer::close" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::playMusic(lua_State* L)
|
||||
{
|
||||
Music* m = (Music*)luaL_checkudata(L, 1, "music");
|
||||
int nLoop = -1;
|
||||
if (lua_gettop(L) >= 2)
|
||||
{
|
||||
nLoop = luaL_checkinteger(L, 2);
|
||||
}
|
||||
int ret = Mix_PlayMusic(m->music.get(), nLoop);
|
||||
cout << "Play music ret: " << ret << " " << SDL_GetError() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::resumeMusic(lua_State* L)
|
||||
{
|
||||
Mix_ResumeMusic();
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::stopMusic(lua_State* L)
|
||||
{
|
||||
Mix_HaltMusic();
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::pauseMusic(lua_State* L)
|
||||
{
|
||||
Mix_PauseMusic();
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::rewindMusic(lua_State* L)
|
||||
{
|
||||
Mix_RewindMusic();
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::fadeInMusic(lua_State* L)
|
||||
{
|
||||
Music* m = (Music*)luaL_checkudata(L, 1, "music");
|
||||
int fadeTime = luaL_checkinteger(L, 2);
|
||||
int nLoop = -1;
|
||||
if (lua_gettop(L) >= 3)
|
||||
{
|
||||
nLoop = luaL_checkinteger(L, 3);
|
||||
}
|
||||
int ret = Mix_FadeInMusic(m->music.get(), nLoop, fadeTime);
|
||||
cout << "Fade in music ret: " << ret << " " << SDL_GetError() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::fadeInMusicPos(lua_State* L)
|
||||
{
|
||||
Music* m = (Music*)luaL_checkudata(L, 1, "music");
|
||||
int fadeTime = luaL_checkinteger(L, 2);
|
||||
double pos = luaL_checknumber(L, 3);
|
||||
int nLoop = -1;
|
||||
if (lua_gettop(L) >= 4)
|
||||
{
|
||||
nLoop = luaL_checkinteger(L, 4);
|
||||
}
|
||||
int ret = Mix_FadeInMusicPos(m->music.get(), nLoop, fadeTime, pos);
|
||||
cout << "Fade in music ret: " << ret << " " << SDL_GetError() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::fadeOutMusic(lua_State* L)
|
||||
{
|
||||
int fadeTime = luaL_checkinteger(L, 1);
|
||||
int ret = Mix_FadeOutMusic(fadeTime);
|
||||
cout << "Fade out music ret: " << ret << " " << SDL_GetError() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::setMusicVolume(lua_State* L)
|
||||
{
|
||||
int v = luaL_checkinteger(L, 1);
|
||||
int old = Mix_VolumeMusic(v);
|
||||
lua_pushinteger(L, old);
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::setMusicPos(lua_State* L)
|
||||
{
|
||||
double pos = luaL_checknumber(L, 1);
|
||||
int ret = Mix_SetMusicPosition(pos);
|
||||
if (ret != 0)
|
||||
{
|
||||
return LuaSDLError(L);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::isPlayingMusic(lua_State* L)
|
||||
{
|
||||
lua_pushboolean(L, Mix_PlayingMusic());
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::isPausedMusic(lua_State* L)
|
||||
{
|
||||
lua_pushboolean(L, Mix_PausedMusic());
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::isFadingMusic(lua_State* L)
|
||||
{
|
||||
switch (Mix_FadingMusic())
|
||||
{
|
||||
|
||||
|
||||
case MIX_FADING_OUT:
|
||||
lua_pushstring(L, "out");
|
||||
break;
|
||||
case MIX_FADING_IN:
|
||||
lua_pushstring(L, "in");
|
||||
break;
|
||||
case MIX_NO_FADING:
|
||||
default:
|
||||
lua_pushstring(L, "no");
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::playChannel(lua_State* L)
|
||||
{
|
||||
Chunk* c = (Chunk*)luaL_checkudata(L, 1, "chunk");
|
||||
int channel = luaL_checkinteger(L, 2);
|
||||
int nLoop = -1;
|
||||
if (lua_gettop(L) >= 3)
|
||||
{
|
||||
nLoop = luaL_checkinteger(L, 3);
|
||||
}
|
||||
|
||||
int ret = Mix_PlayChannel(channel, c->chunk.get(), nLoop);
|
||||
|
||||
cout << "Play channel ret: " << ret << " " << SDL_GetError() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::fadeInChannel(lua_State* L)
|
||||
{
|
||||
Chunk* c = (Chunk*)luaL_checkudata(L, 1, "chunk");
|
||||
int channel = luaL_checkinteger(L, 2);
|
||||
int fadeTime = luaL_checkinteger(L, 3);
|
||||
int nLoop = -1;
|
||||
if (lua_gettop(L) >= 4)
|
||||
{
|
||||
nLoop = luaL_checkinteger(L, 4);
|
||||
}
|
||||
int ret = Mix_FadeInChannel(channel, c->chunk.get(), nLoop, fadeTime);
|
||||
cout << "Fade in channel ret: " << ret << " " << SDL_GetError() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::fadeOutChannel(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
int fadeTime = luaL_checkinteger(L, 2);
|
||||
Mix_FadeOutChannel(channel, fadeTime);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::stopChannel(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
Mix_HaltChannel(channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::resumeChannel(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
Mix_Resume(channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::pauseChannel(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
Mix_Pause(channel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::isPlayingChannel(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
if (channel == -1)
|
||||
{
|
||||
lua_pushinteger(L, Mix_Playing(channel));
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(L, Mix_Playing(channel));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::isPausedChannel(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
if (channel == -1)
|
||||
{
|
||||
lua_pushinteger(L, Mix_Paused(channel));
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(L, Mix_Paused(channel));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::isFadingChannel(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
if (channel == -1)
|
||||
{
|
||||
return luaL_error(L, "Invalid channel id for isFadingChannel.");
|
||||
}
|
||||
|
||||
switch (Mix_FadingChannel(channel))
|
||||
{
|
||||
case MIX_FADING_OUT:
|
||||
lua_pushstring(L, "out");
|
||||
break;
|
||||
case MIX_FADING_IN:
|
||||
lua_pushstring(L, "in");
|
||||
break;
|
||||
case MIX_NO_FADING:
|
||||
default:
|
||||
lua_pushstring(L, "no");
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::setChannelVolume(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
int v = luaL_checkinteger(L, 2);
|
||||
int old = Mix_Volume(channel, v);
|
||||
lua_pushinteger(L, old);
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::setChannelDistance(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
int dist = luaL_checkinteger(L, 2);
|
||||
|
||||
int ret = Mix_SetDistance(channel, dist);
|
||||
if (ret == 0)
|
||||
{
|
||||
return LuaSDLError(L);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::setChannelPosition(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
int angle = luaL_checkinteger(L, 2);
|
||||
int dist = luaL_checkinteger(L, 3);
|
||||
cout << "Mix_SetPosition " << channel << " " << angle << " " << dist << endl;
|
||||
if (0 == Mix_SetPosition(channel, angle, dist))
|
||||
{
|
||||
return LuaSDLError(L);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::setChannelPanning(lua_State* L)
|
||||
{
|
||||
int channel = luaL_checkinteger(L, 1);
|
||||
int left = luaL_checkinteger(L, 2);
|
||||
int right = luaL_checkinteger(L, 3);
|
||||
if (0 == Mix_SetPanning(channel, left, right))
|
||||
{
|
||||
return LuaSDLError(L);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int MusicPlayer::setTotalChannel(lua_State* L)
|
||||
{
|
||||
int nTotal = luaL_checkinteger(L, 1);
|
||||
int count = Mix_AllocateChannels(nTotal);
|
||||
lua_pushinteger(L, count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MusicPlayer::create(lua_State* L)
|
||||
{
|
||||
cout << "In MusicPlayer::create" << endl;
|
||||
|
||||
if (luaL_newmetatable(L, "musicplayer"))
|
||||
{
|
||||
setfn(close, "close");
|
||||
setfn(playMusic, "playMusic");
|
||||
setfn(resumeMusic, "resumeMusic");
|
||||
setfn(pauseMusic, "pauseMusic");
|
||||
setfn(stopMusic, "stopMusic");
|
||||
setfn(rewindMusic, "rewindMusic");
|
||||
setfn(fadeInMusic, "fadeInMusic");
|
||||
setfn(fadeOutMusic, "fadeOutMusic");
|
||||
setfn(fadeInMusicPos, "fadeInMusicPos");
|
||||
|
||||
setfn(setMusicVolume, "setMusicVolume");
|
||||
setfn(setMusicPos, "setMusicPos");
|
||||
|
||||
setfn(isPlayingMusic, "isPlayingMusic");
|
||||
setfn(isPausedMusic, "isPausedMusic");
|
||||
setfn(isFadingMusic, "isFadingMusic");
|
||||
|
||||
setfn(playChannel, "playChannel");
|
||||
setfn(resumeChannel, "resumeChannel");
|
||||
setfn(pauseChannel, "pauseChannel");
|
||||
setfn(stopChannel, "stopChannel");
|
||||
setfn(fadeInChannel, "fadeInChannel");
|
||||
setfn(fadeOutChannel, "fadeOutChannel");
|
||||
|
||||
setfn(setChannelVolume, "setChannelVolume");
|
||||
setfn(setChannelDistance, "setChannelDistance");
|
||||
setfn(setChannelPosition, "setChannelPosition");
|
||||
setfn(setChannelPanning, "setChannelPanning");
|
||||
setfn(setTotalChannel, "setTotalChannel");
|
||||
|
||||
setfn(isPlayingChannel, "isPlayingChannel");
|
||||
setfn(isPausedChannel, "isPausedChannel");
|
||||
setfn(isFadingChannel, "isFadingChannel");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
66
MusicPlayer.h
Normal file
66
MusicPlayer.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
#include "LuaVM.h"
|
||||
#include "SDL2/include/SDL_mixer.h"
|
||||
|
||||
|
||||
class MusicPlayer
|
||||
{
|
||||
public:
|
||||
static int close(lua_State* L);
|
||||
|
||||
static int playMusic(lua_State* L);
|
||||
|
||||
static int resumeMusic(lua_State* L);
|
||||
|
||||
static int stopMusic(lua_State* L);
|
||||
|
||||
static int pauseMusic(lua_State* L);
|
||||
|
||||
static int rewindMusic(lua_State* L);
|
||||
|
||||
static int fadeInMusic(lua_State* L);
|
||||
|
||||
static int fadeInMusicPos(lua_State* L);
|
||||
|
||||
static int fadeOutMusic(lua_State* L);
|
||||
|
||||
static int setMusicVolume(lua_State* L);
|
||||
|
||||
static int setMusicPos(lua_State* L);
|
||||
|
||||
static int isPlayingMusic(lua_State* L);
|
||||
|
||||
static int isPausedMusic(lua_State* L);
|
||||
|
||||
static int isFadingMusic(lua_State* L);
|
||||
|
||||
static int playChannel(lua_State* L);
|
||||
|
||||
static int fadeInChannel(lua_State* L);
|
||||
|
||||
static int fadeOutChannel(lua_State* L);
|
||||
|
||||
static int stopChannel(lua_State* L);
|
||||
|
||||
static int resumeChannel(lua_State* L);
|
||||
|
||||
static int pauseChannel(lua_State* L);
|
||||
|
||||
static int isPlayingChannel(lua_State* L);
|
||||
|
||||
static int isPausedChannel(lua_State* L);
|
||||
|
||||
static int isFadingChannel(lua_State* L);
|
||||
|
||||
static int setChannelVolume(lua_State* L);
|
||||
|
||||
static int setChannelDistance(lua_State* L);
|
||||
|
||||
static int setChannelPosition(lua_State* L);
|
||||
|
||||
static int setChannelPanning(lua_State* L);
|
||||
|
||||
static int setTotalChannel(lua_State* L);
|
||||
|
||||
static int create(lua_State* L);
|
||||
};
|
201
Renderer.cpp
Normal file
201
Renderer.cpp
Normal file
|
@ -0,0 +1,201 @@
|
|||
#include "Renderer.h"
|
||||
#include "Texture.h"
|
||||
#include "Window.h"
|
||||
#include "SDL2/include/SDL_image.h"
|
||||
#include "LuaHelper.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
inline int Renderer::close(lua_State* L)
|
||||
{
|
||||
cout << "In Renderer::close" << endl;
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
p->~Renderer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Renderer::Renderer(SDL_Renderer* r) : rnd(r, SDL_DestroyRenderer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline int Renderer::update(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
SDL_RenderPresent(p->rnd.get());
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Renderer::clear(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
SDL_RenderClear(p->rnd.get());
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Renderer::setColor(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
|
||||
SDL_Color c;
|
||||
if (LuaColorToColor(L, 2, c))
|
||||
{
|
||||
luaL_error(L, "bad argument #2 to setColor. rgba expected, got %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor(p->rnd.get(), c.r, c.g, c.b, c.a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Renderer::getColor(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
Uint8 r, b, g, a;
|
||||
SDL_GetRenderDrawColor(p->rnd.get(), &r, &g, &b, &a);
|
||||
lua_newtable(L);
|
||||
lua_pushinteger(L, r);
|
||||
lua_setfield(L, -2, "r");
|
||||
lua_pushinteger(L, g);
|
||||
lua_setfield(L, -2, "g");
|
||||
lua_pushinteger(L, b);
|
||||
lua_setfield(L, -2, "b");
|
||||
lua_pushinteger(L, a);
|
||||
lua_setfield(L, -2, "a");
|
||||
lua_pushstring(L, "rgba");
|
||||
lua_setfield(L, -2, "type");
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int Renderer::drawRect(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
SDL_Rect r;
|
||||
if (LuaRectToRect(L, 2, r))
|
||||
{
|
||||
luaL_error(L, "bad argument #2 to drawRect. rect expected, got %s", lua_tostring(L, -1));
|
||||
}
|
||||
SDL_RenderDrawRect(p->rnd.get(), &r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Renderer::fillRect(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
SDL_Rect r;
|
||||
if (LuaRectToRect(L, 2, r))
|
||||
{
|
||||
luaL_error(L, "bad argument #2 to drawRect. rect expected, got %s", lua_tostring(L, -1));
|
||||
}
|
||||
SDL_RenderFillRect(p->rnd.get(), &r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Renderer::loadTexture(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
auto filepath = luaL_checkstring(L, 2);
|
||||
SDL_Texture* text = IMG_LoadTexture(p->rnd.get(), filepath);
|
||||
Texture::create(L, p->rnd, text);
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int Renderer::copy(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
auto t = (Texture*)luaL_checkudata(L, 2, "texture");
|
||||
luaL_checktype(L, 3, LUA_TTABLE);
|
||||
luaL_checktype(L, 4, LUA_TTABLE);
|
||||
|
||||
SDL_Rect src;
|
||||
if (LuaRectToRect(L, 3, src))
|
||||
{
|
||||
luaL_error(L, "bad argument #3 to copy. rect expected, got %s", lua_tostring(L, -1));
|
||||
}
|
||||
SDL_Rect dst;
|
||||
if (LuaRectToRect(L, 4, dst))
|
||||
{
|
||||
luaL_error(L, "bad argument #4 to copy. rect expected, got %s", lua_tostring(L, -1));
|
||||
}
|
||||
SDL_RenderCopy(p->rnd.get(), t->text.get(), &src, &dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Renderer::copyTo(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
auto t = (Texture*)luaL_checkudata(L, 2, "texture");
|
||||
luaL_checktype(L, 3, LUA_TTABLE);
|
||||
|
||||
SDL_Rect dst;
|
||||
if (LuaRectPointToRect(L, 3, dst, t->w, t->h))
|
||||
{
|
||||
luaL_error(L, "bad argument #4 to copy. rect/point expected, got %s", lua_tostring(L, -1));
|
||||
}
|
||||
SDL_RenderCopy(p->rnd.get(), t->text.get(), NULL, &dst);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Renderer::copyFill(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
auto t = (Texture*)luaL_checkudata(L, 2, "texture");
|
||||
luaL_checktype(L, 3, LUA_TTABLE);
|
||||
|
||||
SDL_Rect src;
|
||||
if (LuaRectToRect(L, 3, src))
|
||||
{
|
||||
luaL_error(L, "bad argument #4 to copy. rect/point expected, got %s", lua_tostring(L, -1));
|
||||
}
|
||||
SDL_RenderCopy(p->rnd.get(), t->text.get(), &src, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Renderer::copyFullFill(lua_State* L)
|
||||
{
|
||||
auto p = (Renderer*)luaL_checkudata(L, 1, "renderer");
|
||||
auto t = (Texture*)luaL_checkudata(L, 2, "texture");
|
||||
SDL_RenderCopy(p->rnd.get(), t->text.get(), NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Renderer::create(lua_State* L)
|
||||
{
|
||||
cout << "In Renderer::create" << endl;
|
||||
|
||||
auto w = (Window*)luaL_checkudata(L, 1, "window");
|
||||
|
||||
auto p = new (lua_newuserdata(L, sizeof(Renderer))) Renderer(SDL_CreateRenderer(w->wnd.get(), -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE));
|
||||
|
||||
if (luaL_newmetatable(L, "renderer"))
|
||||
{
|
||||
// Type
|
||||
lua_pushstring(L, "renderer");
|
||||
lua_setfield(L, -2, "type");
|
||||
|
||||
// GC
|
||||
lua_pushcfunction(L, close);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
// Fields
|
||||
lua_newtable(L);
|
||||
setfn(close, "close");
|
||||
setfn(update, "update");
|
||||
setfn(clear, "clear");
|
||||
setfn(setColor, "setColor");
|
||||
setfn(getColor, "getColor");
|
||||
setfn(drawRect, "drawRect");
|
||||
setfn(fillRect, "fillRect");
|
||||
setfn(loadTexture, "loadTexture");
|
||||
setfn(copy, "copy");
|
||||
setfn(copyTo, "copyTo");
|
||||
setfn(copyFill, "copyFill");
|
||||
setfn(copyFullFill, "copyFullFill");
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
38
Renderer.h
Normal file
38
Renderer.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
#include "LuaCommon.h"
|
||||
#include <memory>
|
||||
|
||||
|
||||
class Renderer
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<SDL_Renderer> rnd;
|
||||
|
||||
Renderer(SDL_Renderer* r);
|
||||
|
||||
static int update(lua_State* L);
|
||||
|
||||
static int clear(lua_State* L);
|
||||
|
||||
static int setColor(lua_State* L);
|
||||
|
||||
static int getColor(lua_State* L);
|
||||
|
||||
static int drawRect(lua_State* L);
|
||||
|
||||
static int fillRect(lua_State* L);
|
||||
|
||||
static int loadTexture(lua_State* L);
|
||||
|
||||
static int copy(lua_State* L);
|
||||
|
||||
static int copyTo(lua_State* L);
|
||||
|
||||
static int copyFill(lua_State* L);
|
||||
|
||||
static int copyFullFill(lua_State* L);
|
||||
|
||||
static int close(lua_State* L);
|
||||
|
||||
static int create(lua_State* L);
|
||||
};
|
37
Surface.cpp
Normal file
37
Surface.cpp
Normal file
|
@ -0,0 +1,37 @@
|
|||
#include "Surface.h"
|
||||
#include "LuaHelper.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
inline Surface::Surface(SDL_Surface* s) : surf(s, SDL_FreeSurface)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline int Surface::close(lua_State* L)
|
||||
{
|
||||
cout << "In Surface::close" << endl;
|
||||
auto p = (Surface*)luaL_checkudata(L, 1, "surface");
|
||||
p->~Surface();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Surface::create(lua_State* L, SDL_Surface* s)
|
||||
{
|
||||
cout << "In Surface::create" << endl;
|
||||
auto p = new (lua_newuserdata(L, sizeof(Surface))) Surface(s);
|
||||
if (luaL_newmetatable(L, "surface"))
|
||||
{
|
||||
// GC
|
||||
lua_pushcfunction(L, close);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
// Fields
|
||||
lua_newtable(L);
|
||||
settype("surface");
|
||||
setfn(close, "close");
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
16
Surface.h
Normal file
16
Surface.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
#include "LuaVM.h"
|
||||
#include "SDL2/include/SDL.h"
|
||||
#include <memory>
|
||||
|
||||
class Surface
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<SDL_Surface> surf;
|
||||
|
||||
Surface(SDL_Surface* s);
|
||||
|
||||
static int close(lua_State* L);
|
||||
// static int create(lua_State* L, SDL_Surface* surf);
|
||||
static int create(lua_State* L, SDL_Surface* s);
|
||||
};
|
41
Texture.cpp
Normal file
41
Texture.cpp
Normal file
|
@ -0,0 +1,41 @@
|
|||
#include "Texture.h"
|
||||
#include "LuaHelper.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
inline Texture::Texture(const std::shared_ptr<SDL_Renderer>& exrnd, SDL_Texture* t) : rnd(exrnd), text(t, SDL_DestroyTexture)
|
||||
{
|
||||
SDL_QueryTexture(t, NULL, NULL, &w, &h);
|
||||
}
|
||||
|
||||
int Texture::create(lua_State* L, const std::shared_ptr<SDL_Renderer>& rnd, SDL_Texture* t)
|
||||
{
|
||||
cout << "In Texture::create" << endl;
|
||||
auto p = new (lua_newuserdata(L, sizeof(Texture))) Texture(rnd, t);
|
||||
// Metatable
|
||||
if (luaL_newmetatable(L, "texture"))
|
||||
{
|
||||
// Type
|
||||
lua_pushstring(L, "texture");
|
||||
lua_setfield(L, -2, "type");
|
||||
|
||||
// GC
|
||||
lua_pushcfunction(L, close);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
// Fields
|
||||
lua_newtable(L);
|
||||
setfn(close, "close");
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int Texture::close(lua_State* L)
|
||||
{
|
||||
cout << "In Texture::close" << endl;
|
||||
auto p = (Texture*)luaL_checkudata(L, 1, "texture");
|
||||
p->~Texture();
|
||||
return 0;
|
||||
}
|
19
Texture.h
Normal file
19
Texture.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#pragma once
|
||||
#include "LuaVM.h"
|
||||
#include "SDL2/include/SDL.h"
|
||||
#include <memory>
|
||||
|
||||
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<SDL_Renderer> rnd;
|
||||
std::shared_ptr<SDL_Texture> text;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
Texture(const std::shared_ptr<SDL_Renderer>& exrnd, SDL_Texture* t);
|
||||
|
||||
static int close(lua_State* L);
|
||||
static int create(lua_State* L, const std::shared_ptr<SDL_Renderer>& rnd, SDL_Texture* t);
|
||||
};
|
78
Window.cpp
Normal file
78
Window.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include "Window.h"
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define setfn(cfunc, name) lua_pushcfunction(L, cfunc);lua_setfield(L, -2, name)
|
||||
|
||||
inline int Window::close(lua_State* L)
|
||||
{
|
||||
cout << "In Window::close" << endl;
|
||||
auto p = (Window*)luaL_checkudata(L, 1, "window");
|
||||
p->~Window();
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Window::showWindow(lua_State* L)
|
||||
{
|
||||
auto p = (Window*)luaL_checkudata(L, 1, "window");
|
||||
SDL_ShowWindow(p->wnd.get());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int Window::hideWindow(lua_State* L)
|
||||
{
|
||||
auto p = (Window*)luaL_checkudata(L, 1, "window");
|
||||
SDL_HideWindow(p->wnd.get());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Window::getWindowID(lua_State* L)
|
||||
{
|
||||
auto p = (Window*)luaL_checkudata(L, 1, "window");
|
||||
lua_pushinteger(L, SDL_GetWindowID(p->wnd.get()));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int Window::create(lua_State* L)
|
||||
{
|
||||
auto title = luaL_checkstring(L, 1);
|
||||
int w = luaL_checkinteger(L, 2);
|
||||
int h = luaL_checkinteger(L, 3);
|
||||
|
||||
cout << "In Window::create" << endl;
|
||||
auto p = new (lua_newuserdata(L, sizeof(Window))) Window(w, h, title);
|
||||
|
||||
// Data table (for storing lua values)
|
||||
lua_newtable(L);
|
||||
lua_setuservalue(L, -2);
|
||||
|
||||
// Metatable
|
||||
if (luaL_newmetatable(L, "window"))
|
||||
{
|
||||
// Type
|
||||
lua_pushstring(L, "window");
|
||||
lua_setfield(L, -2, "type");
|
||||
|
||||
// GC
|
||||
lua_pushcfunction(L, close);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
// Fields
|
||||
lua_newtable(L);
|
||||
setfn(close, "close");
|
||||
setfn(showWindow, "show");
|
||||
setfn(hideWindow, "hide");
|
||||
setfn(getWindowID, "getid");
|
||||
lua_setfield(L, -2, "__index");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
Window::Window(int w, int h, const char* title) : wnd(SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, SDL_WINDOW_HIDDEN), SDL_DestroyWindow)
|
||||
{
|
||||
|
||||
}
|
||||
|
22
Window.h
Normal file
22
Window.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
#include "LuaVM.h"
|
||||
#include "SDL2/include/SDL.h"
|
||||
#include <memory>
|
||||
|
||||
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<SDL_Window> wnd;
|
||||
|
||||
Window(int w, int h, const char* title);
|
||||
|
||||
static int getWindowID(lua_State* L);
|
||||
|
||||
static int showWindow(lua_State* L);
|
||||
|
||||
static int hideWindow(lua_State* L);
|
||||
|
||||
static int close(lua_State* L);
|
||||
static int create(lua_State* L);
|
||||
};
|
|
@ -1,3 +1,12 @@
|
|||
local Window = require("window")
|
||||
local Renderer = require("renderer")
|
||||
local Font = require("font")
|
||||
local MusicPlayer = require("musicplayer")
|
||||
local Chunk = require("chunk")
|
||||
local Music = require("music")
|
||||
local fs = require('fs')
|
||||
local utils = require("utils")
|
||||
|
||||
local wnd = Window("Hello", 1024, 768)
|
||||
local rnd = Renderer(wnd)
|
||||
local font = Font("asserts/msyh.ttf", 18)
|
||||
|
@ -23,7 +32,7 @@ local next_music = 1
|
|||
|
||||
for i, info in ipairs(all_music) do
|
||||
local filename = string.format("tmp\\tmp_%d.wav", i)
|
||||
ConvertMusic(string.format("asserts\\mp3\\%s",info.name), filename, function()
|
||||
utils.ConvertMusic(string.format("asserts\\mp3\\%s",info.name), filename, function()
|
||||
print(filename, "convert finished.")
|
||||
print("Start loading: ", filename)
|
||||
table.insert(music_table, Chunk(filename))
|
||||
|
@ -41,24 +50,25 @@ setmetatable(texture_track, {
|
|||
__mode = "k"
|
||||
})
|
||||
|
||||
wnd:on('mousedown', function(x, y)
|
||||
print("Clicked", x, y)
|
||||
local t = font:renderText(rnd, string.format("%.0f,%.0f", x, y), {r=255,g=255,b=255,a=0,type="color"})
|
||||
wnd:on('mousedown', function(e)
|
||||
print("Clicked", e.x, e.y)
|
||||
local t = font:renderText(rnd, string.format("%.0f,%.0f", e.x, e.y), RGBA(255, 255, 255, 0))
|
||||
texture_track[t] = true
|
||||
rnd:copyTo(t, {x=x,y=y,type="point"})
|
||||
rnd:copyTo(t, Point(e.x, e.y))
|
||||
rnd:update()
|
||||
end)
|
||||
|
||||
wnd:on('mousemove', function(x, y, xrel, yrel)
|
||||
-- print("Mousemove", x, y, xrel, yrel)
|
||||
wnd:on('mousemove', function(e)
|
||||
-- print("Mousemove", e.x, e.y, e.xrel, e.yrel)
|
||||
end)
|
||||
|
||||
wnd:on('quit', function()
|
||||
print("before quit")
|
||||
return false
|
||||
end)
|
||||
|
||||
wnd:on('keydown', function(key)
|
||||
wnd:on('keydown', function(e)
|
||||
local key = e.key
|
||||
|
||||
print("keydown", key)
|
||||
if key == string.byte('q') then
|
||||
local current = collectgarbage("count")
|
||||
|
@ -74,12 +84,12 @@ wnd:on('keydown', function(key)
|
|||
print ("Tracked texture: ", cnt)
|
||||
return
|
||||
elseif key == string.byte('p') then
|
||||
musicPlayer:fadeOutChannel(last_channel, 5000)
|
||||
musicPlayer.fadeOutChannel(last_channel, 5000)
|
||||
if not music_table[next_music] then
|
||||
next_music = 1
|
||||
end
|
||||
print("Playing", next_music, next_channel)
|
||||
musicPlayer:fadeInChannel(music_table[next_music], next_channel, 1, 3000)
|
||||
musicPlayer.fadeInChannel(music_table[next_music], next_channel, 1, 3000)
|
||||
next_music = next_music + 1
|
||||
last_channel = next_channel
|
||||
next_channel = next_channel + 1
|
||||
|
@ -92,8 +102,8 @@ wnd:on('keydown', function(key)
|
|||
rnd:clear()
|
||||
local t = rnd:loadTexture("asserts/bqb_all/" .. all_bqb[math.random(#all_bqb)].name)
|
||||
texture_track[t] = true
|
||||
rnd:copyTo(t, {x=0,y=0,type="point"})
|
||||
rnd:copyTo(t, Point(0, 0))
|
||||
rnd:update()
|
||||
end)
|
||||
|
||||
wnd:show()
|
||||
wnd:show()
|
||||
|
|
119
code/init.lua
119
code/init.lua
|
@ -1,6 +1,49 @@
|
|||
-- Tweaks
|
||||
local plainRenderer = Renderer
|
||||
Renderer = function(...)
|
||||
local engine = require("engine")
|
||||
|
||||
------------------------- Events -------------------------
|
||||
local event = {}
|
||||
local timers = {}
|
||||
local listeners = {}
|
||||
local callbacks = {}
|
||||
local window_map = {}
|
||||
function event.window_listen(wnd, event_name, cb)
|
||||
local window_id = wnd:getid()
|
||||
window_map[window_id] = wnd
|
||||
|
||||
if not listeners[window_id] then
|
||||
listeners[window_id] = {}
|
||||
end
|
||||
if not listeners[window_id][event_name] then
|
||||
listeners[window_id][event_name] = {}
|
||||
end
|
||||
listeners[window_id][event_name][cb] = true
|
||||
end
|
||||
function event.listen(event_name, cb)
|
||||
if not listeners[event_name] then
|
||||
listeners[event_name] = {}
|
||||
end
|
||||
listeners[event_name][cb] = true
|
||||
end
|
||||
|
||||
------------------------- Utils -------------------------
|
||||
local utils = {}
|
||||
function utils.ConvertMusic(from, target, cb)
|
||||
table.insert(callbacks, cb)
|
||||
engine.convertMusic(from, target, #callbacks)
|
||||
end
|
||||
function utils.setInterval(cb, ms)
|
||||
local tid = engine.setInterval(ms)
|
||||
timers[tid] = cb
|
||||
end
|
||||
function utils.setTimeout(cb, ms)
|
||||
local tid = engine.setTimeout(ms)
|
||||
timers[tid] = cb
|
||||
end
|
||||
package.loaded["utils"] = utils
|
||||
|
||||
------------------------- Tweaks -------------------------
|
||||
local plainRenderer = require("renderer")
|
||||
package.loaded["renderer"] = function(...)
|
||||
local r = plainRenderer(...)
|
||||
local mt = getmetatable(r)
|
||||
local oldFunc = mt.__index.loadTexture
|
||||
|
@ -23,12 +66,26 @@ Renderer = function(...)
|
|||
end
|
||||
return text
|
||||
end
|
||||
Renderer = plainRenderer
|
||||
package.loaded["renderer"] = plainRenderer
|
||||
return r
|
||||
end
|
||||
local plainWindow = require("window")
|
||||
package.loaded["window"] = function(...)
|
||||
local w = plainWindow(...)
|
||||
local mt = getmetatable(w)
|
||||
mt.__index["on"] = function(wnd, event_name, cb)
|
||||
if event_name == "quit" then
|
||||
event.listen("quit", cb)
|
||||
else
|
||||
event.window_listen(wnd, event_name, cb)
|
||||
end
|
||||
end
|
||||
package.loaded["window"] = plainWindow
|
||||
return w
|
||||
end
|
||||
|
||||
-- Promise, Async/Await Helpers
|
||||
function Promise(callback)
|
||||
------------------------- Promise, Async/Await Helpers -------------------------
|
||||
function Promise(cb)
|
||||
local p = {
|
||||
__waiting = {},
|
||||
__status = 0
|
||||
|
@ -54,7 +111,7 @@ function Promise(callback)
|
|||
end
|
||||
end
|
||||
|
||||
callback(p.resolve, p.reject)
|
||||
cb(p.resolve, p.reject)
|
||||
|
||||
return p
|
||||
end
|
||||
|
@ -95,14 +152,50 @@ function async(fn)
|
|||
end
|
||||
end
|
||||
|
||||
-- Load & run game
|
||||
local gameMain, err = loadfile("code/network_test.lua")
|
||||
------------------------- Load & run game -------------------------
|
||||
local gameMain, err = loadfile("code/game.lua")
|
||||
if not gameMain then
|
||||
print("Failed to load chunk.")
|
||||
print("Lua compile error:")
|
||||
print(err)
|
||||
error("Abort")
|
||||
else
|
||||
xpcall(gameMain, function(err)
|
||||
print("LuaMain Exception: ", err)
|
||||
if not xpcall(gameMain, function(err)
|
||||
print("Uncaught Exception from LuaMain: ", err)
|
||||
print(debug.traceback())
|
||||
end)
|
||||
end) then
|
||||
error("Abort")
|
||||
end
|
||||
end
|
||||
|
||||
------------------------- Event handling -------------------------
|
||||
local engineState = true
|
||||
|
||||
local function DispatchEvent(e)
|
||||
if e.windowID then
|
||||
if listeners[e.windowID] and listeners[e.windowID][e.type] then
|
||||
for k in pairs(listeners[e.windowID][e.type]) do
|
||||
k(e)
|
||||
end
|
||||
end
|
||||
elseif e.type == "general" then
|
||||
callbacks[e.ticket]()
|
||||
elseif e.type == "quit" then
|
||||
for k in pairs(listeners["quit"]) do
|
||||
local ret = k()
|
||||
if ret or ret == nil then
|
||||
engineState = false
|
||||
end
|
||||
end
|
||||
else
|
||||
if listeners[e.type] then
|
||||
for k in pairs(listeners[e.type]) do
|
||||
k(e)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
while engineState do
|
||||
local e = engine.waitEvent()
|
||||
DispatchEvent(e)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user