mirror of
https://github.com/Kiritow/LuaEngine.git
synced 2024-03-22 13:11:45 +08:00
LuaEngine v0.3
This commit is contained in:
parent
3abf10ed2b
commit
71059fda47
|
@ -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();
|
||||
|
||||
|
|
24
Music.cpp
24
Music.cpp
|
@ -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
57
NetworkWin.cpp
Normal 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
|
114
SelectWin.cpp
114
SelectWin.cpp
|
@ -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
11
Socket.h
Normal 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
14
TCP.h
|
@ -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;
|
||||
};
|
||||
|
|
44
TCPWin.cpp
44
TCPWin.cpp
|
@ -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;
|
||||
}
|
||||
|
|
16
UDP.h
Normal file
16
UDP.h
Normal 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
348
UDPWin.cpp
Normal 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
|
|
@ -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);
|
||||
|
||||
|
|
4
main.cpp
4
main.cpp
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user