Please login or register.

Login with username, password and session length

 

News:

Welcome to the Updated Lua Forum!


Author Topic: Pushing a (named) table  (Read 264 times)

Rabby

  • Guest
Pushing a (named) table
« on: June 28, 2010, 10:56:02 am »
Hey,
I can successfully use LUA as a scripting engine in my c++ projekt.
However I'm not sure about how to push a table with the correct values onto the stack.
So for example I want to use:

if Player.Life = 50 then
...
end

I can't seem to make that work with the functions:
lua_newtable();
lua_pushinteger(...,50);
etc..
And also knowing how to update those values, for example the players life on an attack would be really nice.

Thanks.

dirkf

  • Contributor
  • **
  • Posts: 92
    • View Profile
Re: Pushing a (named) table
« Reply #1 on: June 29, 2010, 01:47:17 pm »

Rabby

  • Guest
Re: Pushing a (named) table
« Reply #2 on: July 07, 2010, 04:36:19 am »
Nice thanks :)
It's working perfectly.

However, is it also possible to push a table as an argrument for a LUA function?
Example:
cpp-file:
lua_getfield(L, LUA_GLOBALSINDEX, "SomeFunction");//get our function
lua_pushstring(L, "MyTable);
lua_createtable(L,0,1); 
lua_pushstring(L, "Value1");
lua_pushinteger(L, 0);
lua_settable(L, -3);
lua_settable(L, ???); //Not sure how to set the table to the function as argument
lua_pcall(L, 1, 0, 0);//Just the lua table as argument, and call the function SomeFunction

lua-file:
function SomeFunction( MyTable )
MyTable.Value1 = 451;
end

dirkf

  • Contributor
  • **
  • Posts: 92
    • View Profile
Re: Pushing a (named) table
« Reply #3 on: July 07, 2010, 01:21:30 pm »
Something like the following (warning: untested!):

Code: [Select]
lua_getglobal(L, "SomeFunction");
lua_createtable(L, 0, 1);
lua_pushinteger(L, 0);
lua_setfield(L, -2, "Value1");
lua_pcall(L, 1, 0, 0);

See also http://www.lua.org/manual/5.1/manual.html#lua_call

Rabby

  • Guest
Re: Pushing a (named) table
« Reply #4 on: July 09, 2010, 04:29:07 am »
Thanks again, it's perfectly working :)

I just got one final question:
If I'm pushing a table to the global index and then I want to update it, like the Player.Life value, should I just push it again (and it's automatically overwritten), or is it better to retrieve the values of the existing table and update them (if that's the correct way, how could be that implemented correctly)

dirkf

  • Contributor
  • **
  • Posts: 92
    • View Profile
Re: Pushing a (named) table
« Reply #5 on: July 11, 2010, 05:50:31 am »
You shouldn't create a new Player table each time. It generates more garbage and it breaks other code that has taken a local reference to the object.

Here's some simple example code showing how to update a field. This is the most straightforward way of doing it; there are faster but less readable alternatives (and you know what they say: premature optimization is the root of all evil):
Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lua.h"
#include "lauxlib.h"

int main(void)
{
  lua_State *L = luaL_newstate();

  luaL_openlibs(L);
  // create 'Player'object/table
  lua_createtable(L, 0, 1);
  lua_pushinteger(L, 100);
  lua_setfield(L, -2, "Life");
  lua_setglobal(L, "Player");
  // take 10 Life away
  lua_getglobal(L, "Player");
  lua_getfield(L, -1, "Life");
  lua_pushinteger(L, lua_tointeger(L, -1) - 10);
  lua_setfield(L, -3, "Life");

  lua_close(L);
  return EXIT_SUCCESS;
}

Rabby

  • Guest
Re: Pushing a (named) table
« Reply #6 on: July 23, 2010, 05:45:48 pm »
Hey, I've tried to implement your way into my project, but I can't get it working!  :'(
This is what I currently use: Private Paste Link
(for better formatting)
I basically have a init functions [SetObjectData()] and a update function [UpdateObjectData()] which is called afterwards.
However it always crashes at the
Code: [Select]
updateTableData(L,"Life", lpcObject->getLife()); location, I'm sure the update function is broken.

Thanks for your endless pleasantness  :)

Rabby

  • Guest
Re: Pushing a (named) table
« Reply #7 on: July 23, 2010, 05:48:28 pm »
Sorry for the double post, but can't edit my old one :(
The two main functions are UpdateGlobalData() and SetGlobalData()!
Here's a complete version of it:
Private Paste Url

dirkf

  • Contributor
  • **
  • Posts: 92
    • View Profile
Re: Pushing a (named) table
« Reply #8 on: July 27, 2010, 12:49:40 pm »
At first sight I don't see anything wrong. What happens with g_lpcObjectPlayer and lpcObjectTarget between the calls to SetGlobalData() and UpdateGlobalData()? If it crashes when dereferencing lpcObject then this means the pointer is invalid.

One remark though: don't push pointers as ints. Lua specifically has light userdata for that purpose. See lua_pushlightuserdata() and family.

Rabby

  • Guest
Re: Pushing a (named) table
« Reply #9 on: July 29, 2010, 02:18:44 pm »
Thanks for the info about lua_pushlightuserdata(), I'll try that.

g_lpcObjectPlayer and lpcObjectTarget are two pointers of a unit class.
They normally don't change, however the values, like their life, position etc changes and therefore the LUA values for the Player and Target global must be updated every frame.

The pointers are surely valid, but the updateTableData() function must be somehow wrong.

edit: I just saw that i had
Quote
  lua_getfield(L, LUA_GLOBALSINDEX, szName);
}

at the end of the update function which should be lua_setfield(...);
I'll check if that fixes it.

Rabby

  • Newbie
  • Posts: 1
    • View Profile
Re: Pushing a (named) table
« Reply #10 on: August 03, 2010, 10:58:21 am »
I could finally fix it =)
I just had to fix the stack (remove the outdated value(s))

Working update functions:
#1 get table from global stack
#2 void updateTableData(lua_state* L, char* szIndex, int iValue)
{
   lua_getfield(L, -1, szIndex);
   lua_settop(L,-2);

   lua_pushinteger(L, iValue);
   lua_setfield(L, -2, szIndex);
}
#3 set table to global data again


Thanks for your help dirkf

 

+ Quick Reply