1/**
2* Copyright (c) 2006-2010 LOVE Development Team
3*
4* This software is provided 'as-is', without any express or implied
5* warranty. In no event will the authors be held liable for any damages
6* arising from the use of this software.
7*
8* Permission is granted to anyone to use this software for any purpose,
9* including commercial applications, and to alter it and redistribute it
10* freely, subject to the following restrictions:
11*
12* 1. The origin of this software must not be misrepresented; you must not
13* claim that you wrote the original software. If you use this software
14* in a product, an acknowledgment in the product documentation would be
15* appreciated but is not required.
16* 2. Altered source versions must be plainly marked as such, and must not be
17* misrepresented as being the original software.
18* 3. This notice may not be removed or altered from any source distribution.
19**/
20
21// LOVE
22#include "wrap_ThreadModule.h"
23#include "wrap_LuaThread.h"
24#include "wrap_Channel.h"
25#include "ThreadModule.h"
26
27#include "filesystem/File.h"
28#include "filesystem/FileData.h"
29
30// C
31#include <cstring>
32
33namespace love
34{
35namespace thread
36{
37
38#define instance() (Module::getInstance<ThreadModule>(Module::M_THREAD))
39
40int w_newThread(lua_State *L)
41{
42 std::string name = "Thread code";
43 love::Data *data = nullptr;
44
45 if (lua_isstring(L, 1))
46 {
47 size_t slen = 0;
48 const char *str = lua_tolstring(L, 1, &slen);
49
50 // Treat the string as Lua code if it's long or has a newline.
51 if (slen >= 1024 || memchr(str, '\n', slen))
52 {
53 // Construct a FileData from the string.
54 lua_pushvalue(L, 1);
55 lua_pushstring(L, "string");
56 int idxs[] = {lua_gettop(L) - 1, lua_gettop(L)};
57 luax_convobj(L, idxs, 2, "filesystem", "newFileData");
58 lua_pop(L, 1);
59 lua_replace(L, 1);
60 }
61 else
62 luax_convobj(L, 1, "filesystem", "newFileData");
63 }
64 else if (luax_istype(L, 1, love::filesystem::File::type))
65 luax_convobj(L, 1, "filesystem", "newFileData");
66
67 if (luax_istype(L, 1, love::filesystem::FileData::type))
68 {
69 love::filesystem::FileData *fdata = luax_checktype<love::filesystem::FileData>(L, 1);
70 name = std::string("@") + fdata->getFilename();
71 data = fdata;
72 }
73 else
74 {
75 data = luax_checktype<love::Data>(L, 1);
76 }
77
78 LuaThread *t = instance()->newThread(name, data);
79 luax_pushtype(L, t);
80 t->release();
81 return 1;
82}
83
84int w_newChannel(lua_State *L)
85{
86 Channel *c = instance()->newChannel();
87 luax_pushtype(L, c);
88 c->release();
89 return 1;
90}
91
92int w_getChannel(lua_State *L)
93{
94 std::string name = luax_checkstring(L, 1);
95 Channel *c = instance()->getChannel(name);
96 luax_pushtype(L, c);
97 return 1;
98}
99
100// List of functions to wrap.
101static const luaL_Reg module_functions[] =
102{
103 { "newThread", w_newThread },
104 { "newChannel", w_newChannel },
105 { "getChannel", w_getChannel },
106 { 0, 0 }
107};
108
109static const lua_CFunction types[] = {
110 luaopen_thread,
111 luaopen_channel,
112 0
113};
114
115extern "C" int luaopen_love_thread(lua_State *L)
116{
117 ThreadModule *instance = instance();
118 if (instance == nullptr)
119 {
120 luax_catchexcept(L, [&](){ instance = new love::thread::ThreadModule(); });
121 }
122 else
123 instance->retain();
124
125 WrappedModule w;
126 w.module = instance;
127 w.name = "thread";
128 w.type = &Module::type;
129 w.functions = module_functions;
130 w.types = types;
131
132 return luax_register_module(L, w);
133}
134
135} // thread
136} // love
137