Rick Posted November 19, 2013 Share Posted November 19, 2013 Under source/libraries I see LuaJIT & Lua 5.1.4. If I need to make Lua calls using Interpreter::L which library do I need to download the source for and include it in my project LuaJIT or Lua 5.1.4? If it's LuaJIT what version? Quote Link to comment Share on other sites More sharing options...
Josh Posted November 19, 2013 Share Posted November 19, 2013 You can just start using the C++ Lua command set right away in any Leadwerks C++ project, with no extra work. You don't need to worry about which platforms use Lua and which use LuaJIT, it will all just work. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Rick Posted November 19, 2013 Author Share Posted November 19, 2013 It doesn't for me. What do I need to include for a header? I included "Leadwerks.h" and the following give me linker errors saying the functions don't exist. lua_getglobal(Interpreter::L, luaHandlers[msg].c_str()); lua_pushlightuserdata(Interpreter::L, &reader); lua_pcall(Interpreter::L, 1, 0, 0); 1>lua-gluecode.obj : error LNK2019: unresolved external symbol "int __cdecl lua_gettop(struct lua_State *)" (?lua_gettop@@YAHPAUlua_State@@@Z) referenced in function "int __cdecl tolua_luacommands_RakNetNetwork_new00_local(struct lua_State *)" (?tolua_luacommands_RakNetNetwork_new00_local@@YAHPAUlua_State@@@Z) 1>RakNetNetwork.obj : error LNK2019: unresolved external symbol "int __cdecl lua_pcall(struct lua_State *,int,int,int)" (?lua_pcall@@YAHPAUlua_State@@HHH@Z) referenced in function "public: void __thiscall RakNetNetwork::Update(void)" (?Update@RakNetNetwork@@QAEXXZ) 1>RakNetNetwork.obj : error LNK2019: unresolved external symbol "void __cdecl lua_pushlightuserdata(struct lua_State *,void *)" (?lua_pushlightuserdata@@YAXPAUlua_State@@PAX@Z) referenced in function "public: void __thiscall RakNetNetwork::Update(void)" (?Update@RakNetNetwork@@QAEXXZ) 1>RakNetNetwork.obj : error LNK2019: unresolved external symbol "void __cdecl lua_getfield(struct lua_State *,int,char const *)" (?lua_getfield@@YAXPAUlua_State@@HPBD@Z) referenced in function "public: void __thiscall RakNetNetwork::Update(void)" (?Update@RakNetNetwork@@QAEXXZ) 1>C:\Leadwerks\Projects\Duck\Projects\Windows\..\..\\Duck.debug.exe : fatal error LNK1120: 4 unresolved externals ws2_32.lib OpenGL32.lib Glu32.lib winmm.lib Psapi.lib These are the only libs you have in the project so the actual lua functions don't exist anywhere. Quote Link to comment Share on other sites More sharing options...
Rick Posted November 19, 2013 Author Share Posted November 19, 2013 OK, I see you wrapped up some of the lua functions. I see GetGlobal() and Invoke() which would match 2 of the 3 functions I have. What about lua_pushlightuserdata()? I'm pushing a class object pointer to one of the classes I also exposed via tolua. Quote Link to comment Share on other sites More sharing options...
Admin Posted November 19, 2013 Share Posted November 19, 2013 You can call PushObject() for any class derived from a Leadwerks Object. Note the object needs a function like this so Lua knows what it is: std::string Sound::GetClassName()//don't forget to make this virtual!!! { return "Sound"; } This is the source for Object::Push(): void Object::Push(const bool takeownership) { if (Interpreter::L==NULL) Interpreter::Reset(); if (takeownership) { tolua_pushusertype_and_takeownership(Interpreter::L,(void*)this,GetClassName().c_str()); } else { tolua_pushusertype(Interpreter::L,(void*)this,GetClassName().c_str()); } } Quote Link to comment Share on other sites More sharing options...
Rick Posted November 19, 2013 Author Share Posted November 19, 2013 I'll give this a try, but sort of a bummer we can't push objects directly with a void* without having to derive from Leadwerks::Object. Quote Link to comment Share on other sites More sharing options...
Rick Posted November 19, 2013 Author Share Posted November 19, 2013 The tolua++ generated code makes a call to lua_gettop(). What would Leadwerks::Interpreter equal be? I couldn't find anything that seems to fight. Quote Link to comment Share on other sites More sharing options...
Rick Posted November 19, 2013 Author Share Posted November 19, 2013 Well I screwed something up. Now App.lua is saying it can't find a script that it was finding before I started screwing around adding RakNet and using tolua++. Erroring on: require "Scripts/States/StateManager.lua" even though it does exist. Any ideas? Quote Link to comment Share on other sites More sharing options...
Josh Posted November 19, 2013 Share Posted November 19, 2013 There's a line at the end of that BMX PKG generator I made that adds our own dofile and require functions, and you probably need to remove that. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Rick Posted November 19, 2013 Author Share Posted November 19, 2013 I didn't use the BMX file. I have no idea how to run a BMX app, but I'm not really interesting in messing with that right now. I only have 2 headers so I just manually copied and pasted to the pkg file. So I added the dofile and rquire declarations in the package and just changed to referenced Leadwerks version of these in the generated code. ie. replace dofile() with Leadwerks::dofile(). After adding the dofile() and require() it gets passed the !Interpreter::ExecuteFile("Scripts/App.lua") fine now, but hits false on: if (!Interpreter::Invoke(1,1,errorfunctionindex)) return false; I get error: "Lua Error error in error handling" and the program quits. So I think for sure we need to have the dofile and require code at the end of our package and need to replace it with Leadwerks:: versions in the generated code, because that makes it do ExecuteFile() works (since the Lua files use dofile and require), but now we have this errorfunctionidex issue. So not sure what's up with that error function invoking error. Quote Link to comment Share on other sites More sharing options...
Admin Posted November 19, 2013 Share Posted November 19, 2013 When Lua hits an error, the C++ program doesn't know about it until the script is finished executing. In order to pause the program and display the call stack in the debugger, a hook is required that will connect to the Leadwerks debugger and send the call stack over. Lua allows this by providing it with an error function to call if something goes wrong. If you only have a couple of header files, it's much easier to do them manually like your are. Quote Link to comment Share on other sites More sharing options...
Rick Posted November 19, 2013 Author Share Posted November 19, 2013 What/where is this error function then? Is it a lua function or C++ function? Right now it's hitting this error function and returning false in App:Start() in C++ so I'm dead in the water right now on my next debugging steps to see why this isn't working. Since it's returning false on: if (!Interpreter::Invoke(1,1,errorfunctionindex)) return false; I assume this means it can't find the error function to call? Why would that be? At this point in the code I haven't even done any of my own stuff. Quote Link to comment Share on other sites More sharing options...
Josh Posted November 19, 2013 Share Posted November 19, 2013 The function LuaErrorHandler can be found in Error.lua: function LuaErrorHandler(message) Debug:Error("Lua Error: "..message) end This just calls the C++ function Debug::Error(), which connects to the debugger and pauses the program. This script is automatically run when Lua is initialized. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Rick Posted November 19, 2013 Author Share Posted November 19, 2013 OK, so the good news is it's making it inside this function because the error I get is: "Lua Error: error in error handling" which is clearly coming from this error handler because it starts with "Lua Error: ". However the message "error in error handling" isn't all that descriptive . If it seems like it's getting inside this function why would: Interpreter::Invoke(1,1,errorfunctionindex) be returning false making the application quit when being done in: if (!Interpreter::Invoke(1,1,errorfunctionindex)) return false; It would seem to me it was able to invoke the error handler function since I get the error msgbox from it, so why would it return false? What's going on inside Interpreter::Invoke() that's making it return false? Quote Link to comment Share on other sites More sharing options...
Josh Posted November 19, 2013 Share Posted November 19, 2013 Can I see your PKG file? Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Rick Posted November 19, 2013 Author Share Posted November 19, 2013 I'll post it in about 5 hours when I get home. Quote Link to comment Share on other sites More sharing options...
Rick Posted November 20, 2013 Author Share Posted November 20, 2013 Attached is the pkg file that has the 2 headers for my classes. After it's created I just manually add the includes, but then I also had to make the calls to lua's dofile/require be Leadwerks::dofile/require. I also have to change the lua get_top which I assume is equal to Leadwerks::Interpreter::GetStackSize(). After I make those changes the project compiles, but then I get the error function being called when it tries to Invoke the App:Start() function. Side Note: I find that if I exclude the tolua generated cpp file everything works. So the existence of that file in the project is causing issues even though I get the error BEFORE I even call anything generated in that file. The simple fact that it's in the project causes the problem. luacommands.rar Quote Link to comment Share on other sites More sharing options...
Rick Posted November 20, 2013 Author Share Posted November 20, 2013 OK, I was able to get it to run by renaming a couple functions in the file. I renamed tolua_luacommands_open to tolua_luacommands_open1 and luaopen_luacommands to luaopen_luacommands1. Here is what I'm thinking. You used this same method of getting your Leadwerks objects and so those 2 functions are the exact same name for the tolua code you generated. Then when I add it into the project we now have 2 sets of the same function names! I'm shocked it even compiled like that but it does, but clearly that's screwing stuff up. I don't know how I can call my new tolua_luacommands_open1() function inside App.cpp thought? Since it's a cpp file I can't include any header file that tells App.cpp that function exists so it can't find it. Quote Link to comment Share on other sites More sharing options...
Rick Posted November 20, 2013 Author Share Posted November 20, 2013 Sorry for the stream of thought, but I think I got it working. I took out the declaration to tolua_luacommands_open1() from the cpp file and made a header file that looks like: #pragma once #include "Leadwerks.h" #include "tolua++.h" /* Exported function */ TOLUA_API int tolua_luacommands_open1(lua_State* tolua_S); I then include this header file in the tolua generated cpp file AND app.cpp so that I can call tolua_luacommands_open1() in App:Start() in App.cpp. I don't get errors now when trying to call my classes from Lua and it's hitting breakpoints in my VS project for my class when I make the call from Lua! Success!!!! I would say this is far from how easy you made it sound on this page http://www.leadwerks.com/werkspace/files/file/216-tolua/ If everything works, I'll post a tutorial on all the steps I did. Quote Link to comment Share on other sites More sharing options...
Admin Posted November 20, 2013 Share Posted November 20, 2013 Glad you got it working. I haven't done one by hand in a long time. Was it necessary to include the Leadwerks header? Does that make it re-generate all the Leadwerks commands? Quote Link to comment Share on other sites More sharing options...
Rick Posted November 20, 2013 Author Share Posted November 20, 2013 I did include Leadwerks.h because I needed to change some of the base lua commands to the Leadwerks ones, like lua_gettop to Leadwerks:GetStackSize(). Also because I added the dofile/require at the end of the file (not even sure I needed to) I needed to use the Leadwerks version of these. Now I have to see if I can expose this in a dll. The nice thing is embedding RakNet into the main exe I think is required for mobile games because from what I've read you can't really have dll/external libraries on mobile devices. However, if you do what you talked about on Steam then I would need a dll to hold the RakNet commands and load the dll via lua. I hope that works because then this will be able to run in all environments. I just did an #include "Leadwerks.h" at the top, I didn't actually include all the contents of Leadwerks.h in the pkg so it wouldn't have regenerated any Leadwerks stuff. Quote Link to comment Share on other sites More sharing options...
Rick Posted November 20, 2013 Author Share Posted November 20, 2013 Josh, are you passing lua table functions back to c++ to be callbacks at all? If so, how are you doing it? So I'm looking at how you do App stuff. Looks like you create a table from C++ and call it App. Then you load the App.lua file which defines the Start() & Loop() functions. Then you get the App table, get the Start function, push the app table as self, and call the Start function. The main difference in my situation is that the table isn't created in C++, but created in lua. I would have to pass the table to my C++ function. I don't think I could really give it a name with SetGlobal. It must have a name already when it's created from lua that I can use? Quote Link to comment Share on other sites More sharing options...
Rick Posted November 21, 2013 Author Share Posted November 21, 2013 I got this all working, will make blog post/tutorial on it. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.