LuaEngine v0.3

master
Kirigaya Kazuto 2020-05-29 01:39:49 +08:00
parent 3abf10ed2b
commit 71059fda47
12 changed files with 541 additions and 105 deletions

View File

@ -11,8 +11,10 @@ void InitLuaEngine(lua_State* L)
InitMusic(L);
InitCommon(L);
InitTCPSocket(L);
InitThread(L);
InitUDPSocket(L);
InitNetwork(L);
InitSocketSelector(L);
InitThread(L);
}
void InitEngine()
@ -26,7 +28,7 @@ void InitEngine()
SDL_Log("Mix_OpenAudio: %s\n", Mix_GetError());
exit(2);
}
Mix_AllocateChannels(16);
// Stop text input event
SDL_StopTextInput();

View File

@ -4,7 +4,8 @@
module Music
load(filename: string): MusicMedia
loadChunk(filename: string): ChunkMedia
play(music: MusicMedia, [loops: int])
play(music: MusicMedia, [loops: int]) Loops default to 1 time
playChunk(chunk: ChunkMedia, channel: int, [loops: int]) Loops default to 1 time.
pause()
resume()
*/
@ -106,7 +107,7 @@ int music_loadchunkmem(lua_State* L)
int music_play(lua_State* L)
{
auto music = lua_checkpointer<Mix_Music>(L, 1, "LuaEngineMusicMedia");
int loops = -1;
int loops = 0;
if (!lua_isnone(L, 2))
{
loops = luaL_checkinteger(L, 2);
@ -118,6 +119,24 @@ int music_play(lua_State* L)
return 0;
}
int music_playchunk(lua_State* L)
{
auto chunk = lua_checkpointer<Mix_Chunk>(L, 1, "LuaEngineChunkMedia");
int channel = luaL_checkinteger(L, 2);
int loops = 0;
if (!lua_isnone(L, 3))
{
loops = luaL_checkinteger(L, 3);
}
int ret = Mix_PlayChannel(channel, chunk, loops);
if (ret == -1)
{
return MixError(L, Mix_PlayChannel);
}
lua_pushinteger(L, ret);
return 1;
}
int music_pause(lua_State* L)
{
Mix_PauseMusic();
@ -140,6 +159,7 @@ void InitMusic(lua_State* L)
lua_setfield_function(L, "loadChunk", music_loadchunk);
lua_setfield_function(L, "loadChunkmem", music_loadchunkmem);
lua_setfield_function(L, "play", music_play);
lua_setfield_function(L, "playChunk", music_playchunk);
lua_setfield_function(L, "pause", music_pause);
lua_setfield_function(L, "resume", music_resume);
lua_setfield(L, -2, "Music");

57
NetworkWin.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "include.h"
#ifdef _WIN32
#define _WIN32_WINNT 0x0A00 // Win10
#include <winsock2.h>
#include <ws2tcpip.h>
int network_getip(lua_State* L)
{
const char* host = luaL_checkstring(L, 1);
addrinfo* result = NULL;
if (getaddrinfo(host, NULL, NULL, &result) < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "getaddrinfo");
return lua_error(L);
}
int cnt = 0;
for (addrinfo* pinfo = result; pinfo; pinfo = pinfo->ai_next)
{
switch (pinfo->ai_family)
{
case AF_INET:
{
char buffer[1024] = { 0 };
if (inet_ntop(AF_INET, &((sockaddr_in*)(pinfo->ai_addr))->sin_addr, buffer, 1024))
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "inet_ntop");
freeaddrinfo(result);
return lua_error(L);
}
lua_pushstring(L, buffer);
cnt++;
break;
}
}
}
freeaddrinfo(result);
return cnt;
}
void InitNetwork(lua_State* L)
{
lua_getglobal(L, "package");
lua_getfield(L, -1, "loaded");
lua_newtable(L);
lua_setfield_function(L, "getip", network_getip);
lua_setfield(L, -2, "network");
lua_pop(L, 2);
}
#endif // End of _WIN32

View File

