独立事件循环
将事件循环从Window类移动到Top Level.
This commit is contained in:
parent
eca430ca69
commit
f1ef4bfc9d
565
LuaEngine.cpp
565
LuaEngine.cpp
|
@ -68,6 +68,13 @@ void check(lua_State* L, const vector<int>& typearr, const vector<const char*>&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate SDL error on lua stack.
|
||||||
|
// NOTE: Never returns. If this function is used in C++ context, you should compile Lua as C++.
|
||||||
|
void LuaSDLError(lua_State* L)
|
||||||
|
{
|
||||||
|
luaL_error(L, "SDLError: %s", SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
void ConvertMusicAsyncImpl(const string& filename, const string& targetname, int ticket)
|
void ConvertMusicAsyncImpl(const string& filename, const string& targetname, int ticket)
|
||||||
{
|
{
|
||||||
string command = "bin\\ffmpeg.exe -y -loglevel error -hide_banner -i \""s + filename + "\" \"" + targetname + "\"";
|
string command = "bin\\ffmpeg.exe -y -loglevel error -hide_banner -i \""s + filename + "\" \"" + targetname + "\"";
|
||||||
|
@ -162,218 +169,57 @@ struct Window
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int start(lua_State* L)
|
|
||||||
{
|
|
||||||
check(L, { LUA_TUSERDATA });
|
|
||||||
Window* p = (Window*)lua_touserdata(L, 1);
|
|
||||||
lua_settop(L, 1);
|
|
||||||
lua_pushlightuserdata(L, p);
|
|
||||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
||||||
|
|
||||||
bool running = true;
|
|
||||||
|
|
||||||
SDL_Event e;
|
|
||||||
while (running && SDL_WaitEvent(&e))
|
|
||||||
{
|
|
||||||
switch (e.type)
|
|
||||||
{
|
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
|
||||||
{
|
|
||||||
if (lua_getfield(L, -1, "onmousedown") != LUA_TNIL)
|
|
||||||
{
|
|
||||||
lua_pushnumber(L, e.button.x);
|
|
||||||
lua_pushnumber(L, e.button.y);
|
|
||||||
lua_pushnumber(L, e.button.button);
|
|
||||||
const char* arr[8];
|
|
||||||
int ret = GetMouseState(arr, e.button.state);
|
|
||||||
lua_newtable(L);
|
|
||||||
for (int i = 0; i < ret; i++)
|
|
||||||
{
|
|
||||||
lua_pushboolean(L, 1);
|
|
||||||
lua_setfield(L, -2, arr[i]);
|
|
||||||
}
|
|
||||||
lua_call(L, 4, LUA_MULTRET);
|
|
||||||
}
|
|
||||||
else lua_pop(L, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_MOUSEBUTTONUP:
|
|
||||||
{
|
|
||||||
if (lua_getfield(L, -1, "onmouseup") != LUA_TNIL)
|
|
||||||
{
|
|
||||||
lua_pushnumber(L, e.button.x);
|
|
||||||
lua_pushnumber(L, e.button.y);
|
|
||||||
lua_pushnumber(L, e.button.button);
|
|
||||||
const char* arr[8];
|
|
||||||
int ret = GetMouseState(arr, e.button.state);
|
|
||||||
lua_newtable(L);
|
|
||||||
for (int i = 0; i < ret; i++)
|
|
||||||
{
|
|
||||||
lua_pushboolean(L, 1);
|
|
||||||
lua_setfield(L, -2, arr[i]);
|
|
||||||
}
|
|
||||||
lua_call(L, 3, LUA_MULTRET);
|
|
||||||
}
|
|
||||||
else lua_pop(L, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_MOUSEMOTION:
|
|
||||||
{
|
|
||||||
if (lua_getfield(L, -1, "onmousemove") != LUA_TNIL)
|
|
||||||
{
|
|
||||||
lua_pushnumber(L, e.motion.x);
|
|
||||||
lua_pushnumber(L, e.motion.y);
|
|
||||||
lua_pushnumber(L, e.motion.xrel);
|
|
||||||
lua_pushnumber(L, e.motion.yrel);
|
|
||||||
const char* arr[8];
|
|
||||||
int ret = GetMouseState(arr, e.button.state);
|
|
||||||
lua_newtable(L);
|
|
||||||
for (int i = 0; i < ret; i++)
|
|
||||||
{
|
|
||||||
lua_pushboolean(L, 1);
|
|
||||||
lua_setfield(L, -2, arr[i]);
|
|
||||||
}
|
|
||||||
lua_call(L, 5, LUA_MULTRET);
|
|
||||||
}
|
|
||||||
else lua_pop(L, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_QUIT:
|
|
||||||
{
|
|
||||||
if (lua_getfield(L, -1, "onquit") != LUA_TNIL)
|
|
||||||
{
|
|
||||||
lua_call(L, 0, LUA_MULTRET);
|
|
||||||
}
|
|
||||||
else lua_pop(L, 1);
|
|
||||||
running = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
{
|
|
||||||
if (lua_getfield(L, -1, "onkeydown") != LUA_TNIL)
|
|
||||||
{
|
|
||||||
lua_pushnumber(L, e.key.keysym.sym);
|
|
||||||
lua_call(L, 1, LUA_MULTRET);
|
|
||||||
}
|
|
||||||
else lua_pop(L, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_KEYUP:
|
|
||||||
{
|
|
||||||
if (lua_getfield(L, -1, "onkeyup") != LUA_TNIL)
|
|
||||||
{
|
|
||||||
lua_pushnumber(L, e.key.keysym.sym);
|
|
||||||
lua_call(L, 1, LUA_MULTRET);
|
|
||||||
}
|
|
||||||
else lua_pop(L, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_USEREVENT:
|
|
||||||
{
|
|
||||||
switch (e.user.code)
|
|
||||||
{
|
|
||||||
case 1001:
|
|
||||||
{
|
|
||||||
LuaTimerCallbackData* pd = (LuaTimerCallbackData* )e.user.data1;
|
|
||||||
lua_pushlightuserdata(L, pd->p);
|
|
||||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
||||||
lua_pushfstring(L, "tmcb%d", pd->id);
|
|
||||||
lua_gettable(L, -2);
|
|
||||||
delete pd;
|
|
||||||
lua_call(L, 0, LUA_MULTRET);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1002:
|
|
||||||
{
|
|
||||||
// 全局回调, 异步操作无返回值
|
|
||||||
lua_pushfstring(L, "cb%d", *(int*)e.user.data1);
|
|
||||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
||||||
delete e.user.data1;
|
|
||||||
lua_call(L, 0, LUA_MULTRET);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1003:
|
|
||||||
{
|
|
||||||
// 音乐播放完毕
|
|
||||||
if (lua_getfield(L, -1, "onmusicover") != LUA_TNIL)
|
|
||||||
{
|
|
||||||
lua_call(L, 0, LUA_MULTRET);
|
|
||||||
}
|
|
||||||
else lua_pop(L, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 1004:
|
|
||||||
{
|
|
||||||
// 频道播放完毕
|
|
||||||
if (lua_getfield(L, -1, "onchannelover") != LUA_TNIL)
|
|
||||||
{
|
|
||||||
lua_pushinteger(L, *(int*)e.user.data1);
|
|
||||||
delete e.user.data1;
|
|
||||||
lua_call(L, 1, LUA_MULTRET);
|
|
||||||
}
|
|
||||||
else lua_pop(L, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
cout << e.type << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_event_handler(lua_State* L)
|
static int set_event_handler(lua_State* L)
|
||||||
{
|
{
|
||||||
check(L, { LUA_TUSERDATA, LUA_TSTRING, LUA_TFUNCTION });
|
check(L, { LUA_TUSERDATA, LUA_TSTRING, LUA_TFUNCTION }, { "window" });
|
||||||
Window* p = (Window*)lua_touserdata(L, 1);
|
if (strcmp(lua_tostring(L, 2), "quit") == 0) // quit事件特殊处理
|
||||||
lua_pushlightuserdata(L, p);
|
{
|
||||||
|
lua_pushlightuserdata(L, &StartEngine);
|
||||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
lua_getfield(L, -1, "onquit");
|
||||||
|
lua_pushvalue(L, 3);
|
||||||
|
lua_setfield(L, -3, "onquit");
|
||||||
|
return 1; // return old callback.
|
||||||
|
}
|
||||||
|
|
||||||
|
Window* p = (Window*)lua_touserdata(L, 1);
|
||||||
|
if (p->wnd)
|
||||||
|
{
|
||||||
|
lua_pushlightuserdata(L, p->wnd);
|
||||||
|
if (lua_gettable(L, LUA_REGISTRYINDEX) != LUA_TTABLE)
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, p->wnd);
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
lua_pushfstring(L, "on%s", lua_tostring(L, 2));
|
lua_pushfstring(L, "on%s", lua_tostring(L, 2));
|
||||||
lua_pushvalue(L, 3);
|
lua_pushvalue(L, 3);
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
return 0;
|
|
||||||
|
lua_settable(L, LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
lua_pushnil(L); // No old callback. Will return empty.
|
||||||
}
|
}
|
||||||
|
else
|
||||||
static int setTimeout(lua_State* L)
|
|
||||||
{
|
{
|
||||||
check(L, { LUA_TUSERDATA, LUA_TFUNCTION, LUA_TNUMBER }); // ms
|
lua_pushfstring(L, "on%s", lua_tostring(L, 2));
|
||||||
Window* p = (Window*)lua_touserdata(L, 1);
|
lua_pushvalue(L, -1);
|
||||||
|
// window, eventName, callback, windowCBTable, onEvent, onEvent
|
||||||
LuaTimerCallbackData* pd = new LuaTimerCallbackData();
|
lua_gettable(L, -3);
|
||||||
pd->p = p;
|
// window, eventName, callback, windowCBTable, onEvent, oldCallback
|
||||||
pd->type = 0;
|
lua_pushvalue(L, -2);
|
||||||
pd->id = SDL_AddTimer(lua_tointeger(L, 3), LuaTimerCallbackGate, pd);
|
lua_pushvalue(L, 3);
|
||||||
|
// window, eventName, callback, windowCBTable, onEvent, oldCallback, onEvent, callback
|
||||||
lua_pushlightuserdata(L, p);
|
lua_settable(L, -5);
|
||||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
// window, eventName, callback, windowCBTable, onEvent, oldCallback
|
||||||
lua_pushfstring(L, "tmcb%d", pd->id);
|
|
||||||
lua_pushvalue(L, 2);
|
|
||||||
lua_settable(L, -3);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
static int setInterval(lua_State* L)
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
check(L, { LUA_TUSERDATA, LUA_TFUNCTION, LUA_TNUMBER }); // ms
|
return luaL_error(L, "Unable to add event listener to null window.");
|
||||||
Window* p = (Window*)lua_touserdata(L, 1);
|
}
|
||||||
|
|
||||||
LuaTimerCallbackData* pd = new LuaTimerCallbackData();
|
|
||||||
pd->p = p;
|
|
||||||
pd->type = 1;
|
|
||||||
pd->id = SDL_AddTimer(lua_tointeger(L, 3), LuaTimerCallbackGate, pd);
|
|
||||||
|
|
||||||
lua_pushlightuserdata(L, p);
|
|
||||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
||||||
lua_pushfstring(L, "tmcb%d", pd->id);
|
|
||||||
lua_pushvalue(L, 2);
|
|
||||||
lua_settable(L, -3);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int showWindow(lua_State* L)
|
static int showWindow(lua_State* L)
|
||||||
|
@ -418,9 +264,6 @@ struct Window
|
||||||
lua_pushstring(L, "window"); lua_setfield(L, -2, "type");
|
lua_pushstring(L, "window"); lua_setfield(L, -2, "type");
|
||||||
setfn(L, close, "close");
|
setfn(L, close, "close");
|
||||||
setfn(L, set_event_handler, "on");
|
setfn(L, set_event_handler, "on");
|
||||||
setfn(L, start, "start");
|
|
||||||
setfn(L, setTimeout, "setTimeout");
|
|
||||||
setfn(L, setInterval, "setInterval");
|
|
||||||
setfn(L, showWindow, "show");
|
setfn(L, showWindow, "show");
|
||||||
setfn(L, hideWindow, "hide");
|
setfn(L, hideWindow, "hide");
|
||||||
|
|
||||||
|
@ -870,6 +713,25 @@ struct Font
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
struct Chunk
|
struct Chunk
|
||||||
{
|
{
|
||||||
Mix_Chunk* chunk;
|
Mix_Chunk* chunk;
|
||||||
|
@ -928,7 +790,7 @@ struct Chunk
|
||||||
|
|
||||||
const char* filename = lua_tostring(L, 1);
|
const char* filename = lua_tostring(L, 1);
|
||||||
cout << "LoadWAV: " << filename << endl;
|
cout << "LoadWAV: " << filename << endl;
|
||||||
c->chunk = Mix_LoadWAV(filename);
|
c->chunk = Mix_LoadWAVEx(filename);
|
||||||
cout << "Load chunk error: " << SDL_GetError() << endl;
|
cout << "Load chunk error: " << SDL_GetError() << endl;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1365,6 +1227,62 @@ void _Global_On_Channel_Finished(int channel)
|
||||||
SDL_PushEvent(&e);
|
SDL_PushEvent(&e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int setTimeout(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TFUNCTION, LUA_TNUMBER }); // setTimeout(cb: function, ms: number)
|
||||||
|
|
||||||
|
LuaTimerCallbackData* pd = new LuaTimerCallbackData();
|
||||||
|
pd->p = nullptr;
|
||||||
|
pd->type = 0;
|
||||||
|
pd->id = SDL_AddTimer(lua_tointeger(L, 2), LuaTimerCallbackGate, pd);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, &setTimeout);
|
||||||
|
if (lua_gettable(L, LUA_REGISTRYINDEX) != LUA_TTABLE)
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, &setTimeout);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
lua_seti(L, -2, pd->id); // { [timerID] = callback }
|
||||||
|
|
||||||
|
lua_settable(L, LUA_REGISTRYINDEX); // registry[&setTimeout] = timerCallbackTable
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
lua_seti(L, -2, pd->id); // timerCallbackTable[timerID] = callback
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setInterval(lua_State* L)
|
||||||
|
{
|
||||||
|
check(L, { LUA_TFUNCTION, LUA_TNUMBER }); // setTimeout(cb: function, ms: number)
|
||||||
|
|
||||||
|
LuaTimerCallbackData* pd = new LuaTimerCallbackData();
|
||||||
|
pd->p = nullptr;
|
||||||
|
pd->type = 1;
|
||||||
|
pd->id = SDL_AddTimer(lua_tointeger(L, 2), LuaTimerCallbackGate, pd);
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, &setTimeout);
|
||||||
|
if (lua_gettable(L, LUA_REGISTRYINDEX) != LUA_TTABLE)
|
||||||
|
{
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
lua_seti(L, -2, pd->id); // { [timerID] = callback }
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, &setTimeout);
|
||||||
|
lua_settable(L, LUA_REGISTRYINDEX); // registry[&setTimeout] = timerCallbackTable
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
lua_seti(L, -2, pd->id); // timerCallbackTable[timerID] = callback
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int InitEngine(lua_State* L)
|
int InitEngine(lua_State* L)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1389,10 +1307,243 @@ int InitEngine(lua_State* L)
|
||||||
reg_in_lua(L, Chunk::create, "Chunk");
|
reg_in_lua(L, Chunk::create, "Chunk");
|
||||||
reg_in_lua(L, Music::create, "Music");
|
reg_in_lua(L, Music::create, "Music");
|
||||||
reg_in_lua(L, MusicPlayer::create, "MusicPlayer");
|
reg_in_lua(L, MusicPlayer::create, "MusicPlayer");
|
||||||
reg_in_lua(L, ConvertMusicAsync, "ConvertMusic");
|
|
||||||
|
|
||||||
|
// Global functions
|
||||||
|
reg_in_lua(L, ConvertMusicAsync, "ConvertMusic");
|
||||||
|
reg_in_lua(L, setTimeout, "SetTimeout");
|
||||||
|
reg_in_lua(L, setInterval, "SetInterval");
|
||||||
|
|
||||||
|
// Global Library
|
||||||
LibFS::create(L); lua_setglobal(L, "fs");
|
LibFS::create(L); lua_setglobal(L, "fs");
|
||||||
|
|
||||||
|
// Registry table
|
||||||
|
lua_pushlightuserdata(L, &StartEngine);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_settable(L, LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaRunCallback(lua_State* L, int nargs, int nresults = LUA_MULTRET)
|
||||||
|
{
|
||||||
|
int ret = lua_pcall(L, nargs, nresults, 0);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
switch (ret)
|
||||||
|
{
|
||||||
|
case LUA_ERRRUN:
|
||||||
|
cout << "LuaRunError: " << lua_tostring(L, -1) << endl;
|
||||||
|
break;
|
||||||
|
case LUA_ERRMEM:
|
||||||
|
cout << "LuaMemError: " << lua_tostring(L, -1) << endl;
|
||||||
|
break;
|
||||||
|
case LUA_ERRERR:
|
||||||
|
cout << "LuaRecursiveError: " << lua_tostring(L, -1) << endl;
|
||||||
|
break;
|
||||||
|
case LUA_ERRGCMM:
|
||||||
|
cout << "LuaGCError: " << lua_tostring(L, -1) << endl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cout << "LuaError: " << lua_tostring(L, -1) << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StartEngine(lua_State* L)
|
||||||
|
{
|
||||||
|
// The Event Loop
|
||||||
|
bool running = true;
|
||||||
|
|
||||||
|
SDL_Event e;
|
||||||
|
while (running && SDL_WaitEvent(&e))
|
||||||
|
{
|
||||||
|
switch (e.type)
|
||||||
|
{
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
{
|
||||||
|
lua_pushlightuserdata(L, SDL_GetWindowFromID(e.button.windowID));
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
if (lua_getfield(L, -1, "onmousedown") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, e.button.x);
|
||||||
|
lua_pushnumber(L, e.button.y);
|
||||||
|
lua_pushnumber(L, e.button.button);
|
||||||
|
const char* arr[8];
|
||||||
|
int ret = GetMouseState(arr, e.button.state);
|
||||||
|
lua_newtable(L);
|
||||||
|
for (int i = 0; i < ret; i++)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, 1);
|
||||||
|
lua_setfield(L, -2, arr[i]);
|
||||||
|
}
|
||||||
|
LuaRunCallback(L, 4);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_MOUSEBUTTONUP:
|
||||||
|
{
|
||||||
|
lua_pushlightuserdata(L, SDL_GetWindowFromID(e.button.windowID));
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
if (lua_getfield(L, -1, "onmouseup") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, e.button.x);
|
||||||
|
lua_pushnumber(L, e.button.y);
|
||||||
|
lua_pushnumber(L, e.button.button);
|
||||||
|
const char* arr[8];
|
||||||
|
int ret = GetMouseState(arr, e.button.state);
|
||||||
|
lua_newtable(L);
|
||||||
|
for (int i = 0; i < ret; i++)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, 1);
|
||||||
|
lua_setfield(L, -2, arr[i]);
|
||||||
|
}
|
||||||
|
LuaRunCallback(L, 4);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_MOUSEMOTION:
|
||||||
|
{
|
||||||
|
lua_pushlightuserdata(L, SDL_GetWindowFromID(e.motion.windowID));
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
if (lua_getfield(L, -1, "onmousemove") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, e.motion.x);
|
||||||
|
lua_pushnumber(L, e.motion.y);
|
||||||
|
lua_pushnumber(L, e.motion.xrel);
|
||||||
|
lua_pushnumber(L, e.motion.yrel);
|
||||||
|
const char* arr[8];
|
||||||
|
int ret = GetMouseState(arr, e.button.state);
|
||||||
|
lua_newtable(L);
|
||||||
|
for (int i = 0; i < ret; i++)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, 1);
|
||||||
|
lua_setfield(L, -2, arr[i]);
|
||||||
|
}
|
||||||
|
LuaRunCallback(L, 5);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_QUIT:
|
||||||
|
{
|
||||||
|
running = 0;
|
||||||
|
|
||||||
|
lua_pushlightuserdata(L, &StartEngine);
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
|
||||||
|
if (lua_getfield(L, -1, "onquit") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
if (!LuaRunCallback(L, 0, 1))
|
||||||
|
{
|
||||||
|
if (lua_type(L, -1) == LUA_TBOOLEAN && !lua_toboolean(L, -1))
|
||||||
|
{
|
||||||
|
running = 1;
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
{
|
||||||
|
lua_pushlightuserdata(L, SDL_GetWindowFromID(e.key.windowID));
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
if (lua_getfield(L, -1, "onkeydown") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, e.key.keysym.sym);
|
||||||
|
LuaRunCallback(L, 1);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_KEYUP:
|
||||||
|
{
|
||||||
|
lua_pushlightuserdata(L, SDL_GetWindowFromID(e.key.windowID));
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
if (lua_getfield(L, -1, "onkeyup") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pushnumber(L, e.key.keysym.sym);
|
||||||
|
LuaRunCallback(L, 1);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SDL_USEREVENT:
|
||||||
|
{
|
||||||
|
switch (e.user.code)
|
||||||
|
{
|
||||||
|
case 1001:
|
||||||
|
{
|
||||||
|
// 定时器回调
|
||||||
|
LuaTimerCallbackData* pd = (LuaTimerCallbackData*)e.user.data1;
|
||||||
|
lua_pushlightuserdata(L, &setTimeout);
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX); // registry[&setTimeout]
|
||||||
|
lua_geti(L, -1, pd->id); // registry[&setTimeout][timerID]
|
||||||
|
delete pd;
|
||||||
|
LuaRunCallback(L, 0);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1002:
|
||||||
|
{
|
||||||
|
// 全局回调, 异步操作无返回值
|
||||||
|
lua_pushfstring(L, "cb%d", *(int*)e.user.data1);
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
delete e.user.data1;
|
||||||
|
LuaRunCallback(L, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1003:
|
||||||
|
|
||||||
|
// 音乐播放完毕
|
||||||
|
lua_pushlightuserdata(L, &StartEngine);
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
if (lua_getfield(L, -1, "onmusicover") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
LuaRunCallback(L, 0);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1004:
|
||||||
|
{
|
||||||
|
// 频道播放完毕
|
||||||
|
lua_pushlightuserdata(L, &StartEngine);
|
||||||
|
lua_gettable(L, LUA_REGISTRYINDEX);
|
||||||
|
if (lua_getfield(L, -1, "onchannelover") != LUA_TNIL)
|
||||||
|
{
|
||||||
|
lua_pushinteger(L, *(int*)e.user.data1);
|
||||||
|
delete e.user.data1;
|
||||||
|
LuaRunCallback(L, 1);
|
||||||
|
}
|
||||||
|
else lua_pop(L, 1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
cout << e.type << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,4 +3,5 @@
|
||||||
|
|
||||||
|
|
||||||
int InitEngine(lua_State* L);
|
int InitEngine(lua_State* L);
|
||||||
|
int StartEngine(lua_State* L);
|
||||||
int StopEngine();
|
int StopEngine();
|
||||||
|
|
|
@ -9,10 +9,11 @@ int main()
|
||||||
LuaVM L;
|
LuaVM L;
|
||||||
InitEngine(L);
|
InitEngine(L);
|
||||||
cout << "<ENGINE> Started." << endl;
|
cout << "<ENGINE> Started." << endl;
|
||||||
if (luaL_dofile(L, "code/game.lua"))
|
if (luaL_dofile(L, "code/init.lua"))
|
||||||
{
|
{
|
||||||
cout << lua_tostring(L, -1) << endl;
|
cout << lua_tostring(L, -1) << endl;
|
||||||
}
|
}
|
||||||
|
StartEngine(L);
|
||||||
cout << "<ENGINE> Stopped." << endl;
|
cout << "<ENGINE> Stopped." << endl;
|
||||||
} while (0);
|
} while (0);
|
||||||
StopEngine();
|
StopEngine();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user