lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


So, you want all scripts to play the same role? Otherwise they would have different function names naturally. Then, you can create a table with functions corresponding to that role / event, as I proposed.



function_name = function_name or {}
table.insert(function_name, funciton()
 ...
end)

Then, you'll have to call each function in that table from your application.

A more convenient way is to make special support for that kind of things, like I did. In my case you can write functions as usually, but many functions may have the same name:

function events.function_name()
 ...
end

And call them as usually:
lua_getglobal(L, "events");
lua_getfield(L, -1, "function_name");
lua_pcall(L, 0, 0, 0);
lua_pop(L, 1);

events table keeps all functions of the same name in a table and makes them easy to call and assign. Below is the part of code from my project that creates the events table. Note that I've put some functions into local variables. Like "debug_getinfo" that is set to "debug.getinfo". It also uses two functions specific to my projects. They are pcall2 and coroutine_resume2. They work the same as pcall and coroutine.resume, but show an error message if the call failed.

--------- events

local function FunctionFile(f)
if type(f) == "number" then
 f = f + 1
end
return debug_getinfo(f, "S").short_src
end
debug.FunctionFile = FunctionFile

local function make_events(table)
local t = {}

local function index(_, a)
 local function docall(kind, ...)
  local f = t[a]
  if f then
   local ok = true
   local tmp, ret
   if type(f) == "table" then
    for i = 1, #f do
     local v = f[i]
     if f ~= nil then
      if kind == 2 then
       ok, tmp = coroutine_resume2(coroutine_create(v), ...)
      elseif kind == 1 then
       ok, tmp = pcall2(v, ...)
      else
       tmp = v(...)
      end
      if ok and tmp ~= nil then
       ret = tmp
      end
     end
    end
   else
    ret = f(...)
   end
   return ret
  end
 end

 local function call(...)
  return docall(...)
 end
 local function _pcalls(...)
  return docall(1, ...)
 end
 local function _pcall(...)
  local ok, ret = pcall2(docall, 0, ...)
  if ok then
   return ret
  end
 end
 local function _cocalls(...)
  return docall(2, ...)
 end
 local function _cocall(...)
  local ok, ret = coroutine_resume2(coroutine_create(docall), 0, ...)
  if ok then
   return ret
  end
 end
 local function add(func)
  local f = t[a]
  if f == nil then
   t[a] = func
  elseif type(f) == "table" then
   table_insert(f, func)
  else
   t[a] = {f, func}
  end
 end
 local function remove(func)
  local f = t[a]
  if f == func then
   t[a] = nil
  elseif f and type(f) == "table" then
   local i = 1
   local v = f[1]
   while v do
    if v == func then
     if i == 1 and f[2] == nil then
      t[a] = nil
     else
      table_remove(f, i)
     end
     return v
    end
    i = i+1
    v = f[i]
   end
  end
 end
 local function exists(func)
  local f = t[a]
  if func then
   if f == func then
    return true
   elseif f and type(f) == "table" then
    for _, v in ipairs(f) do
     if v == func then
      return true
     end
    end
   end
   return false
  else
   return f ~= nil
  end
 end

return setmetatable({add = add, Add = add, remove = remove, Remove = remove, exists = exists, Exists = exists, pcall = _pcall, cocall = _cocall, cocalls = _cocalls}, {__call = call})
end

local function newindex(_, a, v)
 f = t[a]
 if f then
  if type(f) == "table" then
   table_insert(f, v)
  else
   t[a] = {f, v}
  end
 else
  t[a] = v
 end
end

table = table or {}

function table.RemoveFile(f)
 f = f or FunctionFile(2)
 for k, v in pairs(t) do
  if type(v) == "table" then
   local n = 0
   for i = #v, 1, -1 do
    if FunctionFile(v[i]) == f then
     table_remove(v, i)
    else
     n = n + 1
    end
   end
   if n == 0 then
    t[k] = nil
   end
  elseif FunctionFile(v) == f then
   t[k] = nil
  end
 end
end

function table.RemoveAll()
 t = {}
end

return setmetatable(table, {__index = index, __newindex = newindex})
end

events = make_events{new = make_events}













----- Original Message ----- From: zweifel
To: Lua list
Sent: Wednesday, September 23, 2009 5:36 PM
Subject: Re: Lua Performance questions



I see.. so I can load all scripts at the beginning or at least be sure to load at least one time before calling the function.

But I have to be sure that every script has a different function_name, otherwise I would be unable to call it. Is not it? This is not big problem though...