@ -1,5 +1,5 @@
#include "Select.h"
#include "TCP.h"
#include "Socket.h"
#ifdef _WIN32
#define _WIN32_WINNT 0x0A00 // Win10
@ -8,57 +8,59 @@
#include <vector>
using namespace std;
inline void luatable_to_fdset(lua_State* L, int tbl_index, fd_set& fds)
{
lua_pushnil(L);
while (lua_next(L, tbl_index))
{
lua_pop(L, 1);
auto s = lua_testblock<SocketData>(L, -1, "LuaEngineTCPSocket") ? lua_checkblock<SocketData>(L, -1, "LuaEngineTCPSocket") : lua_checkblock<SocketData>(L, -1, "LuaEngineUDPSocket");
if (s->fd > 0)
{
FD_SET(s->fd, &fds);
}
}
}
inline void fdset_to_luatable(lua_State* L, int tbl_index, fd_set& fds)
{
lua_newtable(L); // ... RetT
lua_pushnil(L); // ... RetT nil
while (lua_next(L, tbl_index))
{
lua_pop(L, 1); // ... RetT Socket
auto s = lua_testblock<SocketData>(L, -1, "LuaEngineTCPSocket") ? lua_checkblock<SocketData>(L, -1, "LuaEngineTCPSocket") : lua_checkblock<SocketData>(L, -1, "LuaEngineUDPSocket");
if (s->fd > 0 && FD_ISSET(s->fd, &fds))
{
lua_pushvalue(L, -1); // ... RetT Socket Socket
lua_pushboolean(L, true); // ... RetT Socket Socket true
lua_settable(L, -4); // ... RetT Socket
}
}
}
int select_call(lua_State* L)
{
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checktype(L, 2, LUA_TTABLE);
luaL_checktype(L, 3, LUA_TTABLE);
int us = luaL_checkinteger(L, 4);
FD_SET readset, writeset, errorset;
fd_set readset, writeset, errorset;
FD_ZERO(&readset);
lua_pushnil(L);
while (lua_next(L, 1))
{
lua_pop(L, 1);
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
if (s->fd > 0)
{
FD_SET(s->fd, &readset);
}
}
luatable_to_fdset(L, 1, readset);
FD_ZERO(&writeset);
lua_pushnil(L);
while (lua_next(L, 2))
{
lua_pop(L, 1);
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
if (s->fd > 0)
{
FD_SET(s->fd, &writeset);
}
}
luatable_to_fdset(L, 2, writeset);
FD_ZERO(&errorset);
lua_pushnil(L);
while (lua_next(L, 3))
{
lua_pop(L, 1);
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
if (s->fd > 0)
{
FD_SET(s->fd, &errorset);
}
}
luatable_to_fdset(L, 3, errorset);
timeval tm;
tm.tv_sec = us / 1000000;
tm.tv_usec = us % 1000000;
printf("[DEBUG] select() start\n");
int ret = select(1024, &readset, &writeset, &errorset, &tm);
printf("[DEBUG] select() done. ret=%d\n", ret);
if (ret < 0)
{
@ -72,47 +74,9 @@ int select_call(lua_State* L)
}
else
{
lua_newtable(L); // ... RetT
lua_pushnil(L); // ... RetT nil
while (lua_next(L, 1))
{
lua_pop(L, 1); // ... RetT Socket
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
if (s->fd > 0 && FD_ISSET(s->fd, &readset))
{
lua_pushvalue(L, -1); // ... RetT Socket Socket
lua_pushboolean(L, true); // ... RetT Socket Socket true
lua_settable(L, -4); // ... RetT Socket
}
}
lua_newtable(L); // ... RetT
lua_pushnil(L); // ... RetT nil
while (lua_next(L, 2))
{
lua_pop(L, 1); // ... RetT Socket
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
if (s->fd > 0 && FD_ISSET(s->fd, &writeset))
{
lua_pushvalue(L, -1); // ... RetT Socket Socket
lua_pushboolean(L, true); // ... RetT Socket Socket true
lua_settable(L, -4); // ... RetT Socket
}
}
lua_newtable(L); // ... RetT
lua_pushnil(L); // ... RetT nil
while (lua_next(L, 3))
{
lua_pop(L, 1); // ... RetT Socket
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
if (s->fd > 0 && FD_ISSET(s->fd, &errorset))
{
lua_pushvalue(L, -1); // ... RetT Socket Socket
lua_pushboolean(L, true); // ... RetT Socket Socket true
lua_settable(L, -4); // ... RetT Socket
}
}
fdset_to_luatable(L, 1, readset); // +1
fdset_to_luatable(L, 2, writeset); // +1
fdset_to_luatable(L, 3, errorset); // +1
return 3; // ... RetT RetT RetT
}

11
Socket.h Normal file
View File

@ -0,0 +1,11 @@
#include "include.h"
#include <vector>
class SocketData
{
public:
int fd;
bool nonblocking;
std::vector<char> data;
int buffsz;
};

14
TCP.h
View File

@ -1,5 +1,4 @@
#include "include.h"
#include <vector>
#include "Socket.h"
/*
class TCPSocket
@ -8,7 +7,7 @@ class TCPSocket
setblocking(nonblocking: boolean)
listen([ip: string], port: int, [backlog: int]) Address default to 0.0.0.0, backlog default to 10.
# Blocking mode: All non-expected error will be raised as exception.
# Blocking mode: All unexpected error will be raised as exception.
connect(ip: string, port: int)
accept(): TCPSocket PeerIP PeerPort
send(data: string) All data will be sent before return.
@ -20,12 +19,3 @@ class TCPSocket
send(data: string)
recv([maxsize: int]): string
*/
class TCPSocket
{
public:
int fd;
bool nonblocking;
std::vector<char> data;
int buffsz;
};

View File

@ -9,19 +9,19 @@ using namespace std;
int tcp_socket_dtor(lua_State* L)
{
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
if (s->fd > 0)
{
closesocket(s->fd);
s->fd = -1;
}
s->~TCPSocket();
s->~SocketData();
return 0;
}
int tcp_socket_close(lua_State* L)
{
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
if (s->fd > 0)
{
closesocket(s->fd);
@ -32,7 +32,7 @@ int tcp_socket_close(lua_State* L)
int tcp_socket_send(lua_State* L)
{
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
size_t sz;
const char* str = luaL_checklstring(L, 2, &sz);
size_t done = 0;
@ -59,7 +59,7 @@ int tcp_socket_send(lua_State* L)
int tcp_socket_recv(lua_State* L)
{
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
int ret = recv(s->fd, s->data.data(), s->buffsz, 0);
if (ret < 0)
{
@ -79,14 +79,19 @@ int tcp_socket_recv(lua_State* L)
int tcp_socket_connect(lua_State* L)
{
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
const char* ip = luaL_checkstring(L, 2);
int port = luaL_checkinteger(L, 3);
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(ip);
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "inet_pton");
return lua_error(L);
}
addr.sin_port = htons(port);
int ret = connect(s->fd, (const sockaddr*)&addr, sizeof(addr));
@ -107,7 +112,7 @@ int tcp_socket_connect(lua_State* L)
int tcp_socket_listen(lua_State* L)
{
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
const char* ip = NULL;
int port;
int backlog = 10;
@ -134,7 +139,12 @@ int tcp_socket_listen(lua_State* L)
addr.sin_family = AF_INET;
if (ip && strcmp(ip, "0.0.0.0"))
{
addr.sin_addr.s_addr = inet_addr(ip);
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "inet_pton");
return lua_error(L);
}
}
else
{
@ -163,7 +173,7 @@ int tcp_socket_listen(lua_State* L)
int tcp_socket_setblocking(lua_State* L)
{
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
luaL_checkany(L, 2);
bool blocking = lua_toboolean(L, 2);
if (blocking != s->nonblocking)
@ -199,7 +209,7 @@ int tcp_socket_accept(lua_State* L);
void put_tcp_socket(lua_State* L, int fd, bool nonblocking)
{
auto s = new (lua_newblock<TCPSocket>(L)) TCPSocket;
auto s = new (lua_newblock<SocketData>(L)) SocketData;
if (luaL_newmetatable(L, "LuaEngineTCPSocket"))
{
lua_setfield_function(L, "__gc", tcp_socket_dtor);
@ -222,7 +232,7 @@ void put_tcp_socket(lua_State* L, int fd, bool nonblocking)
int tcp_socket_accept(lua_State* L)
{
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
sockaddr_in addr;
int addrsz = sizeof(addr);
int ret = accept(s->fd, (sockaddr*)&addr, &addrsz);
@ -237,7 +247,15 @@ int tcp_socket_accept(lua_State* L)
return lua_error(L);
}
put_tcp_socket(L, ret, false);
lua_pushstring(L, inet_ntoa(addr.sin_addr));
char buffer[1024] = { 0 };
if (inet_ntop(AF_INET, &addr.sin_addr, buffer, 1024) < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "inet_ntop");
return lua_error(L);
}
lua_pushstring(L, buffer);
lua_pushinteger(L, ntohs(addr.sin_port));
return 3;
}

View File

16
UDP.h Normal file
View File

@ -0,0 +1,16 @@
#include "Socket.h"
/*
class UDPSocket
constructor()
close()
setblocking(nonblocking: boolean)
setbroadcast(isbroadcast: boolean) Broadcast default to false.
listen([ip: string], port: int) Address default to 0.0.0.0.
connect(ip: string, port: int)
send(data: string)
recv([maxsize: int]): string. Default to 4KB.
sendto([ip: string], port: int, data: string) If ip is empty, default to 255.255.255.255 (broadcast)
recvfrom(): data: string, ip: string, port: int
*/

348
UDPWin.cpp Normal file
View File

@ -0,0 +1,348 @@
#include "UDP.h"
#ifdef _WIN32
#define _WIN32_WINNT 0x0A00 // Win10
#include <winsock2.h>
#include <ws2tcpip.h>
int udp_socket_dtor(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
if (s->fd > 0)
{
closesocket(s->fd);
s->fd = -1;
}
s->~SocketData();
return 0;
}
int udp_socket_close(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
if (s->fd > 0)
{
closesocket(s->fd);
s->fd = -1;
}
return 0;
}
int udp_socket_send(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
size_t sz;
const char* str = luaL_checklstring(L, 2, &sz);
int ret = send(s->fd, str, sz, 0);
if (ret < 0)
{
int errcode = WSAGetLastError();
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
{
lua_pushboolean(L, true);
return 1;
}
put_winerror(L, errcode, "send");
return lua_error(L);
}
return 0;
}
int udp_socket_recv(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
int ret = recv(s->fd, s->data.data(), s->buffsz, 0);
if (ret < 0)
{
int errcode = WSAGetLastError();
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
{
return 0;
}
put_winerror(L, errcode, "recv");
return lua_error(L);
}
lua_pushlstring(L, s->data.data(), ret);
return 1;
}
int udp_socket_sendto(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
const char* ip = NULL;
int port;
size_t sz;
const char* str = NULL;
if (lua_type(L, 2) == LUA_TSTRING)
{
ip = luaL_checkstring(L, 2);
port = luaL_checkinteger(L, 3);
str = luaL_checklstring(L, 4, &sz);
}
else
{
port = luaL_checkinteger(L, 2);
str = luaL_checklstring(L, 3, &sz);
}
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if (ip && strcmp(ip, "255.255.255.255"))
{
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "inet_pton");
return lua_error(L);
}
}
else
{
addr.sin_addr.s_addr = INADDR_BROADCAST;
}
int ret = sendto(s->fd, str, sz, 0, (const sockaddr*)&addr, sizeof(addr));
if (ret < 0)
{
int errcode = WSAGetLastError();
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
{
lua_pushboolean(L, true);
return 1;
}
put_winerror(L, errcode, "sendto");
return lua_error(L);
}
return 0;
}
int udp_socket_recvfrom(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
sockaddr_in addr;
int addrlen = sizeof(addr);
int ret = recvfrom(s->fd, s->data.data(), s->buffsz, 0, (sockaddr*)&addr, &addrlen);
if (ret < 0)
{
int errcode = WSAGetLastError();
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
{
return 0;
}
put_winerror(L, errcode, "recvfrom");
return lua_error(L);
}
char buffer[1024] = { 0 };
if (inet_ntop(AF_INET, &addr.sin_addr, buffer, 1024) < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "inet_ntop");
return lua_error(L);
}
lua_pushlstring(L, s->data.data(), ret);
lua_pushstring(L, buffer);
lua_pushinteger(L, ntohs(addr.sin_port));
return 3;
}
int udp_socket_connect(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
const char* ip = luaL_checkstring(L, 2);
int port = luaL_checkinteger(L, 3);
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "inet_pton");
return lua_error(L);
}
addr.sin_port = htons(port);
int ret = connect(s->fd, (const sockaddr*)&addr, sizeof(addr));
if (ret < 0)
{
int errcode = WSAGetLastError();
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
{
lua_pushboolean(L, true);
return 1;
}
put_winerror(L, errcode, "connect");
return lua_error(L);
}
return 0;
}
int udp_socket_setblocking(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
luaL_checkany(L, 2);
bool blocking = lua_toboolean(L, 2);
if (blocking != s->nonblocking)
{
return 0;
}
if (blocking) // set to blocking
{
u_long arg = 0;
int ret = ioctlsocket(s->fd, FIONBIO, &arg);
if (ret)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "ioctlsocket");
return lua_error(L);
}
}
else // set to nonblocking
{
u_long arg = 1;
int ret = ioctlsocket(s->fd, FIONBIO, &arg);
if (ret)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "ioctlsocket");
return lua_error(L);
}
}
return 0;
}
int udp_socket_setbroadcast(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
socklen_t opt = 0;
if (!lua_isnone(L, 2) && lua_toboolean(L, 2))
{
opt = 1;
}
int ret = setsockopt(s->fd, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(opt));
if (ret < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "setsockopt");
return lua_error(L);
}
return 0;
}
int udp_socket_listen(lua_State* L)
{
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
const char* ip = NULL;
int port;
if (lua_type(L, 2) == LUA_TSTRING)
{
ip = luaL_checkstring(L, 2);
port = luaL_checkinteger(L, 3);
}
else
{
port = luaL_checkinteger(L, 2);
}
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
if (ip && strcmp(ip, "0.0.0.0"))
{
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "inet_pton");
return lua_error(L);
}
}
else
{
addr.sin_addr.s_addr = INADDR_ANY;
}
addr.sin_port = htons(port);
int ret = bind(s->fd, (const sockaddr*)&addr, sizeof(addr));
if (ret < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "bind");
return lua_error(L);
}
return 0;
}
void put_udp_socket(lua_State* L, int fd, bool nonblocking)
{
auto s = new (lua_newblock<SocketData>(L)) SocketData;
if (luaL_newmetatable(L, "LuaEngineUDPSocket"))
{
lua_setfield_function(L, "__gc", udp_socket_dtor);
lua_newtable(L);
lua_setfield_function(L, "close", udp_socket_close);
lua_setfield_function(L, "send", udp_socket_send);
lua_setfield_function(L, "recv", udp_socket_recv);
lua_setfield_function(L, "sendto", udp_socket_sendto);
lua_setfield_function(L, "recvfrom", udp_socket_recvfrom);
lua_setfield_function(L, "listen", udp_socket_listen);
lua_setfield_function(L, "connect", udp_socket_connect);
lua_setfield_function(L, "setblocking", udp_socket_setblocking);
lua_setfield_function(L, "setbroadcast", udp_socket_setbroadcast);
lua_setfield(L, -2, "__index");
}
lua_setmetatable(L, -2);
s->fd = fd;
s->nonblocking = nonblocking;
s->buffsz = 4096;
s->data.resize(s->buffsz);
}
int udp_socket_new(lua_State* L)
{
bool nonblocking = false;
if (!lua_isnone(L, 1))
{
if (lua_toboolean(L, 1))
{
nonblocking = true;
}
}
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
{
int errcode = WSAGetLastError();
put_winerror(L, errcode, "socket");
return lua_error(L);
}
if (nonblocking)
{
u_long arg = 1;
int ret = ioctlsocket(fd, FIONBIO, &arg);
if (ret)
{
int errcode = WSAGetLastError();
closesocket(fd);
put_winerror(L, errcode, "ioctlsocket");
return lua_error(L);
}
}
put_udp_socket(L, fd, nonblocking);
return 1;
}
void InitUDPSocket(lua_State* L)
{
lua_getglobal(L, "package");
lua_getfield(L, -1, "loaded");
lua_pushcfunction(L, udp_socket_new);
lua_setfield(L, -2, "UDPSocket");
lua_pop(L, 2);
}
#endif // end of _WIN32

