lua_bindings/spatial_update_queue: Initial half-working version
This commit is contained in:
parent
a2890529bf
commit
abad1e0e2f
@ -107,6 +107,7 @@ if(BUILD_CLIENT)
|
|||||||
src/lua_bindings/misc.cpp
|
src/lua_bindings/misc.cpp
|
||||||
src/lua_bindings/cereal.cpp
|
src/lua_bindings/cereal.cpp
|
||||||
src/lua_bindings/voxel.cpp
|
src/lua_bindings/voxel.cpp
|
||||||
|
src/lua_bindings/spatial_update_queue.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(${CLIENT_EXE_NAME} ${CLIENT_SRCS})
|
add_executable(${CLIENT_EXE_NAME} ${CLIENT_SRCS})
|
||||||
|
@ -213,14 +213,6 @@ local function SpatialUpdateQueue()
|
|||||||
near_weight=near_weight, near_trigger_d=near_trigger_d,
|
near_weight=near_weight, near_trigger_d=near_trigger_d,
|
||||||
far_weight=far_weight, far_trigger_d=far_trigger_d})
|
far_weight=far_weight, far_trigger_d=far_trigger_d})
|
||||||
end,
|
end,
|
||||||
-- Put something to be prioritized more the closer it is
|
|
||||||
put_near_priority = function(self, p, trigger_d, weight, value)
|
|
||||||
self:put(p, weight, trigger_d, nil, nil, value)
|
|
||||||
end,
|
|
||||||
-- Put something to be prioritized more the farther it is
|
|
||||||
put_far_priority = function(self, p, trigger_d, weight, value)
|
|
||||||
self:put(p, nil, nil, weight, trigger_d, value)
|
|
||||||
end,
|
|
||||||
get = function(self)
|
get = function(self)
|
||||||
local item = table.remove(self.queue)
|
local item = table.remove(self.queue)
|
||||||
if not item then return nil end
|
if not item then return nil end
|
||||||
@ -241,6 +233,9 @@ local function SpatialUpdateQueue()
|
|||||||
if not item then return nil end
|
if not item then return nil end
|
||||||
return item.fw
|
return item.fw
|
||||||
end,
|
end,
|
||||||
|
get_length = function(self)
|
||||||
|
return #self.queue
|
||||||
|
end,
|
||||||
}
|
}
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -268,7 +263,8 @@ function M.init()
|
|||||||
M.chunk_size_voxels:mul_components(M.section_size_chunks)
|
M.chunk_size_voxels:mul_components(M.section_size_chunks)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local node_update_queue = SpatialUpdateQueue()
|
--local node_update_queue = SpatialUpdateQueue()
|
||||||
|
local node_update_queue = buildat.SpatialUpdateQueue()
|
||||||
|
|
||||||
local function update_voxel_geometry(node)
|
local function update_voxel_geometry(node)
|
||||||
local data = node:GetVar("buildat_voxel_data"):GetBuffer()
|
local data = node:GetVar("buildat_voxel_data"):GetBuffer()
|
||||||
@ -381,7 +377,7 @@ function M.init()
|
|||||||
local node_update = node_update_queue:get()
|
local node_update = node_update_queue:get()
|
||||||
local node = replicate.main_scene:GetNode(node_update.node_id)
|
local node = replicate.main_scene:GetNode(node_update.node_id)
|
||||||
log:verbose("Node update #"..
|
log:verbose("Node update #"..
|
||||||
#node_update_queue.queue..
|
node_update_queue:get_length()..
|
||||||
" (f="..(math.floor(f*100)/100)..""..
|
" (f="..(math.floor(f*100)/100)..""..
|
||||||
", fw="..(math.floor(fw*100)/100)..")"..
|
", fw="..(math.floor(fw*100)/100)..")"..
|
||||||
": "..node:GetName())
|
": "..node:GetName())
|
||||||
@ -394,10 +390,10 @@ function M.init()
|
|||||||
did_update = true
|
did_update = true
|
||||||
else
|
else
|
||||||
log:verbose("Poked update #"..
|
log:verbose("Poked update #"..
|
||||||
#node_update_queue.queue..
|
node_update_queue:get_length()..
|
||||||
" (f="..(math.floor((f or -1)*100)/100)..""..
|
" (f="..(math.floor((f or -1)*100)/100)..""..
|
||||||
", fw="..(math.floor((fw or -1)*100)/100)..")")
|
", fw="..(math.floor((fw or -1)*100)/100)..")")
|
||||||
node_update_queue.queue = {}
|
--node_update_queue.queue = {} -- For testing
|
||||||
end
|
end
|
||||||
-- Check this at the end of the loop so at least one is handled
|
-- Check this at the end of the loop so at least one is handled
|
||||||
if not did_update or buildat.get_time_us() >= stop_at_us then
|
if not did_update or buildat.get_time_us() >= stop_at_us then
|
||||||
|
@ -6,10 +6,53 @@ local log = buildat.Logger("__client/api")
|
|||||||
buildat.connect_server = __buildat_connect_server
|
buildat.connect_server = __buildat_connect_server
|
||||||
buildat.extension_path = __buildat_extension_path
|
buildat.extension_path = __buildat_extension_path
|
||||||
buildat.get_time_us = __buildat_get_time_us
|
buildat.get_time_us = __buildat_get_time_us
|
||||||
|
buildat.SpatialUpdateQueue = __buildat_SpatialUpdateQueue
|
||||||
|
|
||||||
buildat.safe.disconnect = __buildat_disconnect
|
buildat.safe.disconnect = __buildat_disconnect
|
||||||
buildat.safe.get_time_us = __buildat_get_time_us
|
buildat.safe.get_time_us = __buildat_get_time_us
|
||||||
|
|
||||||
|
buildat.safe.SpatialUpdateQueue = function()
|
||||||
|
local internal = __buildat_SpatialUpdateQueue()
|
||||||
|
return {
|
||||||
|
update = function(self, ...)
|
||||||
|
return internal:update(...)
|
||||||
|
end,
|
||||||
|
set_p = function(self, ...)
|
||||||
|
return internal:set_p(...)
|
||||||
|
end,
|
||||||
|
put = function(self, safe_p, near_weight, near_trigger_d,
|
||||||
|
far_weight, far_trigger_d, value)
|
||||||
|
if not getmetatable(safe_p) or
|
||||||
|
getmetatable(safe_p).type_name ~= "Vector3" then
|
||||||
|
error("p is not a sandboxed Vector3 instance")
|
||||||
|
end
|
||||||
|
p = getmetatable(safe_p).unsafe
|
||||||
|
return internal:put(p, near_weight, near_trigger_d,
|
||||||
|
far_weight, far_trigger_d, value)
|
||||||
|
end,
|
||||||
|
get = function(self, ...)
|
||||||
|
return internal:get(...)
|
||||||
|
end,
|
||||||
|
peek_next_f = function(self, ...)
|
||||||
|
return internal:peek_next_f(...)
|
||||||
|
end,
|
||||||
|
peek_next_fw = function(self, ...)
|
||||||
|
return internal:peek_next_fw(...)
|
||||||
|
end,
|
||||||
|
get_length = function(self, ...)
|
||||||
|
return internal:get_length(...)
|
||||||
|
end,
|
||||||
|
set_p = function(self, safe_p)
|
||||||
|
if not getmetatable(safe_p) or
|
||||||
|
getmetatable(safe_p).type_name ~= "Vector3" then
|
||||||
|
error("p is not a sandboxed Vector3 instance")
|
||||||
|
end
|
||||||
|
p = getmetatable(safe_p).unsafe
|
||||||
|
internal:set_p(p)
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
function buildat.safe.set_simple_voxel_model(safe_node, w, h, d, safe_buffer)
|
function buildat.safe.set_simple_voxel_model(safe_node, w, h, d, safe_buffer)
|
||||||
if not getmetatable(safe_node) or
|
if not getmetatable(safe_node) or
|
||||||
getmetatable(safe_node).type_name ~= "Node" then
|
getmetatable(safe_node).type_name ~= "Node" then
|
||||||
|
@ -10,12 +10,14 @@ namespace lua_bindings {
|
|||||||
extern void init_misc(lua_State *L);
|
extern void init_misc(lua_State *L);
|
||||||
extern void init_cereal(lua_State *L);
|
extern void init_cereal(lua_State *L);
|
||||||
extern void init_voxel(lua_State *L);
|
extern void init_voxel(lua_State *L);
|
||||||
|
extern void init_spatial_update_queue(lua_State *L);
|
||||||
|
|
||||||
void init(lua_State *L)
|
void init(lua_State *L)
|
||||||
{
|
{
|
||||||
init_misc(L);
|
init_misc(L);
|
||||||
init_cereal(L);
|
init_cereal(L);
|
||||||
init_voxel(L);
|
init_voxel(L);
|
||||||
|
init_spatial_update_queue(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace lua_bindingss
|
} // namespace lua_bindingss
|
||||||
|
326
src/lua_bindings/spatial_update_queue.cpp
Normal file
326
src/lua_bindings/spatial_update_queue.cpp
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
// Copyright 2014 Perttu Ahola <celeron55@gmail.com>
|
||||||
|
#include "lua_bindings/util.h"
|
||||||
|
#include "core/log.h"
|
||||||
|
#include <tolua++.h>
|
||||||
|
#include <Vector3.h>
|
||||||
|
#include <list>
|
||||||
|
#include <algorithm>
|
||||||
|
#define MODULE "lua_bindings"
|
||||||
|
|
||||||
|
#define DEF_METHOD(name){\
|
||||||
|
lua_pushcfunction(L, l_##name);\
|
||||||
|
lua_setfield(L, -2, #name);\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_TOLUA_STUFF(result_name, index, type)\
|
||||||
|
if(!tolua_isusertype(L, index, #type, 0, &tolua_err)){\
|
||||||
|
tolua_error(L, __PRETTY_FUNCTION__, &tolua_err);\
|
||||||
|
return 0;\
|
||||||
|
}\
|
||||||
|
type *result_name = (type*)tolua_tousertype(L, index, 0);
|
||||||
|
#define TRY_GET_TOLUA_STUFF(result_name, index, type)\
|
||||||
|
type *result_name = nullptr;\
|
||||||
|
if(tolua_isusertype(L, index, #type, 0, &tolua_err)){\
|
||||||
|
result_name = (type*)tolua_tousertype(L, index, 0);\
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just do this; Urho3D's stuff doesn't really clash with anything in buildat
|
||||||
|
using namespace Urho3D;
|
||||||
|
|
||||||
|
namespace lua_bindings {
|
||||||
|
|
||||||
|
struct SpatialUpdateQueue
|
||||||
|
{
|
||||||
|
struct Value { // Describes an update
|
||||||
|
ss_ type;
|
||||||
|
uint32_t node_id = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Item { // Queue item
|
||||||
|
Vector3 p = Vector3(0, 0, 0);
|
||||||
|
Value value;
|
||||||
|
float near_weight = -1.0f;
|
||||||
|
float near_trigger_d = -1.0f;
|
||||||
|
float far_weight = -1.0f;
|
||||||
|
float far_trigger_d = -1.0f;
|
||||||
|
float f = -1.0f;
|
||||||
|
float fw = -1.0f;
|
||||||
|
|
||||||
|
bool operator>(const Item &other) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector3 m_p;
|
||||||
|
Vector3 m_queue_oldest_p;
|
||||||
|
size_t m_queue_length = 0; // GCC std::list's size() is O(n)
|
||||||
|
std::list<Item> m_queue;
|
||||||
|
std::list<Item> m_old_queue;
|
||||||
|
|
||||||
|
void update(int max_operations)
|
||||||
|
{
|
||||||
|
if(m_old_queue.empty())
|
||||||
|
return;
|
||||||
|
log_d(MODULE, "SpatialUpdateQueue(): Items in old queue: %zu",
|
||||||
|
m_old_queue.size());
|
||||||
|
for(int i=0; i<max_operations; i++){
|
||||||
|
if(m_old_queue.empty())
|
||||||
|
break;
|
||||||
|
Item &item = m_old_queue.back();
|
||||||
|
put_item(item);
|
||||||
|
m_old_queue.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_p(const Vector3 &p)
|
||||||
|
{
|
||||||
|
m_p = p;
|
||||||
|
if(m_old_queue.empty() && (m_p - m_queue_oldest_p).Length() > 20){
|
||||||
|
m_queue_length = 0;
|
||||||
|
m_old_queue.swap(m_queue);
|
||||||
|
m_queue_oldest_p = m_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_item(Item &item)
|
||||||
|
{
|
||||||
|
if(item.near_trigger_d == -1.0f && item.far_trigger_d == -1.0f)
|
||||||
|
throw Exception("Item has neither trigger");
|
||||||
|
float d = (item.p - m_p).Length();
|
||||||
|
item.f = -1.0f;
|
||||||
|
item.fw = -1.0f;
|
||||||
|
if(item.near_trigger_d != -1.0f){
|
||||||
|
float f_near = d / item.near_trigger_d;
|
||||||
|
float fw_near = f_near / item.near_weight;
|
||||||
|
if(item.fw == -1.0f || (fw_near < item.fw &&
|
||||||
|
(item.f == -1.0f || f_near < item.f))){
|
||||||
|
item.f = f_near;
|
||||||
|
item.fw = fw_near;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(item.far_trigger_d != -1.0f){
|
||||||
|
float f_far = item.far_trigger_d / d;
|
||||||
|
float fw_far = f_far / item.far_weight;
|
||||||
|
if(item.fw == -1.0f || (fw_far < item.fw &&
|
||||||
|
(item.f == -1.0f || f_far < item.f))){
|
||||||
|
item.f = f_far;
|
||||||
|
item.fw = fw_far;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(item.f == -1.0f || item.fw == -1.0f)
|
||||||
|
throw Exception("item.f == -1.0f || item.fw == -1.0f");
|
||||||
|
|
||||||
|
auto it = std::lower_bound(m_queue.begin(), m_queue.end(),
|
||||||
|
item, std::greater<Item>()); // position in descending order
|
||||||
|
m_queue.insert(it, item);
|
||||||
|
m_queue_length++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void put(const Vector3 &p, float near_weight, float near_trigger_d,
|
||||||
|
float far_weight, float far_trigger_d, const Value &value)
|
||||||
|
{
|
||||||
|
Item item;
|
||||||
|
item.p = p;
|
||||||
|
item.near_weight = near_weight;
|
||||||
|
item.near_trigger_d = near_trigger_d;
|
||||||
|
item.far_weight = far_weight;
|
||||||
|
item.far_trigger_d = far_trigger_d;
|
||||||
|
item.value = value;
|
||||||
|
put_item(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty()
|
||||||
|
{
|
||||||
|
return m_queue.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop()
|
||||||
|
{
|
||||||
|
m_queue.pop_back();
|
||||||
|
m_queue_length--;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value& get_value()
|
||||||
|
{
|
||||||
|
if(m_queue.empty())
|
||||||
|
throw Exception("SpatialUpdateQueue::get_value(): Empty");
|
||||||
|
return m_queue.back().value;
|
||||||
|
}
|
||||||
|
|
||||||
|
float get_f()
|
||||||
|
{
|
||||||
|
if(m_queue.empty())
|
||||||
|
throw Exception("SpatialUpdateQueue::get_f(): Empty");
|
||||||
|
return m_queue.back().f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float get_fw()
|
||||||
|
{
|
||||||
|
if(m_queue.empty())
|
||||||
|
throw Exception("SpatialUpdateQueue::get_fw(): Empty");
|
||||||
|
return m_queue.back().fw;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t get_length()
|
||||||
|
{
|
||||||
|
return m_queue_length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool SpatialUpdateQueue::Item::operator>(const Item &other) const
|
||||||
|
{
|
||||||
|
if(f > 1.0f && other.f <= 1.0f)
|
||||||
|
return true;
|
||||||
|
if(f <= 1.0f && other.f > 1.0f)
|
||||||
|
return false;
|
||||||
|
return fw > other.fw;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LuaSUQ
|
||||||
|
{
|
||||||
|
static constexpr const char *class_name = "SpatialUpdateQueue";
|
||||||
|
SpatialUpdateQueue internal;
|
||||||
|
|
||||||
|
static int gc_object(lua_State *L){
|
||||||
|
delete *(LuaSUQ**)(lua_touserdata(L, 1));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int l_update(lua_State *L){
|
||||||
|
LuaSUQ *o = internal_checkobject(L, 1);
|
||||||
|
int max_operations = luaL_checkinteger(L, 2);
|
||||||
|
o->internal.update(max_operations);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int l_set_p(lua_State *L){
|
||||||
|
LuaSUQ *o = internal_checkobject(L, 1);
|
||||||
|
tolua_Error tolua_err;
|
||||||
|
GET_TOLUA_STUFF(p, 2, Vector3);
|
||||||
|
o->internal.set_p(*p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int l_put(lua_State *L){
|
||||||
|
LuaSUQ *o = internal_checkobject(L, 1);
|
||||||
|
tolua_Error tolua_err;
|
||||||
|
GET_TOLUA_STUFF(p, 2, Vector3);
|
||||||
|
float near_weight = (lua_type(L, 3) == LUA_TNIL) ?
|
||||||
|
-1.0f : luaL_checknumber(L, 3);
|
||||||
|
float near_trigger_d = (lua_type(L, 4) == LUA_TNIL) ?
|
||||||
|
-1.0f : luaL_checknumber(L, 4);
|
||||||
|
float far_weight = (lua_type(L, 5) == LUA_TNIL) ?
|
||||||
|
-1.0f : luaL_checknumber(L, 5);
|
||||||
|
float far_trigger_d = (lua_type(L, 6) == LUA_TNIL) ?
|
||||||
|
-1.0f : luaL_checknumber(L, 6);
|
||||||
|
luaL_checktype(L, 7, LUA_TTABLE);
|
||||||
|
SpatialUpdateQueue::Value value;
|
||||||
|
lua_getfield(L, -1, "type");
|
||||||
|
value.type = luaL_checkstring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_getfield(L, -1, "node_id");
|
||||||
|
value.node_id = luaL_checkinteger(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
o->internal.put(*p, near_weight, near_trigger_d,
|
||||||
|
far_weight, far_trigger_d, value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static int l_get(lua_State *L){
|
||||||
|
LuaSUQ *o = internal_checkobject(L, 1);
|
||||||
|
if(o->internal.empty())
|
||||||
|
return 0;
|
||||||
|
SpatialUpdateQueue::Value &value = o->internal.get_value();
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushstring(L, value.type.c_str());
|
||||||
|
lua_setfield(L, -2, "type");
|
||||||
|
lua_pushinteger(L, value.node_id);
|
||||||
|
lua_setfield(L, -2, "node_id");
|
||||||
|
o->internal.pop();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int l_peek_next_f(lua_State *L){
|
||||||
|
LuaSUQ *o = internal_checkobject(L, 1);
|
||||||
|
if(o->internal.empty())
|
||||||
|
return 0;
|
||||||
|
float v = o->internal.get_f();
|
||||||
|
lua_pushnumber(L, v);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int l_peek_next_fw(lua_State *L){
|
||||||
|
LuaSUQ *o = internal_checkobject(L, 1);
|
||||||
|
if(o->internal.empty())
|
||||||
|
return 0;
|
||||||
|
float v = o->internal.get_fw();
|
||||||
|
lua_pushnumber(L, v);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int l_get_length(lua_State *L){
|
||||||
|
LuaSUQ *o = internal_checkobject(L, 1);
|
||||||
|
int l = o->internal.get_length();
|
||||||
|
lua_pushinteger(L, l);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LuaSUQ* internal_checkobject(lua_State *L, int narg){
|
||||||
|
luaL_checktype(L, narg, LUA_TUSERDATA);
|
||||||
|
void *ud = luaL_checkudata(L, narg, class_name);
|
||||||
|
if(!ud) luaL_typerror(L, narg, class_name);
|
||||||
|
return *(LuaSUQ**)ud;
|
||||||
|
}
|
||||||
|
static int l_create(lua_State *L){
|
||||||
|
LuaSUQ *o = new LuaSUQ();
|
||||||
|
*(void**)(lua_newuserdata(L, sizeof(void*))) = o;
|
||||||
|
luaL_getmetatable(L, class_name);
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static void register_metatable(lua_State *L){
|
||||||
|
lua_newtable(L);
|
||||||
|
int method_table_L = lua_gettop(L);
|
||||||
|
luaL_newmetatable(L, class_name);
|
||||||
|
int metatable_L = lua_gettop(L);
|
||||||
|
|
||||||
|
// hide metatable from Lua getmetatable()
|
||||||
|
lua_pushliteral(L, "__metatable");
|
||||||
|
lua_pushvalue(L, method_table_L);
|
||||||
|
lua_settable(L, metatable_L);
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__index");
|
||||||
|
lua_pushvalue(L, method_table_L);
|
||||||
|
lua_settable(L, metatable_L);
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__gc");
|
||||||
|
lua_pushcfunction(L, gc_object);
|
||||||
|
lua_settable(L, metatable_L);
|
||||||
|
|
||||||
|
lua_pop(L, 1); // drop metatable_L
|
||||||
|
|
||||||
|
// fill method_table_L
|
||||||
|
DEF_METHOD(update);
|
||||||
|
DEF_METHOD(set_p);
|
||||||
|
DEF_METHOD(put);
|
||||||
|
DEF_METHOD(get);
|
||||||
|
DEF_METHOD(peek_next_f);
|
||||||
|
DEF_METHOD(peek_next_fw);
|
||||||
|
DEF_METHOD(get_length);
|
||||||
|
|
||||||
|
// drop method_table_L
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int l_SpatialUpdateQueue(lua_State *L)
|
||||||
|
{
|
||||||
|
return LuaSUQ::l_create(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_spatial_update_queue(lua_State *L)
|
||||||
|
{
|
||||||
|
#define DEF_BUILDAT_FUNC(name){ \
|
||||||
|
lua_pushcfunction(L, l_##name); \
|
||||||
|
lua_setglobal(L, "__buildat_" #name); \
|
||||||
|
}
|
||||||
|
LuaSUQ::register_metatable(L);
|
||||||
|
|
||||||
|
DEF_BUILDAT_FUNC(SpatialUpdateQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lua_bindingss
|
||||||
|
// vim: set noet ts=4 sw=4:
|
||||||
|
|
@ -4,6 +4,7 @@
|
|||||||
#include "core/types.h"
|
#include "core/types.h"
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <lua.h>
|
#include <lua.h>
|
||||||
|
#include <lauxlib.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace lua_bindings
|
namespace lua_bindings
|
||||||
|
Loading…
x
Reference in New Issue
Block a user