lua-users home
lua-l archive

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


Ok, take a look at the following lua script:

-- Funcion to be executed later
function SayHello()
  myNewNpc_temp:SayRoom("Hello everybody!");
end

-- Create a new NPC and store it in "myNewNpc"
local myNewNpc_temp := NPCManager.New("Bob");

-- Create a timer to run the SayHello function in 10 seconds
local eventId = mud:onTimer(10, SayHello);

-- end of lua script



In the above example, the NPC is created (myNewNpc_temp) and a timer
is created.  (eg. the function SayHello() is stored in the registry) 
When the timer executes and the host program runs the SayHello
function, it no longer knows about myNewNpc_temp.

It was mentioned above that variables are defaulted to being global
unless otherwise specified.  I think it would be a bad idea to have a
global variable called "myNewNpc".  I'd like everything to be nice and
local but I think if I use only local variables then when my timer
functions (eg. SayHello() ) are stored then it no longer knows about
my previously declared local variables...

Does that make more sense?

Thanks again for helping me!


On 12/12/05, Pavel Antokolsky aka Zigmar <zigmar@gmail.com> wrote:
> I'm not sure I completly understand the issue with object creation.
> Can you expain, please?
>
> On 12/12/05, John Klimek <jklimek@gmail.com> wrote:
> > Thanks for the examples!
> >
> > So it seems like I can't do what I wanted above because suppose my
> > script was run twice and "myNewNpc" was created twice?  (once from
> > each script)
> >
> > Whats the best way to handle this?  Even the example above wouldn't
> > work (local myNewNpc = NPCManager.GetNPC("Bob")) because suppose that
> > two NPC's were named Bob?
> >
> >
> >
> > On 12/12/05, Pavel Antokolsky aka Zigmar <zigmar@gmail.com> wrote:
> > > On 12/12/05, John Klimek <jklimek@gmail.com> wrote:
> > > > Ok, I understand that I have to store this function in the Lua
> > > > registry, but how would I do this from my C/Delphi function?  Can you
> > > > give me a code example?
> > > See the attachment. I've created a simple app (with C++) that allows
> > > to register some hypothetic event handler and later calls to
> > > registered function.
> > >
> > > > Also, lets say I have the following code:
> > > >
> > > > -- Funcion to be executed later
> > > > function SayHello()
> > > >   myNewNpc:SayRoom("Hello everybody!");
> > > > end
> > > >
> > > > -- Create a new NPC and store it in "myNewNpc"
> > > > myNewNpc := NPCManager.New("Bob");
> > > >
> > > > -- Create a timer to run the SayHello function in 10 seconds
> > > > local eventId = mud:onTimer(10, SayHello);
> > > >
> > > > -- end of lua script
> > > >
> > > >
> > > > What would the code look like (in C/Delphi) for the onTimer function?
> > > > Also, if I store my function SayHello in the Lua registry and execute
> > > > it later, won't it lose the value of myNewNpc and then throw an error?
> > > >  Would I have to modify my function to something like this:
> > > No, you don't have to. A global variable are always visible and
> > > persistent - once you have declared it - it there until you remove it,
> > > even if the script body finished running. Actually lua-based ini files
> > > parsers - work line this - some variable are declared in script and
> > > host app exectues the script body, and read the global variables
> > > afterwards.
> > > Note the 'a' gloval variable in attached example.
> > >
> > > > function SayHello()
> > > >   myNewNpc = NPCManager.GetNPC("Bob");
> > > >   myNewNpc:SayRoom("Hello everybody!");
> > > > end
> > > Here you actually modify (or create) _global_ variable "myNewNpc". If
> > > you wanted to create local variable, you should have written:
> > >
> > > function SayHello()
> > >   local myNewNpc = NPCManager.GetNPC("Bob");
> > >   myNewNpc:SayRoom("Hello everybody!");
> > > end
> > >
> > >
> > > > On 12/11/05, Pavel Antokolsky aka Zigmar <zigmar@gmail.com> wrote:
> > > > > On 12/10/05, John Klimek <jklimek@gmail.com> wrote:
> > > > >
> > > > >  > Zigmar, can you explain what you mean when you say "register a
> > > > >  > function itself, not its name"?
> > > > >  Functions are first-class objects in lua, and therefore function can
> > > > > get another function as parameter, functions can be stored in
> > > > > variables, etc. So what I mean, as the function that registers event,
> > > > > can receive not the name of the function (which therefor must be
> > > > > global) but a function object itself. It allows you to pass local
> > > > > function, function stored in some tables or even anonymous function
> > > > > (as I wrote in example)
> > > > >
> > > > >  > For example, in your lua code you have:
> > > > >  > mud.onTimer(10, function() npc:say("Hello") end )
> > > > >  >
> > > > >  > It looks like mud is a table filled with cfunctions.  Am I right?
> > > > >  Yep. It probably some library filled with function that gives you a
> > > > > connectivity to your host application (mud server). For example
> > > > > queries about different statuses, registering/removing events,
> > > > > spawning monsters, etc.
> > > > >
> > > > >  > Furthermore it looks like you are calling this cfuntion (wherever
> > > > >  > mud.onTimer is mapped) and passing it a lua function parameter.  Am I
> > > > >  > right on this as well?
> > > > >  Exactly. onTimer is a function that registers user event and calls
> > > > > it with specific interval.
> > > > >
> > > > >  >  If so, how would you declare the cfunction
> > > > >  > onTimer that would handle this input?
> > > > >  Just like any other cfunction - you just handle the parameters on
> > > > > stack in appropriate way. The tricky thing is that you can non pop and
> > > > > store function object in C-app as you can do with strings. The
> > > > > function has to be stored inside lua state itself. To do this, you can
> > > > > use "registry".
> > > > >
> > > > >  >  Delphi examples are preferred
> > > > >  > but C/C++ will work too =)
> > > > >  Here is an excelent explanation, along with code examples
> > > > >  http://www.lua.org/pil/27.3.html
> > > > >
> > > > >  BTW, I  thought that it might be a good idea, that event registration
> > > > > function will return some kind of event id (integral or whatever), so
> > > > > it can be used later to remove that event notification.
> > > > >
> > > > >  For example:
> > > > >
> > > > >  local eventId = mud.onTimer(10, someFunc);
> > > > >  ....
> > > > >  mud.removeEvent(eventId); -- or maybe "removeTimerEvent"?
> > > > >  --from now on someFunc will not be called anymore
> > > > >
> > > > >
> > > > >  Also there should be some functionality to allow to reset all event
> > > > > notifications.
> > > > >
> > > > >
> > > > >  > Thanks!!
> > > > >  You are welcome :)
> > > > >
> > > > >  > On 12/9/05, Pavel Antokolsky aka Zigmar <zigmar@gmail.com> wrote:
> > > > >  > > Just an idea - I think it will be much more convinient and flexible to
> > > > >  > > register a function itself, not its name. Then, you can write
> > > > >  > > something like:
> > > > >  > >
> > > > >  > > -- Every ten seconds
> > > > >  > > mud.onTimer(10, function() npc:say("Hello") end )
> > > > >  > >
> > > > >  > > This system can be also extended to handle different events. For example:
> > > > >  > > mud:onRoomEnter("main", function(who,where) npc:say("Hello, " ..
> > > > > who.name) end )
> > > > >  > > it can be, for example, extended to handle rooms with masks
> > > > >  > > mud:onRoomEnter("dungeon_*",
> > > > >  > >    function(who, where)
> > > > >  > >        if where:name != "dungen_saferoom" then
> > > > >  > >            local monster = mud:spawn("monster",where)
> > > > >  > >            monter:attack(who)
> > > > >  > >        end
> > > > >  > >   end
> > > > >  > > )
> > > > >  > >
> > > > >  > > And so on... I can't even think of all possibilites with such system :)
> > >
> > > --
> > > Best regards,
> > > Zigmar
> > >
> > >
> > >
> >
>
>
> --
> Best regards,
> Zigmar
>