Game Development Community

LuaPlus binding with Tilde debugger.

by Antony K Jones · in Torque 3D Professional · 12/11/2014 (8:04 pm) · 121 replies

I have a LuaPlus binding that I would like to share. Possibly at some point have it integrated into the main branch.
It is a binding not a bridge. Which means that the binding is in separate files from the Torque source. The lua can exist at some point without TorqueScript, but that requires a lot of work converting the .cs files to .lua files. I have started to convert some of the .cs files, but like I said it is a lot of work. There is the potential of redirecting torquescript functions to the statics functions used by lua. So that lua and torquescript can share script funcs. This also makes it easier to eventually pull torquescript out into its own binding. Making the type of binding Torque uses optional.

If I could get someone who might be interested in the Torque Committee to email me that would be great.

antony.jones@comcast.net

P.S. not all of the TorqueScript functionality is supported. I felt that trying to support everything TorqueScript has to offer may affect performance. This of course is open for discussion. In fact pretty much all of it is.
#81
12/25/2014 (4:09 pm)
Did the above not enlighten?
#82
12/25/2014 (4:22 pm)
Oops, you ninja'd me. Reading now :).

EDIT: right, this is exactly what I've been asking about. If I wanted to add another function to SceneObject, do I now have to go in and add a function to scriptBinding.cpp, and a macro in the TS folder, and a metal table registration in the Lua folder?
#83
12/25/2014 (4:37 pm)
i'm sorry i didn't understand you before Dan. yes. Maybe we can hide it with Macros or some UI like Unreal does. this type of setup also provides for the possibility of making stuff pluginable. which allows hot reloading of c code. my ears are open for solutions. I felt this would be the least problematic of the solutions.
#84
12/25/2014 (5:00 pm)
If the static function was actually a method of a class. Things would be a lot cleaner. But that is a lot more work for me. But we can do that as we code in the future. :)
#85
12/25/2014 (6:12 pm)
Right, so my question is why we can't, for example, replace the contents of DefineEngineMethod and so on to generate the appropriate definitions instead. Or even add to them, if you'd like to have TS and Lua bindings simultaneously. Is it a problem having those macros all inline in C++ files? Is there simply not enough information in those macros? Or am I completely misunderstanding the problem?
#86
12/25/2014 (6:34 pm)
It's been a while I don't really remember, but I do remember trying it both ways. It certainly seems reasonable. In fact I actually tried going back to it a couple times but something came up. I'm afraid I am getting old and I don't remember things to well. One thing that just came to mind even though I'm fairly certain that this was not the problem. What if you want to strip out the code of a particular binding. You can't just put a #ifdef in a Macro. So it makes it harder to strip the code out that you aren't using. It also seems like a burden to the macro to handle all of the different kind of bindings. It's not very modular. Just my initial thoughts. I'll keep trying to remember. :) sorry
#87
12/25/2014 (6:52 pm)
Yup. I can't recall why. As far as my opinion i guess i felt strongly at the time that the implementation and the binding should be in a separate file. I felt that the macros where already overly burdened and that to keep adding information to the macros was excessive. I think i also really wanted to eventually move the binding code into actual methods belonging to the class. And then the binding is just simply what was in the luaScriptBInding and the static functions would go away. Another good reason for this was that later if we moved to a more pluginable direction then the internal class would more closely match the external api class. :) It may have been personal. Sorry I don't remember what immediate problems I ran into.
#88
12/25/2014 (6:53 pm)
The nice thing is I just wasted a lot of my time and hopefully not a lot of yours.
#89
12/25/2014 (6:59 pm)
Oh and debugging Macros suck, big time!
#90
12/26/2014 (6:46 am)
Couldn't you take something like this:

# define ConsoleFunction(name,returnType,minArgs,maxArgs,usage1) \
static returnType c##name(SimObject *, S32, ConsoleValueRef*); \
static ConsoleConstructor g##name##obj(NULL,#name,c##name,"",minArgs,maxArgs);\
static returnType c##name(SimObject *, S32 argc, ConsoleValueRef *argv)

And change into something like this:

# define ConsoleFunction(name,returnType,minArgs,maxArgs,usage1) \
TSConsoleFunction(name,returnType,minArgs,maxArgs,usage1) \
LuaConsoleFunction(name,returnType,minArgs,maxArgs,usage1)

And put that in your generic script binding files. Then in the Torquescript file define TSConsoleFunction as the same macro as before and define LuaConsoleFunction as whatever you need to create the lua bindings for the function. This way you can add/remove ConsoleFunction bindings for each scripting language in one spot without having to go through your existing code and update all your functions.
#91
12/26/2014 (7:56 am)
Quote:
Oh and debugging Macros suck, big time!
Agreed! Almost as fun as debugging templates....
#92
12/26/2014 (9:45 am)
Andrew: That sounds very reasonable. Let me share my final vision for things and you can tell me if I'm crazy.

