Jump to content

Lua state


Rick
 Share

Recommended Posts

I always use a Create() static function because some classes can fail to create a new object with certain parameters.

 

You make a single header file containing all your classes (with the extension "pkg"), then run that executable, and it generates your Lua glue code.

 

I use this little BMX tool to scan all headers and compile the pkg automatically. If you just add "//lua" after a class or function, this will detect it and add it to the PKG:

'Open header file
Global cleanheaderfile = WriteFile("luacommands.pkg")
If Not cleanheaderfile RuntimeError "could not open file luacommands.pkg"

'Write necessary header functions
WriteLine cleanheaderfile,"$#include ~qLeadwerks.h~q" 
WriteLine cleanheaderfile,"$using namespace Leadwerks;"
WriteLine cleanheaderfile,""

'Traverse directory and write all marked functions
TraverseFiles(CurrentDir())

'Assign classes
For Local class:TClass=EachIn TClass.list
   If class.parentname
       class.parent = TClass.Find(class.parentname)
       'If class.parent Print class.parent.name
   EndIf
Next

'Sort classes
'TClass.list.sort()

'Write the data    
For class=EachIn TClass.list
   class.Write(cleanheaderfile)
Next

WriteLine cleanheaderfile,"bool dofile(const std::string& path);"
WriteLine cleanheaderfile,"bool require(const std::string& path);"

CloseFile cleanheaderfile

Type TClass
   Global map:TMap=New TMap
   Global list:TList=New TList

   Field written:Int
   Field name:String
   Field parent:TClass
   Field parentname:String
   Field members:TList=New TList

   Function Create:TClass(name:String)
       Local class:TClass=New TClass
       class.name=name
       list.AddLast(class)
       map.Insert name.Trim(),class
       Return class
   EndFunction

   Function Find:TClass(name:String)
       Return TClass(map.valueforkey(name.Trim()))
   EndFunction

   Rem
   Method ContainsParent:Int(class:TClass)
       If parent
           If parent=class
               Return True
           EndIf
           Return parent.ContainsParent(class)
       EndIf
       Return False
   EndMethod

   Method Compare:Int(o:Object)
       Local class:TClass=TClass(o)
       If class.ContainsParent(Self) Return -1
       If Self.ContainsParent(class) Return 1
       If class.name>Self.name Return 1
       If class.name<Self.name Return -1
       Return 0
   EndMethod
   EndRem

   Method Write(stream:TStream)
       If Not written
           Local baseclass:TClass=parent
           While baseclass
               baseclass.Write(stream)
               baseclass=baseclass.parent
           Wend
           If parentname
               stream.WriteLine "class "+name+" : public "+parentname    
           Else
               stream.WriteLine "class "+name        
           EndIf
           stream.WriteLine "{"
           For Local s:String=EachIn members
               stream.WriteLine "    "+s
           Next
           stream.WriteLine "};"
           stream.WriteLine ""
           written=True
       EndIf
   EndMethod

EndType

'Helper Functions 
Function FindLua(inputFile:String)
   'Print "Analyzing ~q"+inputfile+"~q"

   file= ReadFile(inputFile)
   Local closureneeded = False
   Local class:TClass

   If Not file RuntimeError "could not open file"

   While Not Eof(file)
       line$ = ReadLine(file)
       OriginalLine$ = line
       'line = Lower(line)

       Local sarr:String[]
       line=line.Trim()
       sarr=line.Split("//")
       If sarr.length>1
           Local tag$ = sarr[sarr.length-1]
           If tag.ToLower()="lua"
               line=sarr[0].Trim()
               'If "class is in the string print the line then an open bracket else print the line tabbed twice
               'DebugStop
               If Instr(line, "class",1) <> 0
                   Local sarr2:String[]=line.split("")
                   class=TClass.Create(sarr2[1])                    
                   'class.name=sarr2[1]
                   If sarr2.length>4
                       class.parentname=sarr2[4].Trim()
                   EndIf
                   'Print class.name

                   'WriteLine cleanheaderfile,sarr[sarr.length-2].Trim()
                   'WriteLine cleanheaderfile,"{"
                   'closureneeded = True
               Else
                   If class'Assert class
                       class.members.addlast(sarr[sarr.length-2].Trim())
                   Else
                       Print "Possible error in file ~q"+inputfile+"~q.  No class found."
                   EndIf
                   'Print sarr[sarr.length-2].Trim()
                   'If closureneeded WriteLine cleanheaderfile,"~t" + sarr[sarr.length-2].Trim()
               EndIf
           EndIf
       EndIf
   Wend
   'If closureneeded
       'WriteLine cleanheaderfile,"};"
       'WriteLine cleanheaderfile,""
   'EndIf 

   'Extra global functions
   CloseStream file
EndFunction

Function TraverseFiles(root:String)

   dir = ReadDir(root)
   If Not dir RuntimeError "failed to read current directory"

   Repeat
       currentFile$ = NextFile(dir)
       If currentFile = "" Exit
       If currentFile = "." Or currentFile = ".." Continue
       If FileType(root + "\" +currentFile) = 2 
           'DebugStop
           TraverseFiles(root + "\" + currentFile)
       EndIf
       If ExtractExt(currentFile) = "h"
           'Print(root + "\" + currentFile)
           FindLua(root + "\" +currentFile)
       EndIf
   Forever

   CloseDir dir

EndFunction 

 

 

Link to comment
Share on other sites

Note that this doesn't seem to like private members as it tries to access them directly :/

 

And you have to include your class headers that it's making stuff for in the final output.

 

Also note you can't use using namespace Leadwerks in your header files. All namespaces seem to need to be on the types.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...