Trival build
This commit is contained in:
parent
ec0a6f9f6a
commit
a516ae15ec
119
LuaChannel.cpp
Normal file
119
LuaChannel.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
#include "LuaChannel.h"
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <chrono>
|
||||
using namespace std;
|
||||
|
||||
class Channel
|
||||
{
|
||||
public:
|
||||
queue<string> bus;
|
||||
mutex mLock;
|
||||
condition_variable cond;
|
||||
};
|
||||
|
||||
map<int, Channel> gChannels;
|
||||
mutex gChannelLock;
|
||||
|
||||
|
||||
void ChannelSend(Channel& c, const string& data)
|
||||
{
|
||||
unique_lock<mutex> ulk(c.mLock);
|
||||
c.bus.push(data);
|
||||
}
|
||||
|
||||
int ChannelRead(Channel& c, string& out_data, int timeout=-1)
|
||||
{
|
||||
unique_lock<mutex> ulk(c.mLock);
|
||||
if (c.bus.empty())
|
||||
{
|
||||
if (timeout > 0)
|
||||
{
|
||||
if (cv_status::timeout == c.cond.wait_for(ulk, chrono::seconds(timeout)))
|
||||
{
|
||||
return 0; // timed out.
|
||||
}
|
||||
out_data = c.bus.front();
|
||||
c.bus.pop();
|
||||
return 1;
|
||||
}
|
||||
else if(timeout == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
c.cond.wait(ulk);
|
||||
out_data = c.bus.front();
|
||||
c.bus.pop();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out_data = c.bus.front();
|
||||
c.bus.pop();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
Channel& AcquireChannel(int channelID)
|
||||
{
|
||||
unique_lock<mutex> ulk(gChannelLock);
|
||||
return gChannels[channelID];
|
||||
}
|
||||
|
||||
int InitChannel(lua_State* L)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
class VMInfo
|
||||
{
|
||||
public:
|
||||
unique_ptr<thread> ptd;
|
||||
unique_ptr<LuaVM> pvm;
|
||||
int wait_join;
|
||||
|
||||
VMInfo() : wait_join(0), pvm(new LuaVM)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~VMInfo()
|
||||
{
|
||||
if (ptd.get() && ptd.get()->joinable())
|
||||
{
|
||||
if (wait_join)
|
||||
{
|
||||
ptd.get()->join();
|
||||
}
|
||||
else
|
||||
{
|
||||
pvm.release();
|
||||
ptd.get()->detach();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void VMRunner(VMInfo& vm, string code)
|
||||
{
|
||||
|
||||
if (!vm.wait_join)
|
||||
{
|
||||
vm.pvm.reset();
|
||||
}
|
||||
}
|
||||
|
||||
int CreateVM(lua_State* L)
|
||||
{
|
||||
VMInfo* vm = new (lua_newuserdata(L, sizeof(VMInfo))) VMInfo;
|
||||
string code(lua_tostring(L, 1));
|
||||
vm->ptd.reset(new thread(VMRunner, *vm, code));
|
||||
return 1;
|
||||
}
|
5
LuaChannel.h
Normal file
5
LuaChannel.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
#include "LuaVM.h"
|
||||
|
||||
int InitChannel(lua_State* L);
|
||||
int CreateVM(lua_State* L); // -1 +1
|
57
LuaCommon.cpp
Normal file
57
LuaCommon.cpp
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "LuaCommon.h"
|
||||
using namespace std;
|
||||
|
||||
bool LuaCompareType(lua_State* L, int index, const char* type, bool leave)
|
||||
{
|
||||
int indexType = lua_getfield(L, index, "type");
|
||||
if (indexType == LUA_TSTRING)
|
||||
{
|
||||
if (strcmp(lua_tostring(L, -1), type) == 0)
|
||||
{
|
||||
if (!leave) lua_pop(L, 1);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!leave) lua_pop(L, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
if (leave) lua_pushstring(L, lua_typename(L, indexType));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void check(lua_State* L, const vector<int>& typearr, const vector<const char*>& userdata_type)
|
||||
{
|
||||
int sz = typearr.size();
|
||||
int nextIndex = 0;
|
||||
int maxIndex = userdata_type.size();
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
6
LuaCommon.h
Normal file
6
LuaCommon.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
#include "LuaVM.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*>());
|
|
@ -9,65 +9,14 @@
|
|||
#include "SDL2/include/SDL_ttf.h"
|
||||
#include "SDL2/include/SDL_image.h"
|
||||
#include "PlatAPI.h"
|
||||
#include "LuaEnum.h"
|
||||
#include "LuaCommon.h"
|
||||
#include "LuaNetwork.h"
|
||||
using namespace std;
|
||||
|
||||
// Global single-thread unprotected event callback id counter
|
||||
int callback_counter = 1;
|
||||
|
||||
bool LuaCompareType(lua_State* L, int index, const char* type, bool leave=false)
|
||||
{
|
||||
int indexType = lua_getfield(L, index, "type");
|
||||
if (indexType == LUA_TSTRING)
|
||||
{
|
||||
if (strcmp(lua_tostring(L, -1), type) == 0)
|
||||
{
|
||||
if(!leave) lua_pop(L, 1);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!leave) lua_pop(L, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
if (leave) lua_pushstring(L, lua_typename(L, indexType));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void check(lua_State* L, const vector<int>& typearr, const vector<const char*>& userdata_type=vector<const char*>())
|
||||
{
|
||||
int sz = typearr.size();
|
||||
int nextIndex = 0;
|
||||
int maxIndex = userdata_type.size();
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
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));
|
||||
}
|
||||
nextIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
luaL_error(L, "Not enough userdata type string.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
@ -1269,7 +1218,6 @@ struct LibFS
|
|||
}
|
||||
};
|
||||
|
||||
#define reg_in_lua(L, cfunc, name) lua_pushcfunction(L, cfunc); lua_setglobal(L, name)
|
||||
|
||||
void check_init(lua_State* L, const char* name, int ret, int expected = 0)
|
||||
{
|
||||
|
@ -1354,6 +1302,17 @@ static int setInterval(lua_State* L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int evFireExit(lua_State* L)
|
||||
{
|
||||
SDL_Event e;
|
||||
e.type = SDL_QUIT;
|
||||
e.quit.timestamp = SDL_GetTicks();
|
||||
SDL_PushEvent(&e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define reg_in_lua(L, cfunc, name) lua_pushcfunction(L, cfunc); lua_setglobal(L, name)
|
||||
|
||||
int InitEngine(lua_State* L)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1383,9 +1342,13 @@ int InitEngine(lua_State* L)
|
|||
reg_in_lua(L, ConvertMusicAsync, "ConvertMusic");
|
||||
reg_in_lua(L, setTimeout, "SetTimeout");
|
||||
reg_in_lua(L, setInterval, "SetInterval");
|
||||
reg_in_lua(L, evFireExit, "FireExit");
|
||||
|
||||
// Global Library
|
||||
LibFS::create(L); lua_setglobal(L, "fs");
|
||||
InitEnum(L);
|
||||
InitNetwork(L);
|
||||
|
||||
|
||||
// Registry table
|
||||
lua_pushlightuserdata(L, &StartEngine);
|
||||
|
@ -1641,11 +1604,17 @@ int StartEngine(lua_State* L)
|
|||
lua_pop(L, 1);
|
||||
break;
|
||||
}
|
||||
case 1005:
|
||||
case 1006:
|
||||
{
|
||||
HandleNetworkEvent(L, e);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
cout << e.type << endl;
|
||||
cout << "Unhandled Event: 0x" << hex << e.type << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
507
LuaEnum.cpp
Normal file
507
LuaEnum.cpp
Normal file
|
@ -0,0 +1,507 @@
|
|||
#include "LuaEnum.h"
|
||||
#include "SDL2/include/SDL.h"
|
||||
#include "SDL2/include/SDL_mixer.h"
|
||||
#include "SDL2/include/SDL_ttf.h"
|
||||
#include "SDL2/include/SDL_image.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define addkey(key, name) lua_pushinteger(L, key);lua_setfield(L, -2, name)
|
||||
|
||||
|
||||
/*
|
||||
Key code generated with Python script:
|
||||
```python
|
||||
lst = filter(lambda x: True if x else False, content.replace('\r', '').split('\n'))
|
||||
|
||||
x = set()
|
||||
|
||||
for line in lst:
|
||||
keyname = line.split('=')[0].strip()
|
||||
Lkeyname = keyname.replace('SDLK_', '').lower()
|
||||
Gkeyname = keyname.replace('SDLK_', '').upper()
|
||||
if Lkeyname not in x:
|
||||
print "addkey({}, \"{}\");".format(keyname, Lkeyname)
|
||||
x.add(Lkeyname)
|
||||
if Gkeyname not in x:
|
||||
print "addkey({}, \"{}\");".format(keyname, Gkeyname)
|
||||
x.add(Gkeyname)
|
||||
```
|
||||
*/
|
||||
|
||||
int InitEnum(lua_State* L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
addkey(SDLK_UNKNOWN, "unknown");
|
||||
addkey(SDLK_UNKNOWN, "UNKNOWN");
|
||||
addkey(SDLK_RETURN, "return");
|
||||
addkey(SDLK_RETURN, "RETURN");
|
||||
addkey(SDLK_ESCAPE, "escape");
|
||||
addkey(SDLK_ESCAPE, "ESCAPE");
|
||||
addkey(SDLK_BACKSPACE, "backspace");
|
||||
addkey(SDLK_BACKSPACE, "BACKSPACE");
|
||||
addkey(SDLK_TAB, "tab");
|
||||
addkey(SDLK_TAB, "TAB");
|
||||
addkey(SDLK_SPACE, "space");
|
||||
addkey(SDLK_SPACE, "SPACE");
|
||||
addkey(SDLK_EXCLAIM, "exclaim");
|
||||
addkey(SDLK_EXCLAIM, "EXCLAIM");
|
||||
addkey(SDLK_QUOTEDBL, "quotedbl");
|
||||
addkey(SDLK_QUOTEDBL, "QUOTEDBL");
|
||||
addkey(SDLK_HASH, "hash");
|
||||
addkey(SDLK_HASH, "HASH");
|
||||
addkey(SDLK_PERCENT, "percent");
|
||||
addkey(SDLK_PERCENT, "PERCENT");
|
||||
addkey(SDLK_DOLLAR, "dollar");
|
||||
addkey(SDLK_DOLLAR, "DOLLAR");
|
||||
addkey(SDLK_AMPERSAND, "ampersand");
|
||||
addkey(SDLK_AMPERSAND, "AMPERSAND");
|
||||
addkey(SDLK_QUOTE, "quote");
|
||||
addkey(SDLK_QUOTE, "QUOTE");
|
||||
addkey(SDLK_LEFTPAREN, "leftparen");
|
||||
addkey(SDLK_LEFTPAREN, "LEFTPAREN");
|
||||
addkey(SDLK_RIGHTPAREN, "rightparen");
|
||||
addkey(SDLK_RIGHTPAREN, "RIGHTPAREN");
|
||||
addkey(SDLK_ASTERISK, "asterisk");
|
||||
addkey(SDLK_ASTERISK, "ASTERISK");
|
||||
addkey(SDLK_PLUS, "plus");
|
||||
addkey(SDLK_PLUS, "PLUS");
|
||||
addkey(SDLK_COMMA, "comma");
|
||||
addkey(SDLK_COMMA, "COMMA");
|
||||
addkey(SDLK_MINUS, "minus");
|
||||
addkey(SDLK_MINUS, "MINUS");
|
||||
addkey(SDLK_PERIOD, "period");
|
||||
addkey(SDLK_PERIOD, "PERIOD");
|
||||
addkey(SDLK_SLASH, "slash");
|
||||
addkey(SDLK_SLASH, "SLASH");
|
||||
addkey(SDLK_0, "0");
|
||||
addkey(SDLK_1, "1");
|
||||
addkey(SDLK_2, "2");
|
||||
addkey(SDLK_3, "3");
|
||||
addkey(SDLK_4, "4");
|
||||
addkey(SDLK_5, "5");
|
||||
addkey(SDLK_6, "6");
|
||||
addkey(SDLK_7, "7");
|
||||
addkey(SDLK_8, "8");
|
||||
addkey(SDLK_9, "9");
|
||||
addkey(SDLK_COLON, "colon");
|
||||
addkey(SDLK_COLON, "COLON");
|
||||
addkey(SDLK_SEMICOLON, "semicolon");
|
||||
addkey(SDLK_SEMICOLON, "SEMICOLON");
|
||||
addkey(SDLK_LESS, "less");
|
||||
addkey(SDLK_LESS, "LESS");
|
||||
addkey(SDLK_EQUALS, "equals");
|
||||
addkey(SDLK_EQUALS, "EQUALS");
|
||||
addkey(SDLK_GREATER, "greater");
|
||||
addkey(SDLK_GREATER, "GREATER");
|
||||
addkey(SDLK_QUESTION, "question");
|
||||
addkey(SDLK_QUESTION, "QUESTION");
|
||||
addkey(SDLK_AT, "at");
|
||||
addkey(SDLK_AT, "AT");
|
||||
addkey(SDLK_LEFTBRACKET, "leftbracket");
|
||||
addkey(SDLK_LEFTBRACKET, "LEFTBRACKET");
|
||||
addkey(SDLK_BACKSLASH, "backslash");
|
||||
addkey(SDLK_BACKSLASH, "BACKSLASH");
|
||||
addkey(SDLK_RIGHTBRACKET, "rightbracket");
|
||||
addkey(SDLK_RIGHTBRACKET, "RIGHTBRACKET");
|
||||
addkey(SDLK_CARET, "caret");
|
||||
addkey(SDLK_CARET, "CARET");
|
||||
addkey(SDLK_UNDERSCORE, "underscore");
|
||||
addkey(SDLK_UNDERSCORE, "UNDERSCORE");
|
||||
addkey(SDLK_BACKQUOTE, "backquote");
|
||||
addkey(SDLK_BACKQUOTE, "BACKQUOTE");
|
||||
addkey(SDLK_a, "a");
|
||||
addkey(SDLK_a, "A");
|
||||
addkey(SDLK_b, "b");
|
||||
addkey(SDLK_b, "B");
|
||||
addkey(SDLK_c, "c");
|
||||
addkey(SDLK_c, "C");
|
||||
addkey(SDLK_d, "d");
|
||||
addkey(SDLK_d, "D");
|
||||
addkey(SDLK_e, "e");
|
||||
addkey(SDLK_e, "E");
|
||||
addkey(SDLK_f, "f");
|
||||
addkey(SDLK_f, "F");
|
||||
addkey(SDLK_g, "g");
|
||||
addkey(SDLK_g, "G");
|
||||
addkey(SDLK_h, "h");
|
||||
addkey(SDLK_h, "H");
|
||||
addkey(SDLK_i, "i");
|
||||
addkey(SDLK_i, "I");
|
||||
addkey(SDLK_j, "j");
|
||||
addkey(SDLK_j, "J");
|
||||
addkey(SDLK_k, "k");
|
||||
addkey(SDLK_k, "K");
|
||||
addkey(SDLK_l, "l");
|
||||
addkey(SDLK_l, "L");
|
||||
addkey(SDLK_m, "m");
|
||||
addkey(SDLK_m, "M");
|
||||
addkey(SDLK_n, "n");
|
||||
addkey(SDLK_n, "N");
|
||||
addkey(SDLK_o, "o");
|
||||
addkey(SDLK_o, "O");
|
||||
addkey(SDLK_p, "p");
|
||||
addkey(SDLK_p, "P");
|
||||
addkey(SDLK_q, "q");
|
||||
addkey(SDLK_q, "Q");
|
||||
addkey(SDLK_r, "r");
|
||||
addkey(SDLK_r, "R");
|
||||
addkey(SDLK_s, "s");
|
||||
addkey(SDLK_s, "S");
|
||||
addkey(SDLK_t, "t");
|
||||
addkey(SDLK_t, "T");
|
||||
addkey(SDLK_u, "u");
|
||||
addkey(SDLK_u, "U");
|
||||
addkey(SDLK_v, "v");
|
||||
addkey(SDLK_v, "V");
|
||||
addkey(SDLK_w, "w");
|
||||
addkey(SDLK_w, "W");
|
||||
addkey(SDLK_x, "x");
|
||||
addkey(SDLK_x, "X");
|
||||
addkey(SDLK_y, "y");
|
||||
addkey(SDLK_y, "Y");
|
||||
addkey(SDLK_z, "z");
|
||||
addkey(SDLK_z, "Z");
|
||||
addkey(SDLK_CAPSLOCK, "capslock");
|
||||
addkey(SDLK_CAPSLOCK, "CAPSLOCK");
|
||||
addkey(SDLK_F1, "f1");
|
||||
addkey(SDLK_F1, "F1");
|
||||
addkey(SDLK_F2, "f2");
|
||||
addkey(SDLK_F2, "F2");
|
||||
addkey(SDLK_F3, "f3");
|
||||
addkey(SDLK_F3, "F3");
|
||||
addkey(SDLK_F4, "f4");
|
||||
addkey(SDLK_F4, "F4");
|
||||
addkey(SDLK_F5, "f5");
|
||||
addkey(SDLK_F5, "F5");
|
||||
addkey(SDLK_F6, "f6");
|
||||
addkey(SDLK_F6, "F6");
|
||||
addkey(SDLK_F7, "f7");
|
||||
addkey(SDLK_F7, "F7");
|
||||
addkey(SDLK_F8, "f8");
|
||||
addkey(SDLK_F8, "F8");
|
||||
addkey(SDLK_F9, "f9");
|
||||
addkey(SDLK_F9, "F9");
|
||||
addkey(SDLK_F10, "f10");
|
||||
addkey(SDLK_F10, "F10");
|
||||
addkey(SDLK_F11, "f11");
|
||||
addkey(SDLK_F11, "F11");
|
||||
addkey(SDLK_F12, "f12");
|
||||
addkey(SDLK_F12, "F12");
|
||||
addkey(SDLK_PRINTSCREEN, "printscreen");
|
||||
addkey(SDLK_PRINTSCREEN, "PRINTSCREEN");
|
||||
addkey(SDLK_SCROLLLOCK, "scrolllock");
|
||||
addkey(SDLK_SCROLLLOCK, "SCROLLLOCK");
|
||||
addkey(SDLK_PAUSE, "pause");
|
||||
addkey(SDLK_PAUSE, "PAUSE");
|
||||
addkey(SDLK_INSERT, "insert");
|
||||
addkey(SDLK_INSERT, "INSERT");
|
||||
addkey(SDLK_HOME, "home");
|
||||
addkey(SDLK_HOME, "HOME");
|
||||
addkey(SDLK_PAGEUP, "pageup");
|
||||
addkey(SDLK_PAGEUP, "PAGEUP");
|
||||
addkey(SDLK_DELETE, "delete");
|
||||
addkey(SDLK_DELETE, "DELETE");
|
||||
addkey(SDLK_END, "end");
|
||||
addkey(SDLK_END, "END");
|
||||
addkey(SDLK_PAGEDOWN, "pagedown");
|
||||
addkey(SDLK_PAGEDOWN, "PAGEDOWN");
|
||||
addkey(SDLK_RIGHT, "right");
|
||||
addkey(SDLK_RIGHT, "RIGHT");
|
||||
addkey(SDLK_LEFT, "left");
|
||||
addkey(SDLK_LEFT, "LEFT");
|
||||
addkey(SDLK_DOWN, "down");
|
||||
addkey(SDLK_DOWN, "DOWN");
|
||||
addkey(SDLK_UP, "up");
|
||||
addkey(SDLK_UP, "UP");
|
||||
addkey(SDLK_NUMLOCKCLEAR, "numlockclear");
|
||||
addkey(SDLK_NUMLOCKCLEAR, "NUMLOCKCLEAR");
|
||||
addkey(SDLK_KP_DIVIDE, "kp_divide");
|
||||
addkey(SDLK_KP_DIVIDE, "KP_DIVIDE");
|
||||
addkey(SDLK_KP_MULTIPLY, "kp_multiply");
|
||||
addkey(SDLK_KP_MULTIPLY, "KP_MULTIPLY");
|
||||
addkey(SDLK_KP_MINUS, "kp_minus");
|
||||
addkey(SDLK_KP_MINUS, "KP_MINUS");
|
||||
addkey(SDLK_KP_PLUS, "kp_plus");
|
||||
addkey(SDLK_KP_PLUS, "KP_PLUS");
|
||||
addkey(SDLK_KP_ENTER, "kp_enter");
|
||||
addkey(SDLK_KP_ENTER, "KP_ENTER");
|
||||
addkey(SDLK_KP_1, "kp_1");
|
||||
addkey(SDLK_KP_1, "KP_1");
|
||||
addkey(SDLK_KP_2, "kp_2");
|
||||
addkey(SDLK_KP_2, "KP_2");
|
||||
addkey(SDLK_KP_3, "kp_3");
|
||||
addkey(SDLK_KP_3, "KP_3");
|
||||
addkey(SDLK_KP_4, "kp_4");
|
||||
addkey(SDLK_KP_4, "KP_4");
|
||||
addkey(SDLK_KP_5, "kp_5");
|
||||
addkey(SDLK_KP_5, "KP_5");
|
||||
addkey(SDLK_KP_6, "kp_6");
|
||||
addkey(SDLK_KP_6, "KP_6");
|
||||
addkey(SDLK_KP_7, "kp_7");
|
||||
addkey(SDLK_KP_7, "KP_7");
|
||||
addkey(SDLK_KP_8, "kp_8");
|
||||
addkey(SDLK_KP_8, "KP_8");
|
||||
addkey(SDLK_KP_9, "kp_9");
|
||||
addkey(SDLK_KP_9, "KP_9");
|
||||
addkey(SDLK_KP_0, "kp_0");
|
||||
addkey(SDLK_KP_0, "KP_0");
|
||||
addkey(SDLK_KP_PERIOD, "kp_period");
|
||||
addkey(SDLK_KP_PERIOD, "KP_PERIOD");
|
||||
addkey(SDLK_APPLICATION, "application");
|
||||
addkey(SDLK_APPLICATION, "APPLICATION");
|
||||
addkey(SDLK_POWER, "power");
|
||||
addkey(SDLK_POWER, "POWER");
|
||||
addkey(SDLK_KP_EQUALS, "kp_equals");
|
||||
addkey(SDLK_KP_EQUALS, "KP_EQUALS");
|
||||
addkey(SDLK_F13, "f13");
|
||||
addkey(SDLK_F13, "F13");
|
||||
addkey(SDLK_F14, "f14");
|
||||
addkey(SDLK_F14, "F14");
|
||||
addkey(SDLK_F15, "f15");
|
||||
addkey(SDLK_F15, "F15");
|
||||
addkey(SDLK_F16, "f16");
|
||||
addkey(SDLK_F16, "F16");
|
||||
addkey(SDLK_F17, "f17");
|
||||
addkey(SDLK_F17, "F17");
|
||||
addkey(SDLK_F18, "f18");
|
||||
addkey(SDLK_F18, "F18");
|
||||
addkey(SDLK_F19, "f19");
|
||||
addkey(SDLK_F19, "F19");
|
||||
addkey(SDLK_F20, "f20");
|
||||
addkey(SDLK_F20, "F20");
|
||||
addkey(SDLK_F21, "f21");
|
||||
addkey(SDLK_F21, "F21");
|
||||
addkey(SDLK_F22, "f22");
|
||||
addkey(SDLK_F22, "F22");
|
||||
addkey(SDLK_F23, "f23");
|
||||
addkey(SDLK_F23, "F23");
|
||||
addkey(SDLK_F24, "f24");
|
||||
addkey(SDLK_F24, "F24");
|
||||
addkey(SDLK_EXECUTE, "execute");
|
||||
addkey(SDLK_EXECUTE, "EXECUTE");
|
||||
addkey(SDLK_HELP, "help");
|
||||
addkey(SDLK_HELP, "HELP");
|
||||
addkey(SDLK_MENU, "menu");
|
||||
addkey(SDLK_MENU, "MENU");
|
||||
addkey(SDLK_SELECT, "select");
|
||||
addkey(SDLK_SELECT, "SELECT");
|
||||
addkey(SDLK_STOP, "stop");
|
||||
addkey(SDLK_STOP, "STOP");
|
||||
addkey(SDLK_AGAIN, "again");
|
||||
addkey(SDLK_AGAIN, "AGAIN");
|
||||
addkey(SDLK_UNDO, "undo");
|
||||
addkey(SDLK_UNDO, "UNDO");
|
||||
addkey(SDLK_CUT, "cut");
|
||||
addkey(SDLK_CUT, "CUT");
|
||||
addkey(SDLK_COPY, "copy");
|
||||
addkey(SDLK_COPY, "COPY");
|
||||
addkey(SDLK_PASTE, "paste");
|
||||
addkey(SDLK_PASTE, "PASTE");
|
||||
addkey(SDLK_FIND, "find");
|
||||
addkey(SDLK_FIND, "FIND");
|
||||
addkey(SDLK_MUTE, "mute");
|
||||
addkey(SDLK_MUTE, "MUTE");
|
||||
addkey(SDLK_VOLUMEUP, "volumeup");
|
||||
addkey(SDLK_VOLUMEUP, "VOLUMEUP");
|
||||
addkey(SDLK_VOLUMEDOWN, "volumedown");
|
||||
addkey(SDLK_VOLUMEDOWN, "VOLUMEDOWN");
|
||||
addkey(SDLK_KP_COMMA, "kp_comma");
|
||||
addkey(SDLK_KP_COMMA, "KP_COMMA");
|
||||
addkey(SDLK_KP_EQUALSAS400, "kp_equalsas400");
|
||||
addkey(SDLK_KP_EQUALSAS400, "KP_EQUALSAS400");
|
||||
addkey(SDLK_ALTERASE, "alterase");
|
||||
addkey(SDLK_ALTERASE, "ALTERASE");
|
||||
addkey(SDLK_SYSREQ, "sysreq");
|
||||
addkey(SDLK_SYSREQ, "SYSREQ");
|
||||
addkey(SDLK_CANCEL, "cancel");
|
||||
addkey(SDLK_CANCEL, "CANCEL");
|
||||
addkey(SDLK_CLEAR, "clear");
|
||||
addkey(SDLK_CLEAR, "CLEAR");
|
||||
addkey(SDLK_PRIOR, "prior");
|
||||
addkey(SDLK_PRIOR, "PRIOR");
|
||||
addkey(SDLK_RETURN2, "return2");
|
||||
addkey(SDLK_RETURN2, "RETURN2");
|
||||
addkey(SDLK_SEPARATOR, "separator");
|
||||
addkey(SDLK_SEPARATOR, "SEPARATOR");
|
||||
addkey(SDLK_OUT, "out");
|
||||
addkey(SDLK_OUT, "OUT");
|
||||
addkey(SDLK_OPER, "oper");
|
||||
addkey(SDLK_OPER, "OPER");
|
||||
addkey(SDLK_CLEARAGAIN, "clearagain");
|
||||
addkey(SDLK_CLEARAGAIN, "CLEARAGAIN");
|
||||
addkey(SDLK_CRSEL, "crsel");
|
||||
addkey(SDLK_CRSEL, "CRSEL");
|
||||
addkey(SDLK_EXSEL, "exsel");
|
||||
addkey(SDLK_EXSEL, "EXSEL");
|
||||
addkey(SDLK_KP_00, "kp_00");
|
||||
addkey(SDLK_KP_00, "KP_00");
|
||||
addkey(SDLK_KP_000, "kp_000");
|
||||
addkey(SDLK_KP_000, "KP_000");
|
||||
addkey(SDLK_THOUSANDSSEPARATOR, "thousandsseparator");
|
||||
addkey(SDLK_THOUSANDSSEPARATOR, "THOUSANDSSEPARATOR");
|
||||
addkey(SDLK_DECIMALSEPARATOR, "decimalseparator");
|
||||
addkey(SDLK_DECIMALSEPARATOR, "DECIMALSEPARATOR");
|
||||
addkey(SDLK_CURRENCYUNIT, "currencyunit");
|
||||
addkey(SDLK_CURRENCYUNIT, "CURRENCYUNIT");
|
||||
addkey(SDLK_CURRENCYSUBUNIT, "currencysubunit");
|
||||
addkey(SDLK_CURRENCYSUBUNIT, "CURRENCYSUBUNIT");
|
||||
addkey(SDLK_KP_LEFTPAREN, "kp_leftparen");
|
||||
addkey(SDLK_KP_LEFTPAREN, "KP_LEFTPAREN");
|
||||
addkey(SDLK_KP_RIGHTPAREN, "kp_rightparen");
|
||||
addkey(SDLK_KP_RIGHTPAREN, "KP_RIGHTPAREN");
|
||||
addkey(SDLK_KP_LEFTBRACE, "kp_leftbrace");
|
||||
addkey(SDLK_KP_LEFTBRACE, "KP_LEFTBRACE");
|
||||
addkey(SDLK_KP_RIGHTBRACE, "kp_rightbrace");
|
||||
addkey(SDLK_KP_RIGHTBRACE, "KP_RIGHTBRACE");
|
||||
addkey(SDLK_KP_TAB, "kp_tab");
|
||||
addkey(SDLK_KP_TAB, "KP_TAB");
|
||||
addkey(SDLK_KP_BACKSPACE, "kp_backspace");
|
||||
addkey(SDLK_KP_BACKSPACE, "KP_BACKSPACE");
|
||||
addkey(SDLK_KP_A, "kp_a");
|
||||
addkey(SDLK_KP_A, "KP_A");
|
||||
addkey(SDLK_KP_B, "kp_b");
|
||||
addkey(SDLK_KP_B, "KP_B");
|
||||
addkey(SDLK_KP_C, "kp_c");
|
||||
addkey(SDLK_KP_C, "KP_C");
|
||||
addkey(SDLK_KP_D, "kp_d");
|
||||
addkey(SDLK_KP_D, "KP_D");
|
||||
addkey(SDLK_KP_E, "kp_e");
|
||||
addkey(SDLK_KP_E, "KP_E");
|
||||
addkey(SDLK_KP_F, "kp_f");
|
||||
addkey(SDLK_KP_F, "KP_F");
|
||||
addkey(SDLK_KP_XOR, "kp_xor");
|
||||
addkey(SDLK_KP_XOR, "KP_XOR");
|
||||
addkey(SDLK_KP_POWER, "kp_power");
|
||||
addkey(SDLK_KP_POWER, "KP_POWER");
|
||||
addkey(SDLK_KP_PERCENT, "kp_percent");
|
||||
addkey(SDLK_KP_PERCENT, "KP_PERCENT");
|
||||
addkey(SDLK_KP_LESS, "kp_less");
|
||||
addkey(SDLK_KP_LESS, "KP_LESS");
|
||||
addkey(SDLK_KP_GREATER, "kp_greater");
|
||||
addkey(SDLK_KP_GREATER, "KP_GREATER");
|
||||
addkey(SDLK_KP_AMPERSAND, "kp_ampersand");
|
||||
addkey(SDLK_KP_AMPERSAND, "KP_AMPERSAND");
|
||||
addkey(SDLK_KP_DBLAMPERSAND, "kp_dblampersand");
|
||||
addkey(SDLK_KP_DBLAMPERSAND, "KP_DBLAMPERSAND");
|
||||
addkey(SDLK_KP_VERTICALBAR, "kp_verticalbar");
|
||||
addkey(SDLK_KP_VERTICALBAR, "KP_VERTICALBAR");
|
||||
addkey(SDLK_KP_DBLVERTICALBAR, "kp_dblverticalbar");
|
||||
addkey(SDLK_KP_DBLVERTICALBAR, "KP_DBLVERTICALBAR");
|
||||
addkey(SDLK_KP_COLON, "kp_colon");
|
||||
addkey(SDLK_KP_COLON, "KP_COLON");
|
||||
addkey(SDLK_KP_HASH, "kp_hash");
|
||||
addkey(SDLK_KP_HASH, "KP_HASH");
|
||||
addkey(SDLK_KP_SPACE, "kp_space");
|
||||
addkey(SDLK_KP_SPACE, "KP_SPACE");
|
||||
addkey(SDLK_KP_AT, "kp_at");
|
||||
addkey(SDLK_KP_AT, "KP_AT");
|
||||
addkey(SDLK_KP_EXCLAM, "kp_exclam");
|
||||
addkey(SDLK_KP_EXCLAM, "KP_EXCLAM");
|
||||
addkey(SDLK_KP_MEMSTORE, "kp_memstore");
|
||||
addkey(SDLK_KP_MEMSTORE, "KP_MEMSTORE");
|
||||
addkey(SDLK_KP_MEMRECALL, "kp_memrecall");
|
||||
addkey(SDLK_KP_MEMRECALL, "KP_MEMRECALL");
|
||||
addkey(SDLK_KP_MEMCLEAR, "kp_memclear");
|
||||
addkey(SDLK_KP_MEMCLEAR, "KP_MEMCLEAR");
|
||||
addkey(SDLK_KP_MEMADD, "kp_memadd");
|
||||
addkey(SDLK_KP_MEMADD, "KP_MEMADD");
|
||||
addkey(SDLK_KP_MEMSUBTRACT, "kp_memsubtract");
|
||||
addkey(SDLK_KP_MEMSUBTRACT, "KP_MEMSUBTRACT");
|
||||
addkey(SDLK_KP_MEMMULTIPLY, "kp_memmultiply");
|
||||
addkey(SDLK_KP_MEMMULTIPLY, "KP_MEMMULTIPLY");
|
||||
addkey(SDLK_KP_MEMDIVIDE, "kp_memdivide");
|
||||
addkey(SDLK_KP_MEMDIVIDE, "KP_MEMDIVIDE");
|
||||
addkey(SDLK_KP_PLUSMINUS, "kp_plusminus");
|
||||
addkey(SDLK_KP_PLUSMINUS, "KP_PLUSMINUS");
|
||||
addkey(SDLK_KP_CLEAR, "kp_clear");
|
||||
addkey(SDLK_KP_CLEAR, "KP_CLEAR");
|
||||
addkey(SDLK_KP_CLEARENTRY, "kp_clearentry");
|
||||
addkey(SDLK_KP_CLEARENTRY, "KP_CLEARENTRY");
|
||||
addkey(SDLK_KP_BINARY, "kp_binary");
|
||||
addkey(SDLK_KP_BINARY, "KP_BINARY");
|
||||
addkey(SDLK_KP_OCTAL, "kp_octal");
|
||||
addkey(SDLK_KP_OCTAL, "KP_OCTAL");
|
||||
addkey(SDLK_KP_DECIMAL, "kp_decimal");
|
||||
addkey(SDLK_KP_DECIMAL, "KP_DECIMAL");
|
||||
addkey(SDLK_KP_HEXADECIMAL, "kp_hexadecimal");
|
||||
addkey(SDLK_KP_HEXADECIMAL, "KP_HEXADECIMAL");
|
||||
addkey(SDLK_LCTRL, "lctrl");
|
||||
addkey(SDLK_LCTRL, "LCTRL");
|
||||
addkey(SDLK_LSHIFT, "lshift");
|
||||
addkey(SDLK_LSHIFT, "LSHIFT");
|
||||
addkey(SDLK_LALT, "lalt");
|
||||
addkey(SDLK_LALT, "LALT");
|
||||
addkey(SDLK_LGUI, "lgui");
|
||||
addkey(SDLK_LGUI, "LGUI");
|
||||
addkey(SDLK_RCTRL, "rctrl");
|
||||
addkey(SDLK_RCTRL, "RCTRL");
|
||||
addkey(SDLK_RSHIFT, "rshift");
|
||||
addkey(SDLK_RSHIFT, "RSHIFT");
|
||||
addkey(SDLK_RALT, "ralt");
|
||||
addkey(SDLK_RALT, "RALT");
|
||||
addkey(SDLK_RGUI, "rgui");
|
||||
addkey(SDLK_RGUI, "RGUI");
|
||||
addkey(SDLK_MODE, "mode");
|
||||
addkey(SDLK_MODE, "MODE");
|
||||
addkey(SDLK_AUDIONEXT, "audionext");
|
||||
addkey(SDLK_AUDIONEXT, "AUDIONEXT");
|
||||
addkey(SDLK_AUDIOPREV, "audioprev");
|
||||
addkey(SDLK_AUDIOPREV, "AUDIOPREV");
|
||||
addkey(SDLK_AUDIOSTOP, "audiostop");
|
||||
addkey(SDLK_AUDIOSTOP, "AUDIOSTOP");
|
||||
addkey(SDLK_AUDIOPLAY, "audioplay");
|
||||
addkey(SDLK_AUDIOPLAY, "AUDIOPLAY");
|
||||
addkey(SDLK_AUDIOMUTE, "audiomute");
|
||||
addkey(SDLK_AUDIOMUTE, "AUDIOMUTE");
|
||||
addkey(SDLK_MEDIASELECT, "mediaselect");
|
||||
addkey(SDLK_MEDIASELECT, "MEDIASELECT");
|
||||
addkey(SDLK_WWW, "www");
|
||||
addkey(SDLK_WWW, "WWW");
|
||||
addkey(SDLK_MAIL, "mail");
|
||||
addkey(SDLK_MAIL, "MAIL");
|
||||
addkey(SDLK_CALCULATOR, "calculator");
|
||||
addkey(SDLK_CALCULATOR, "CALCULATOR");
|
||||
addkey(SDLK_COMPUTER, "computer");
|
||||
addkey(SDLK_COMPUTER, "COMPUTER");
|
||||
addkey(SDLK_AC_SEARCH, "ac_search");
|
||||
addkey(SDLK_AC_SEARCH, "AC_SEARCH");
|
||||
addkey(SDLK_AC_HOME, "ac_home");
|
||||
addkey(SDLK_AC_HOME, "AC_HOME");
|
||||
addkey(SDLK_AC_BACK, "ac_back");
|
||||
addkey(SDLK_AC_BACK, "AC_BACK");
|
||||
addkey(SDLK_AC_FORWARD, "ac_forward");
|
||||
addkey(SDLK_AC_FORWARD, "AC_FORWARD");
|
||||
addkey(SDLK_AC_STOP, "ac_stop");
|
||||
addkey(SDLK_AC_STOP, "AC_STOP");
|
||||
addkey(SDLK_AC_REFRESH, "ac_refresh");
|
||||
addkey(SDLK_AC_REFRESH, "AC_REFRESH");
|
||||
addkey(SDLK_AC_BOOKMARKS, "ac_bookmarks");
|
||||
addkey(SDLK_AC_BOOKMARKS, "AC_BOOKMARKS");
|
||||
addkey(SDLK_BRIGHTNESSDOWN, "brightnessdown");
|
||||
addkey(SDLK_BRIGHTNESSDOWN, "BRIGHTNESSDOWN");
|
||||
addkey(SDLK_BRIGHTNESSUP, "brightnessup");
|
||||
addkey(SDLK_BRIGHTNESSUP, "BRIGHTNESSUP");
|
||||
addkey(SDLK_DISPLAYSWITCH, "displayswitch");
|
||||
addkey(SDLK_DISPLAYSWITCH, "DISPLAYSWITCH");
|
||||
addkey(SDLK_KBDILLUMTOGGLE, "kbdillumtoggle");
|
||||
addkey(SDLK_KBDILLUMTOGGLE, "KBDILLUMTOGGLE");
|
||||
addkey(SDLK_KBDILLUMDOWN, "kbdillumdown");
|
||||
addkey(SDLK_KBDILLUMDOWN, "KBDILLUMDOWN");
|
||||
addkey(SDLK_KBDILLUMUP, "kbdillumup");
|
||||
addkey(SDLK_KBDILLUMUP, "KBDILLUMUP");
|
||||
addkey(SDLK_EJECT, "eject");
|
||||
addkey(SDLK_EJECT, "EJECT");
|
||||
addkey(SDLK_SLEEP, "sleep");
|
||||
addkey(SDLK_SLEEP, "SLEEP");
|
||||
addkey(SDLK_APP1, "app1");
|
||||
addkey(SDLK_APP1, "APP1");
|
||||
addkey(SDLK_APP2, "app2");
|
||||
addkey(SDLK_APP2, "APP2");
|
||||
addkey(SDLK_AUDIOREWIND, "audiorewind");
|
||||
addkey(SDLK_AUDIOREWIND, "AUDIOREWIND");
|
||||
addkey(SDLK_AUDIOFASTFORWARD, "audiofastforward");
|
||||
addkey(SDLK_AUDIOFASTFORWARD, "AUDIOFASTFORWARD");
|
||||
lua_setglobal(L, "Keys");
|
||||
return 0;
|
||||
}
|
5
LuaEnum.h
Normal file
5
LuaEnum.h
Normal file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include "LuaVM.h"
|
||||
|
||||
int InitEnum(lua_State* L);
|
662
LuaNetwork.cpp
Normal file
662
LuaNetwork.cpp
Normal file
|
@ -0,0 +1,662 @@
|
|||
#include "LuaNetwork.h"
|
||||
|
||||
// Using Win10 by default
|
||||
#define _WIN32_WINNT 0x0A00
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib,"ws2_32.lib")
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <functional>
|
||||
#include "LuaCommon.h"
|
||||
using namespace std;
|
||||
|
||||
int LuaWSError(lua_State* L, const string& prefix="")
|
||||
{
|
||||
char msgbuf[1024] = { 0 };
|
||||
int err = WSAGetLastError();
|
||||
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), msgbuf, 1024, NULL);
|
||||
if (!prefix.empty())
|
||||
{
|
||||
return luaL_error(L, "%s: %s", prefix.c_str(), msgbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
return luaL_error(L, msgbuf);
|
||||
}
|
||||
}
|
||||
|
||||
// Bought from GSock.
|
||||
int DNSResolve(const std::string& HostName, std::vector<std::string>& _out_IPStrVec)
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
|
||||
/// Use getaddrinfo instead
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
struct addrinfo* result = nullptr;
|
||||
|
||||
int ret = getaddrinfo(HostName.c_str(), NULL, &hints, &result);
|
||||
if (ret != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cnt = 0;
|
||||
for (struct addrinfo* ptr = result; ptr != nullptr; ptr = ptr->ai_next)
|
||||
{
|
||||
cnt++;
|
||||
switch (ptr->ai_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
sockaddr_in* paddr = (struct sockaddr_in*) (ptr->ai_addr);
|
||||
char ip_buff[64] = { 0 };
|
||||
const char* ptr = inet_ntop(AF_INET, &(paddr->sin_addr), ip_buff, 64);
|
||||
if (ptr != NULL)
|
||||
{
|
||||
vec.push_back(ptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
sockaddr_in6* paddr = (struct sockaddr_in6*) (ptr->ai_addr);
|
||||
char ip_buff[128] = { 0 };
|
||||
const char* ptr = inet_ntop(AF_INET6, &(paddr->sin6_addr), ip_buff, 128);
|
||||
if (ptr != NULL)
|
||||
{
|
||||
vec.push_back(ptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}// End of switch
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
|
||||
_out_IPStrVec = std::move(vec);
|
||||
|
||||
// if(cnt!=(int)_out_IPStrVec.size()),
|
||||
// then (cnt-(int)_out_IPStrVec.size()) errors happend while calling inet_ntop().
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int DNSResolve(const std::string& HostName, std::string& _out_IPStr)
|
||||
{
|
||||
std::vector<std::string> vec;
|
||||
int ret = DNSResolve(HostName, vec);
|
||||
if (ret < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (vec.empty())
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
_out_IPStr = vec[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
class ThreadPool
|
||||
{
|
||||
public:
|
||||
int maxSize;
|
||||
|
||||
using TaskRunner = void (*)(void*);
|
||||
|
||||
class TaskData
|
||||
{
|
||||
public:
|
||||
TaskRunner runner;
|
||||
void* data;
|
||||
mutex mLock;
|
||||
condition_variable cond;
|
||||
|
||||
volatile int status; // -1 exit 0 new task 1 started 2 finished
|
||||
|
||||
TaskData()
|
||||
{
|
||||
runner = nullptr;
|
||||
data = nullptr;
|
||||
status = 2;
|
||||
}
|
||||
};
|
||||
|
||||
vector<TaskData> tasks;
|
||||
vector<thread> workers;
|
||||
|
||||
static void task_runner(TaskData& td)
|
||||
{
|
||||
unique_lock<mutex> ulk(td.mLock);
|
||||
while (1)
|
||||
{
|
||||
td.cond.wait(ulk);
|
||||
if (td.status == -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
td.status = 1;
|
||||
if (td.runner)
|
||||
{
|
||||
td.runner(td.data);
|
||||
}
|
||||
td.status = 2;
|
||||
}
|
||||
}
|
||||
|
||||
ThreadPool(int maxSize) : maxSize(maxSize), tasks(maxSize)
|
||||
{
|
||||
for (int i = 0; i < maxSize; i++)
|
||||
{
|
||||
workers.emplace_back(task_runner, tasks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
~ThreadPool()
|
||||
{
|
||||
for (int i = 0; i < maxSize; i++)
|
||||
{
|
||||
TaskData& td = tasks[i];
|
||||
{
|
||||
unique_lock<mutex> ulk(td.mLock);
|
||||
td.status = -1;
|
||||
td.cond.notify_all();
|
||||
}
|
||||
workers[i].join();
|
||||
}
|
||||
}
|
||||
|
||||
int addTask(TaskRunner runner, void* data)
|
||||
{
|
||||
for (int i = 0; i < maxSize; i++)
|
||||
{
|
||||
TaskData& td = tasks[i];
|
||||
if (td.status == 2)
|
||||
{
|
||||
unique_lock<mutex> ulk(td.mLock);
|
||||
td.runner = runner;
|
||||
td.data = data;
|
||||
td.status = 0;
|
||||
td.cond.notify_all();
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// need_copy: false 本方法对data有管辖权. true 本方法对data没有管辖权, 需要拷贝.
|
||||
void PushReadEvent(int fd, const char* data, int read_ret, bool need_copy = false)
|
||||
{
|
||||
SDL_Event e;
|
||||
e.type = SDL_USEREVENT;
|
||||
e.user.code = 1005;
|
||||
SocketEventData* p = new SocketEventData;
|
||||
p->fd = fd;
|
||||
p->ret = read_ret;
|
||||
if (read_ret <= 0)
|
||||
{
|
||||
p->errcode = WSAGetLastError();
|
||||
p->data = nullptr;
|
||||
if (!need_copy) delete[] data;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->errcode = 0;
|
||||
if (need_copy)
|
||||
{
|
||||
char* s = new char[read_ret + 32];
|
||||
memcpy(s, data, read_ret);
|
||||
p->data = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
p->data = data;
|
||||
}
|
||||
}
|
||||
SDL_PushEvent(&e);
|
||||
}
|
||||
|
||||
void PushWriteEvent(int fd)
|
||||
{
|
||||
SDL_Event e;
|
||||
e.type = SDL_USEREVENT;
|
||||
e.user.code = 1006;
|
||||
SocketEventData* p = new SocketEventData;
|
||||
p->data = nullptr;
|
||||
p->fd = fd;
|
||||
p->ret = 0;
|
||||
p->errcode = 0;
|
||||
SDL_PushEvent(&e);
|
||||
}
|
||||
|
||||
|
||||
class SocketSelector
|
||||
{
|
||||
public:
|
||||
mutex mLock;
|
||||
condition_variable cond;
|
||||
volatile int status;
|
||||
set<int> wait_read;
|
||||
set<int> wait_write;
|
||||
|
||||
int control_usec; // 1ms
|
||||
int control_usec_low_bound; // 0.5ms
|
||||
int control_usec_high_bound; // 1.5ms
|
||||
|
||||
SocketSelector()
|
||||
{
|
||||
control_usec = 1000;
|
||||
control_usec_low_bound = 500;
|
||||
control_usec_high_bound = 1500;
|
||||
status = 1; // 0 Require stop, 1 Running
|
||||
}
|
||||
|
||||
int run_once()
|
||||
{
|
||||
fd_set* pRead;
|
||||
fd_set* pWrite;
|
||||
fd_set fs_read;
|
||||
fd_set fs_write;
|
||||
timeval tm;
|
||||
tm.tv_sec = 0;
|
||||
tm.tv_usec = control_usec;
|
||||
|
||||
{
|
||||
lock_guard<mutex> ulk(mLock);
|
||||
|
||||
if (!wait_read.empty())
|
||||
{
|
||||
FD_ZERO(&fs_read);
|
||||
for (const int& fd : wait_read)
|
||||
{
|
||||
FD_SET(fd, &fs_read);
|
||||
}
|
||||
pRead = &fs_read;
|
||||
}
|
||||
if (!wait_write.empty())
|
||||
{
|
||||
FD_ZERO(&fs_write);
|
||||
for (const int& fd : wait_write)
|
||||
{
|
||||
FD_SET(fd, &fs_write);
|
||||
}
|
||||
pWrite = &fs_write;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = select(0, pRead, pWrite, nullptr, &tm); // 都没有就空等一个tick.
|
||||
if (ret <= 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
{
|
||||
lock_guard<mutex> ulk(mLock);
|
||||
|
||||
for (const int& fd : wait_read)
|
||||
{
|
||||
if (FD_ISSET(fd, &fs_read))
|
||||
{
|
||||
char* buffer = new char[1024];
|
||||
int ret = recv(fd, buffer, 1024, 0);
|
||||
PushReadEvent(fd, buffer, ret);
|
||||
wait_read.erase(fd);
|
||||
}
|
||||
}
|
||||
|
||||
for (const int& fd : wait_write)
|
||||
{
|
||||
if (FD_ISSET(fd, &fs_write))
|
||||
{
|
||||
PushWriteEvent(fd);
|
||||
wait_write.erase(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
while (status)
|
||||
{
|
||||
run_once();
|
||||
}
|
||||
}
|
||||
|
||||
void add_wait_read(int fd)
|
||||
{
|
||||
lock_guard<mutex> lk(mLock);
|
||||
wait_read.insert(fd);
|
||||
}
|
||||
|
||||
void add_wait_write(int fd)
|
||||
{
|
||||
lock_guard<mutex> lk(mLock);
|
||||
wait_write.insert(fd);
|
||||
}
|
||||
};
|
||||
|
||||
#define setfn(func, name) lua_pushcfunction(L, func);lua_setfield(L, -2, name)
|
||||
|
||||
struct ClientSocket
|
||||
{
|
||||
int fd;
|
||||
int family;
|
||||
int socketType;
|
||||
|
||||
static int close(lua_State* L)
|
||||
{
|
||||
check(L, { LUA_TUSERDATA }, { "clientsocket" });
|
||||
ClientSocket* p = (ClientSocket*)lua_touserdata(L, 1);
|
||||
if (p->fd != -1)
|
||||
{
|
||||
closesocket(p->fd);
|
||||
p->fd = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int connect_ipv4(lua_State* L)
|
||||
{
|
||||
check(L, { LUA_TUSERDATA, LUA_TSTRING, LUA_TNUMBER }, { "clientsocket" });
|
||||
ClientSocket* p = (ClientSocket*)lua_touserdata(L, 1);
|
||||
const char* addr = lua_tostring(L, 2);
|
||||
int port = lua_tointeger(L, 3);
|
||||
|
||||
string IPStr;
|
||||
if (DNSResolve(addr, IPStr) < 0)
|
||||
{
|
||||
return LuaWSError(L, "DNS resolve failed ("s + addr + ")");
|
||||
}
|
||||
|
||||
struct sockaddr_in saddr;
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
if (inet_pton(AF_INET, IPStr.c_str(), &(saddr.sin_addr.s_addr)) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
saddr.sin_port = htons(port);
|
||||
saddr.sin_family = AF_INET;
|
||||
|
||||
int ret = connect(p->fd, (const sockaddr*)& saddr, sizeof(saddr));
|
||||
if (ret < 0)
|
||||
{
|
||||
return LuaWSError(L, "Connect failed. ("s + IPStr + ")");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int send(lua_State* L)
|
||||
{
|
||||
check(L, { LUA_TUSERDATA, LUA_TSTRING }, { "clientsocket" });
|
||||
ClientSocket* p = (ClientSocket*)lua_touserdata(L, 1);
|
||||
size_t dataLen = 0;
|
||||
const char* data = lua_tolstring(L, 2, &dataLen);
|
||||
size_t done = 0;
|
||||
while (done < dataLen)
|
||||
{
|
||||
int ret = ::send(p->fd, data + done, dataLen - done, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
return LuaWSError(L, "Send failed");
|
||||
}
|
||||
done += ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int recv(lua_State* L)
|
||||
{
|
||||
check(L, { LUA_TUSERDATA }, { "clientsocket" });
|
||||
ClientSocket* p = (ClientSocket*)lua_touserdata(L, 1);
|
||||
int size;
|
||||
if (lua_gettop(L) >= 2)
|
||||
{
|
||||
printf("%s\n", lua_typename(L, lua_type(L, 2)));
|
||||
size = lua_tointeger(L, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 1024;
|
||||
}
|
||||
if (size > 0)
|
||||
{
|
||||
unique_ptr<char> data(new char[size]);
|
||||
int ret = ::recv(p->fd, data.get(), size, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
return LuaWSError(L, "Recv failed");
|
||||
}
|
||||
else if (ret == 0)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushlstring(L, data.get(), ret);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return luaL_error(L, "Bad argument #%d. integer above 0 expected, got %s", 2, lua_tostring(L, 2));
|
||||
}
|
||||
}
|
||||
|
||||
static int create(lua_State* L)
|
||||
{
|
||||
int socketType = SOCK_STREAM;
|
||||
if (lua_gettop(L) >= 1)
|
||||
{
|
||||
if (lua_type(L, 1) == LUA_TSTRING)
|
||||
{
|
||||
if (strcmp(lua_tostring(L, 1), "tcp") == 0)
|
||||
{
|
||||
socketType = SOCK_STREAM;
|
||||
}
|
||||
else if (strcmp(lua_tostring(L, 1), "udp") == 0)
|
||||
{
|
||||
socketType = SOCK_DGRAM;
|
||||
}
|
||||
else
|
||||
{
|
||||
return luaL_error(L, "Invalid socket type: %s", lua_tostring(L, 1));
|
||||
}
|
||||
}
|
||||
lua_settop(L, 0);
|
||||
}
|
||||
int fd = socket(AF_INET, socketType, 0);
|
||||
if (fd == -1)
|
||||
{
|
||||
return LuaWSError(L);
|
||||
}
|
||||
ClientSocket* p = (ClientSocket*)lua_newuserdata(L, sizeof(ClientSocket));
|
||||
p->fd = fd;
|
||||
p->family = AF_INET;
|
||||
p->socketType = socketType;
|
||||
if (lua_getfield(L, LUA_REGISTRYINDEX, "__clientsocket_mt") != LUA_TTABLE)
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
lua_newtable(L);
|
||||
// GC
|
||||
setfn(close, "__gc");
|
||||
|
||||
// Fields
|
||||
lua_newtable(L);
|
||||
lua_pushstring(L, "clientsocket"); lua_setfield(L, -2, "type");
|
||||
setfn(close, "close");
|
||||
setfn(connect_ipv4, "connect");
|
||||
setfn(send, "send");
|
||||
setfn(recv, "recv");
|
||||
|
||||
// Set __index of metatable.
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, LUA_REGISTRYINDEX, "__clientsocket_mt");
|
||||
}
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
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;
|
||||
WSAData wdt;
|
||||
wd = MAKEWORD(2, 2);
|
||||
int ret = WSAStartup(wd, &wdt);
|
||||
if (ret < 0)
|
||||
{
|
||||
return LuaWSError(L);
|
||||
}
|
||||
lua_pushcfunction(L, ClientSocket::create);
|
||||
lua_setglobal(L, "ClientSocket");
|
||||
|
||||
return 0;
|
||||
}
|
15
LuaNetwork.h
Normal file
15
LuaNetwork.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
#include "LuaVM.h"
|
||||
#include "SDL2/include/SDL.h"
|
||||
|
||||
int InitNetwork(lua_State* L);
|
||||
|
||||
struct SocketEventData
|
||||
{
|
||||
int fd;
|
||||
const char* data;
|
||||
int ret;
|
||||
int errcode;
|
||||
};
|
||||
|
||||
void HandleNetworkEvent(lua_State* L, const SDL_Event& e);
|
|
@ -96,8 +96,13 @@ function async(fn)
|
|||
end
|
||||
|
||||
-- Load & run game
|
||||
local gameMain = loadfile("code/snake.lua")
|
||||
xpcall(gameMain, function(err)
|
||||
local gameMain, err = loadfile("code/network_test.lua")
|
||||
if not gameMain then
|
||||
print("Failed to load chunk.")
|
||||
print(err)
|
||||
else
|
||||
xpcall(gameMain, function(err)
|
||||
print("LuaMain Exception: ", err)
|
||||
print(debug.traceback())
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -54,13 +54,13 @@ function Snake(box)
|
|||
if not s.dead then
|
||||
if s.queue[1] then
|
||||
local key = table.remove(s.queue, 1)
|
||||
if key == string.byte('w') and s.face ~= "down" then
|
||||
if key == Keys.W and s.face ~= "down" then
|
||||
s.face = "up"
|
||||
elseif key == string.byte('s') and s.face ~= "up" then
|
||||
elseif key == Keys.S and s.face ~= "up" then
|
||||
s.face = "down"
|
||||
elseif key == string.byte('a') and s.face ~= "right" then
|
||||
elseif key == Keys.A and s.face ~= "right" then
|
||||
s.face = "left"
|
||||
elseif key == string.byte('d') and s.face ~= "left" then
|
||||
elseif key == Keys.D and s.face ~= "left" then
|
||||
s.face = "right"
|
||||
end
|
||||
end
|
||||
|
@ -133,16 +133,26 @@ local world = GameBox()
|
|||
local player = Snake(world)
|
||||
|
||||
wnd:on('keydown', function(key)
|
||||
if key == Keys.R then
|
||||
world = GameBox()
|
||||
player = Snake(world)
|
||||
elseif key == Keys.ESCAPE then
|
||||
FireExit()
|
||||
else
|
||||
table.insert(player.queue, key)
|
||||
end
|
||||
end)
|
||||
|
||||
SetInterval(function()
|
||||
world:update()
|
||||
player:update()
|
||||
end, 150)
|
||||
|
||||
SetInterval(function()
|
||||
rnd:clear()
|
||||
world:draw()
|
||||
player:draw()
|
||||
rnd:update()
|
||||
end, 200)
|
||||
end, 1000//60)
|
||||
|
||||
wnd:show()
|
||||
|
|
Loading…
Reference in New Issue
Block a user