Welcome to our forums...

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed.

Forum Statistics

  • Forum Members:
  • Total Threads:
  • Total Posts: 1
There are 1 users currently browsing forums.
.Net Programming A powerful framework built by Microsoft to facilitate development in Windows platforms.

Reply
  #1  
Old 07-27-2008
cpf's Avatar
cpf cpf is offline
Hiiii
 
Join Date: Jun 2005
Location: Box 12 Site 5 RR1
Posts: 3,067
Rep Power: 9
cpf is on a distinguished road
LuaInterface Explained

Hi

I recently made a .net app (wiresim.com) that's main feature was scriptability. In fact, making your application scriptable is very good thing to do for your advanced users, and hopefully with this article, how to do that will be clear

When I first looked into adding scripting support to .net languages, the world seemed bleak, filled with overly complicated windows scripting hosts and the like...

Until I found LuaInterface!

Of course, all my troubles did not go away after that, I still had to figure out how to put this into my program Looking through the documentation included with LuaInterface, it has nice examples of running standalone scripts with very little 2-way interaction with their host. This is fine for some applications (lua just calls functions in the host, without the host calling functions in lua), but for my application, I needed full 2-way communication!

So, without recounting a journal of my path in figuring this out, here's a C# class I've made to help future users of LuaInterface. After the code block, I'll explain what stuff does. Ignore the "PHP code," I just want the highlighting. Also, when you see stuff like parentform.Log, that's just a function that logs errors, replace it with your app's.
PHP Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LuaInterface;
namespace wiresim
{
    public class 
LuaStuff
    
{
        public 
string path;
        public 
Lua lua=new Lua();
       
        private 
int retries 0;
        
        public 
LuaFunction FindFunc(string name){
            try
            {
                
LuaFunction retfunc this.lua.GetFunction(name);
                return 
retfunc;
            } catch (
Exception e){
                
this.parentent.parentform.Log(e.Messagetrue);
                return 
null;
            }

    }
        public 
void CallFunction(string name)
        {
            if (
FindFunc(name) == null)
            {
                return;
            }
            try
            {
                
LuaFunction retfunc this.lua.GetFunction(name);
                
retfunc.Call();

            }
            catch (
Exception e)
            {
                
this.parentent.parentform.Log(e.Messagetrue);
                
            }

        }
        public 
void runfileinthread()
        {
            try
            {
                
                
lua.DoFile(path);
                
               
            }
            catch (
Exception ex)
            {
                
retries++;
                if (
retries 10)
                {
                    
this.parentent.parentform.Log(ex.Messagetrue);
                    
this.parentent.parentform.Log("Lua actually *****ed up, probably a syntax error, check the console for more"true);
                
                }
                else
                {
                    
this.parentent.parentform.Log("Lua *****ed up, this is normal and has to detremental effects, lets try this again"false);
                    
runfileinthread();
                }
                
//MessageBox.Show("Compile Error!", "Script Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);

            
}
           

        }
       
    }

So, here's the explanation:
I first create a new Lua object, along with some variables to store the location of the lua script. Nothing really new there
PHP Code:
public LuaFunction FindFunc(string name){
            try
            {
                
LuaFunction retfunc this.lua.GetFunction(name);
                return 
retfunc;
            } catch (
Exception e){
                
this.parentent.parentform.Log(e.Messagetrue);
                return 
null;
            }

    } 
This function uses the GetFunction() method of LuaInterface.Lua, however instead of calling it, I just determine if an error is encountered getting the function object. If an error is encountered, it means that the function your named does not exist, so this function returns null. If it does exist (and therefore no error happen), the LuaFunction object is returned. Technically this and the next function really could be in one, but I like keeping the purposes seperate.
PHP Code:
public void CallFunction(string name)
        {
            if (
FindFunc(name) == null)
            {
                return;
            }
            try
            {
                
LuaFunction retfunc this.lua.GetFunction(name);
                
retfunc.Call();

            }
            catch (
Exception e)
            {
                
this.parentent.parentform.Log(e.Messagetrue);
                
            }

        } 
This is where the fun starts. This function is similar to the one above, however instead of just checking if the function exists, it calls the function (retfunc.Call()).
PHP Code:
public void runfileinthread()
        {
            try
            {
                
                
lua.DoFile(path);
                
               
            }
            catch (
Exception ex)
            {
                
retries++;
                if (
retries 10)
                {
                    
this.parentent.parentform.Log(ex.Messagetrue);
                    
this.parentent.parentform.Log("Syntax Error!"true);
                
                }
                else
                {
                    
this.parentent.parentform.Log("Recoverable Lua Error"false);
                    
runfileinthread();
                }
                

            }
           

        }
       
    } 
This is effectively a wrapper for the LuaInterface.Lua.DoFile() method, but it has error trapping built in, due do a bug I encountered with Lua. This bug was that, randomly, the lua.DoFile(path) command would fail with a generic error. Run the same command again, and the error would not happen This is a work around, and I'd recommend you first try removing it and seeing if you get the same issue. You'll note, however, that the number of retries is limited to 10, because the function never fails that many times in a row unless you have a syntax error.

Right about now you'll be thinking "great, I can call functions in Lua, but can Lua call functions in the host app?" Why yes, of course! And as an added bonus, it's incredibly easy to do!

To Export a variable (or native .net object!) to Lua:
Simply
PHP Code:
lua["variablename"]=variable 
Where lua is your instance of the LuaInterface.Lua object. variable can be anything, an array, object, int, windows form control, etc. If the object you exported has functions or properties, they can be accessed in lua via
PHP Code:
variablename:function(parameter,parameter
and
PHP Code:
variablename.property=value 
(where variablename is the name of your variable, function/property are the names of the function/property, and parameter/value is anything)
Note: You can read back that variable (or any variable, for that matter) with
PHP Code:
foo=(type)lua["variablename"]; 
To Export a single function to Lua:
*looks in docs*
PHP Code:
lua.RegisterFunction("functionname",null,typeof(SeeBelow).GetMethod("externalFunctionName")); 
Where functionname is the name that the function should be called with from within Lua, SeeBelow is the class that the function is in, and externalFunctionName is the name of the function in the SeeBelow class that you want to register with Lua.

Phew, hope you understood everything, if you have any questions, please post here or contact me via email at
cpf at cpfx.ca
or MSN at
cpf@airenet.com
__________________

Quote:
Calamitie originally posted:
Calamitie says:
Noodles is a lossy teleportation framework for Noodle objects

Last edited by cpf; 07-27-2008 at 09:09 PM. Reason: stuff stuff stuff
Reply With Quote


Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Headers: Explained RickTucker PHP Articles 2 10-02-2006 06:17 PM