View File

@ -33,6 +33,12 @@ T* lua_checkblock(lua_State* L, int idx, const char* name)
return (T*)luaL_checkudata(L, idx, name);
}
template<typename T>
T* lua_testblock(lua_State* L, int idx, const char* name)
{
return (T*)luaL_testudata(L, idx, name);
}
// Shared Functions
void put_surface(lua_State* L, SDL_Surface* surf);
void put_texture(lua_State* L, SDL_Texture* text);
@ -45,6 +51,8 @@ void InitMusic(lua_State* L);
void InitEvent(lua_State* L);
void InitCommon(lua_State* L);
void InitTCPSocket(lua_State* L);
void InitUDPSocket(lua_State* L);
void InitNetwork(lua_State* L);
void InitThread(lua_State* L);
void InitSocketSelector(lua_State* L);

View File

@ -1,6 +1,7 @@
#include "LuaEngine.h"
#include <string>
#include <iostream>
#include <direct.h>
using namespace std;
string LoadFile(const string& filename)
@ -28,7 +29,8 @@ int main()
lua_State* L = luaL_newstate();
luaL_openlibs(L);
InitLuaEngine(L);
string code = LoadFile("game/app.lua");
_chdir("game");
string code = LoadFile("test.lua");
if (luaL_loadstring(L, code.c_str()))
{
cout << lua_tostring(L, -1) << endl;