INTERNAL CLASS( the class we use now ):

//scene/sceneobject.h
class SceneObject : public NetObject, private SceneContainer::Link, public ProcessObject
{
public:
Point3F getEulerRotation(); // actually add function to class
};

//scene/sceneobject.cpp
#include "scene/sceneobject.h"
Point3F SceneObject::getEulerRotation();

// scriptbinding/lua/luaScriptbinding.cpp
metatableFunctionsLuaObj.RegisterDirect( "getEulerRotation", &SceneObject_getEulerRotation ); // Simple Register in a file of it's own

// scriptbinding/torquescript/tsScriptBinding.h"
( Will need this function added to TorqueScript. )
torqueScript.RegisterFunction( "getEulerRotation", &SceneObject_getEulerRotation );
Hoping to avoid calling a lot of function calls to reduce pointer hopping and cache misses.


// Torque Plugin API
// This is the function the plug-in uses.
// sdk/scene/tsceneobject.h
class TSceneObject
{
SceneObject* mObject;
Point3F getEulerRotation() { mObject->getEulerRotation() }
};

#93
12/26/2014 (2:41 pm)
Quote:
( Will need this function added to TorqueScript. )
torqueScript.RegisterFunction( "getEulerRotation", &SceneObject_getEulerRotation );

This already exists more or less:

github.com/GarageGames/Torque3D/blob/81a385094fa270a4838b801e49d143ef61ef2b58/En...

Unless I'm misunderstanding you it sounds like your proposal would require a lot of foot work reorganizing things. There are a lot of function definitions in a lot of classes, not to mention in all the resources, tutorials, documentation, etc. If it could be done without breaking all that I think everyone would be a lot more receptive to the idea. Wouldn't altering the definitions of the existing macros be the path of least resistance while still accomplishing your goals?
#94
12/26/2014 (4:27 pm)
Andrew: You hit the nail on the head. It was an aggressive plan. I was trying to do things in stages. But I was also proposing it to see how much interest it generated. I'm fine with whatever. I shot for the moon. It seems like bad form to add code like turret to an engine. Seems like you should be able to link to torque libraries. Like Ogre and Unreal. And I thought the solution I was proposing might take care of 2 problems. I feel like part of the problem with torque is the Macros. By making the code in the Macros into functions I think it is a excellent step forward. Unreal has what they call Hot Reloading code. This is great with iterating. It is like edit and continue. It allows you to reload c code. I'm not sure but I think it is because there code is separated into dynamic linked libraries. My guess is when they build for different platforms they link the dll's differently. Since not all platforms support dll's. What I am saying about Unreal is conjecture because I don't really know what they do. It is pure speculation. Of course we don't have to do Hot Reloading with c code. We can do this with Lua. And I am sure we can probably do this with TorqueScript.
#95
12/26/2014 (4:28 pm)
Shouldn't the Editor be a plugin? :)
#96
12/26/2014 (4:31 pm)
/unlurk
Quote:Shouldn't the Editor be a plugin? :)
Script-side it is, see: www.garagegames.com/community/forums/viewthread/140846 for a discussion related to that type of thing.
/lurk
#97
12/26/2014 (6:05 pm)
Quote:
Shouldn't the Editor be a plugin? :)

You don't know just how much I agree with that sentiment. I've been working on a side project in T2D and I'm working on loading C++ code from DLLs at runtime. Registering functions is easy, registering console objects is a bit more challenging.

It's up to the steering committee on the macros. Personally, I like them. I'd rather see you either a) expand each macro to support multiple languages b) expand the constructors of ConsoleConstructor (for functions) and ConcreteClassRep (for objects) to support multiple languages.

If you're going to ditch the macros from torquescript then I think you should leave Lua out of the picture for awhile and work on a branch where you remove all the torquescript macros. Then that chunk of work can be evaluated on it's own.
#98
12/26/2014 (6:56 pm)
What you're all saying makes sense. I will go a different direction. Thank you for all of the valuable information. :)
#99
12/27/2014 (6:28 am)
@Lefteris

With regard to the scripts being associated with nodes issue, what I think happens in godot is the scope is heavily associated with the current node. So in your script when you define functions and such it is contained within the nodes namespace. Probably something similar can be done with sandboxing in lua. Not all scripting vms do this properly as usually you just end up dumping your code into a big global namespace. I think UnrealScript and also AngelScript allows for this.

If you are looking for a good dataflow language might I suggest using VHDL? ;)

Jokes aside, I would be interested to know if you have any problems with garbage collection your current implementation.

In any case, I think in the end one can make fairly persuasive arguments for and against lua(jit) but it doesn't mean anything if people like steve who end up actually churning out commercial torque games just prefer the characteristics of TorqueScript.

@Antony

Looking forward to seeing what you come up with! :)
#100
12/27/2014 (8:31 am)
Thank you James. Andrew was definitely right I should have broken this down into a 2 part problem. Thank you everybody.