C# Events in Lua

Started by
11 comments, last by ddboarm 14 years, 7 months ago
I am working on a rough prototype Object Creation Engine that is setup up dynamically by Lua script. Initially, I thought this would be easy. But I soon found out different. While enjoyable overall, it has been a challenge trying to convert C snippets to equivalent C#(based on fairly limited "accurate" sources). Besides, many examples only include what the author considers advanced. Here's why this is so drawn out - I want others to understand and possibly implement my procedures. If I'm on the right track, lemme know...and if I'm wrong, I'll expect explanations :). This is a kind of pseudo code I do: Given:

// language = C#
// lua = new LuaInterface
// event Object_OnCreate
// event Button_OnClick
// txtArray = Control.TextBox {multiline = true}


Object_OnCreate(sender, e)
{
    lua.RegisterObject("event.sender", sender);
    lua.RegisterObject("event.evkey", e.Key);
    lua.RegisterObject("event.evobj", e.Object);
}

Button_OnClick(sender, e)
{
    LuaInterface.LuaTable _LTable = (LuaInterface.LuaTable)lua[path];
    string[] arrTable = new string[_LTable.Keys.Count];
    int ndx = 0;

    foreach (DictionaryEntry element in _LTable)
    {
       string sVal;
       sVal = element.Key.ToString() + " = " + element.Value.ToString() + '\n';
       arrTable.SetValue(sVal, ndx++);
    }
    txtArray.Clear();

    foreach (object element in arrArray)
    {
       txtArray.AppendText(element.ToString());
    }
}

// LuaSnippet

event = {}

event.sender = ""
event.evkey = ""
event.evobj = ""

So, the Object is created and fires off a delegate event I wrote. As you can see, I register the object with a Lua table named "event". This was to ensure that my Lua function would receive all the correct information when I call it from C#: Given:

// language C#
lua.DoString("event:Engine_OnObjectCreated()");

// LuaSnippet
omni = {}

function event:Engine_OnObjectCreated()
    sKey = { event.evkey}
    omni[sKey] = {}
    omni[sKey].Obj = event.evobj
end

With "omni" being a global table, I am assuming that I can add a new Key [sKey] to the "omni" table, and even a new Key ["Obj"] with the value referencing the newly created object. This process has evolved from fruitless searches on finding an example of getting a Lua function to trigger as a direct result of an event. I know there has got to be an easier way to call this On_Event_Function in Lua. Here is the pseudo code equivalent to I'm looking for: Given:

// language C#
Button.Click += new OnButtonClickEventHandler(
     Lua.DoScript("event:Engine_OnObjectCreated()"));

// LuaSnippet
function event:Engine_OnObjectCreated(sender, e)
    //c#
    {
      txtArray.AppendText(e.Key + "= " e.Value + '\n');
    }
end

Obviously, the C# inside the LuaSnippet is just my way of capturing a message through Lua calling a C# function. Amazing to me, I was able to trace four things in the text results, therefore tracing the object creation, verifying proper reference, and even the type of object through my C# debugger. In my quest to achieve 1 thing, I believe I have succeeded in achieving two things. First, I succeeded in my mission of firing an event in Lua with all the necessary parts -- albeit, not the most efficient method, I am sure. Second, I have a quality testing widget to understand how Lua works and that the table has the correct references. And this, my friends, is what I wanted to share with you all (err, um, y'all for those of us in Texas). After all that, my question really comes down to "Is there a better way for an event to hook up with a Lua function?" Later (and anxiously awaiting replies)... [Edited by - ddboarm on September 11, 2009 4:59:45 PM]
Advertisement
The listing above is only good for the first object created because I was able to put:

{
Object.Created += new ObjectCreatedEventHandler(//C# func)
}

in my main body of code where Object is constructed. Without being able to put the full event handler in my Lua script, this is going to be much more difficult -- or I will redesign the entire system, possibly scrapping Lua all together.
Evidently I'm missing something...can't figure it out. I have totally reworked what I had done in my original post.

C#:
public class foo
{
public foo()
{
debug.print("hello");
}
}

I want Lua to create the foo object -- no problem. However, I am looking to fire an event when the object is created (foo_OnCreate).

Lua:
luanet.load_assembly("Program");
foo = luanet.import_type("Program.foo");

-- //NOTE: Debug() is a registered func in C#//
Debug("***** About to Initialize Cosmos *****")

function foo_OnCreate(sender,args)
Debug("foo Created!!!")
end

OnCreate = foo.OnCosmosCreate:Add(foo_OnCreate())

foo = foo()

In my main program class I have created my public delegate, event, and invoker for the foo_OnCreate event. The event fires and I get the message in my Immediate Output window "Hello", then "foo Created!!!". But, then I get a message from Lua:

invalid arguments to method: RegisterEventHandler.Add

I know that if I try 'Debug(sender:ToString().." foo Created!!!")' in the foo_OnCreate event, I get an error that the local 'sender' is nil.

Any help or suggestions would be very much appreciated.

[Edited by - ddboarm on September 11, 2009 5:44:17 PM]
Okay...I get the idea that there really are not many C# users on this forum. And some of you may think I like talking to myself, but at least I've been able to glean a lot of information from even the C users regarding Lua scripting.

Frankly, I've been going about this entirely the wrong way. After about 5 iterations, starting from scratch each time, I have finally discovered the best method for using Lua. While my Lua scripts can easily be more aware of objects, instancing, events, etc., I have redirected my focus for Lua. I am using Lua to quickly and dynamically build tables that hold parameters to pass to an instanced class (instantiated within my C# engine which is readily aware, and capable, of handling events without a lot of work on my part).

Whew!!! Aside from the project above...if anyone is interested in using my C# Lua engine, let me know. I have developed it as a class library to be interfaced from other Console or Window apps. It simply provides a friendlier atmosphere with comments for usage. It also includes a few options for grabbing or pushing scripted tables, and parsing into 'keyed' string arrays (i.e. arrElement[0]="KeyName|KeyVal"). I will be adding a function that allows my engine to build a 'keyed' string array and push to a Lua script for saving values. That will be a challenge, but I know I will need some functionality like that as object values change over time once they are in use.

Anyway...if anyone has any thoughts or ramblings, I'd like to read 'em.
I use C# with Lua, but I use Lua Interface, and have my own event system in my engine that has the ability to propagate events to C#.

I wouldnt consider myself an expert on c# delegates and such, but i use LuaInterface for my Lua to C# interaction.

Maybe check out what they are doing?

------------------------------

redwoodpixel.com

Maybe out of topic, but why bother using Lua with .Net when you can use .Net language as scripting ? In my framework, I use C# for scripting. Using Reflection it's really easy. The good news is that you can use any .Net language (C#, VB.Net, IronPython, F#, J"...).
- Iliak -
[ ArcEngine: An open source .Net gaming framework ]
[ Dungeon Eye: An open source remake of Eye of the Beholder II ]
Quote:Original post by iliak
Maybe out of topic, but why bother using Lua with .Net when you can use .Net language as scripting ? In my framework, I use C# for scripting. Using Reflection it's really easy. The good news is that you can use any .Net language (C#, VB.Net, IronPython, F#, J"...).


Because the lua VM is directly embedded in my engine, and it allows direct interaction between .NET and my game logic environment via lua. Since my game logic is in lua, i can manipulate my game logic with a C# editor.

EDIT: Also it should be noted that were i to ship a game, C# would not be bundled since it only implements the editor.

------------------------------

redwoodpixel.com

Quote:Original post by AverageJoeSSU
I use C# with Lua, but I use Lua Interface, and have my own event system in my engine that has the ability to propagate events to C#.

I wouldnt consider myself an expert on c# delegates and such, but i use LuaInterface for my Lua to C# interaction.

Maybe check out what they are doing?


If I understand you correctly, you create events in your Lua Interface code? I am using the LuaInterface (.DLLs) as well. What I wanted originally was, for instance:

- object created in C#
- Lua script captures event

I have shifted my thinking to something a little different:
- object created in C#
- C# (thru a custom delegate event handler, event, and invoker) raises the event and performs a lua.DoString("myFunc")

It is actually much cleaner that way and my scripts are only tasked with the job of passing object parameters to the application when the application asks for them (via the event handler). One of the neat things I did, as I mentioned in an earlier post, was create an event handler inside my LuaEngine where my script performs a PushTable(MyTable{}). The event argument passes an array of the table derived from the DictionaryEntry(k,v) datatype...such that an array element contains the string "KeyName|KeyValue".

How are you interfacing your C#/Lua events with your C# app?

Thanks for the response...
Quote:Original post by iliak
Maybe out of topic, but why bother using Lua with .Net when you can use .Net language as scripting ? In my framework, I use C# for scripting. Using Reflection it's really easy. The good news is that you can use any .Net language (C#, VB.Net, IronPython, F#, J"...).


There are many schools of thought on why one would choose Lua for scripting over say the C# Script. But I have 2 specific reasons for choosing Lua.

- Popularity: I am choosing Lua scripts because of popularity. I want to attract gamers for creating content. I know that not all gamers are developers, so I need something that a lot of gamers could be familiar with (the World of Warcraft crowd for instance).

- Implementation: I know that implementing the C# Script could be very easy and non-problematic in most cases. I am, however, using the VS Express app. I have tried downloading and installing the C# Script. Immediately, I ran into problems with my IDE randomly crashing at the most inopportune moment - at one time causing me to think I might have lost over 350 lines of code. Since I removed/uninstalled the .DLLs, I have no more problems...and I reverted to my first reason for choosing Lua.

Thank you for your response to this thread :)
Quote:Original post by ddboarm
Quote:Original post by AverageJoeSSU
I use C# with Lua, but I use Lua Interface, and have my own event system in my engine that has the ability to propagate events to C#.

I wouldnt consider myself an expert on c# delegates and such, but i use LuaInterface for my Lua to C# interaction.

Maybe check out what they are doing?


If I understand you correctly, you create events in your Lua Interface code? I am using the LuaInterface (.DLLs) as well. What I wanted originally was, for instance:

- object created in C#
- Lua script captures event

I have shifted my thinking to something a little different:
- object created in C#
- C# (thru a custom delegate event handler, event, and invoker) raises the event and performs a lua.DoString("myFunc")

It is actually much cleaner that way and my scripts are only tasked with the job of passing object parameters to the application when the application asks for them (via the event handler). One of the neat things I did, as I mentioned in an earlier post, was create an event handler inside my LuaEngine where my script performs a PushTable(MyTable{}). The event argument passes an array of the table derived from the DictionaryEntry(k,v) datatype...such that an array element contains the string "KeyName|KeyValue".

How are you interfacing your C#/Lua events with your C# app?

Thanks for the response...


My Events are from an event system entirely implemented in Lua, If you go to the lua programming gems site you can find it. The guy who wrote the chapter says it is similar to how C# does events.

I basically pass the lua_state* from my engine dll up to LuaInterface, using the other constructor that takes an IntPtr which is a lua state.

that lua_state* contains the API from my engine for lua to create and manipulate game objects / fire and subscribe to events.



------------------------------

redwoodpixel.com

This topic is closed to new replies.

Advertisement