How does tostring, concat and using the object directly have different results? - lua

I'm using an version of Lua 5.1 in a game called Kingdoms of Amalur. This is havocscript but afaik, havocscript is lua. Now there is a custom type called ui64 that the game has and a custom package that injects a hook that I added to the game.
If I do the following:
module("playerdodge_hook", package.seeall)
function save_to_file(filename, data)
if io then
io.output(filename)
io.write(data)
io.flush()
end
end
function dodge_hook()
local x = SIMTYPE_ID("longbow_unique11a")
save_to_file("type", type(x))
save_to_file("directly", x)
save_to_file("tostring", tostring(x))
save_to_file("concat", "" .. x)
end
The output of the files are the following:
type
ui64
Directly
Sin
tostring
0
concat (does not exist)
I am no expert in Lua, but i'm trying to understand how this works. As I would like to be able to print debug information and save this externally.
Edit:
Short answer is the game's engine used a proprietary override the io write method.
Amalur has different types, and the ui64 is actually a pointer to some memory inaccessible to lua/havok script, but the library allows manipulation. And basically when a ui64 is passed in raw to write calls the localization for the Type or Actor or whatever the internal object represented.
had an altered version of io library that when it received an ui64 would interrogate the

First, I want to say that I could not use actual io.write as io is not loaded into the engine but I have a similar method that I can use to write text to an ini entry, however, every time I call the write method it overrides the content of my personal entry regardless of if I change the key.
The basic gist of the issue is that the game Kingdoms of Amalur havok engine has a custom write/(and pretty much any other way to display text) routine.
The ui64 data type is more or less a pointer to an object that exists in havok or c. However, the engine offers an api that can take these pointers and call various routines.
Passing the ui64 to the write method would make the game invoke into it's localization tables and output the localized name to the screen for this particular Type. Thus longbow_unique11a is Sin.
Since my goal was to try to get the actual localized name and dump them all plus other data, I came up with a workaround.
Essentially, the game allows you to name crafted items, and when it does so it populates the name with a default entry and so some by decompiling some methods I was able to come up a routine to build my string like so::
function dump_item_names(tbl)
local callback = function(text, canceled)
op = {}
for i = 1,#tbl do
local actor = tbl[i]
local typeId = get_hex_of_raw_id(actor)
WINDOW.populate_edit_box(name_win.m_editbox, actor)
local name = WINDOW.get_editbox_text(name_win.m_editbox)
op[#op + 1] = typeId .. ',' .. name
end
save_to_file("items.txt", table.concat(op,'\n'))
end
name_win.launch(SL(357894144), tbl[1], true, 100, callback, false)
end
So yeah, not really a lua problem so much as a havok problem and me not understanding a foreign game engine that I'm hacking.

Related

In Lua, access the evaluated value of a C function addressed via a userdata table

I have a piece of lua code that is called from a C program that passes it a table.
The table contains a table which has a field that LUA reports is of type "function".
I want to invoke that function and get its return value, but the following just causes a crash (????stack corruption????):
function myFunc (tableIn)
local interface = tableIn["interface"] -- type(interface) is table
local targetFunc = interface["targetFunc"] -- type(targetFunc) is function
local value = targetFunc()
...
end
I'm therefore assuming that I need to pass one or more parameters to targetFunc(...) but I have no idea what targetFunc() is expecting and I don't have access to the documentation or code for targetFunc - which I'm also guessing is written in C.
I've seen the thread lua - get the list of parameter names of a function, from outside the function and run the code as suggested - but that just seems to return "*temporary".
The question: is there some "standard" way of calling a C routine from LUA - or is there any other programmatic way (even a one-off) of finding out how many and what type of parameters targetFunc(...) needs.
Even an answer of "no - you need to see the code / doc for targetFunc(...)" would help!
Thanks in advance...

Is there a way to check if a GTK widget supports a property without checking version numbers?

According to the GTK API reference, the "license-type" property of GtkAboutDialog is only present in GTK >= 3.0. For compatibility, my code currently checks the GTK version before setting the "license-type" property:
-- This is Lua code binding to GTK via lgi
local dialog = Gtk.AboutDialog {
title = "About Me",
-- ...,
}
if Gtk.check_version(3,0,0) == nil then
dialog.license_type = Gtk.License.MIT_X11
end
Instead of doing this, is there a way to directly ask GTK if a widget supports a certain property? I think the code would be more self-documenting and less bug prone if I could write something that looks like
if supports_property(dialog, "license-type") then
dialog.license_type = Gtk.License.MIT_X11
end
Since this question is really about the GTK API, I'm OK with answers in any programming language. Although the examples are in Lua, I assume a similar problem should show up in other dynamic-language bindings or even in C, assuming that there is a way to set properties by name without going through the set_license_type accessor function.
You don't need to use the _property field like you are doing in your currently accepted answer since lgi finds all names in the type categories tables directly. Additionally, it is also possible to get type of an instance using _type accessor. So I'd recommend following solution:
if dialog._type.license_type then
dialog.license_type = Gtk.License.MIT_X11
end
You can use the g_object_class_find_property() function to see if a property exists.
Note that this function takes a GObjectClass, not the GObject instance. All GObject classes come in these class-instance pairs, with the class structure used for shared things like vtable methods. To get the GObjectClass associated with an object instance, in C, you can use the G_OBJECT_GET_CLASS() macro. (If you want to do this in Lua, and if Lua can't call C macros like that, you'll have to trace the definition of G_OBJECT_GET_CLASS().)
In lgi, a class's properties are present in its _property field:
if Gtk.AboutDialog._property.license_type then
dialog.license_type = Gtk.License.MIT_X11
end
If for some reasons you need to know if a property is present without instantiating it, you can go with #andlabs idea in this way:
local lgi = require'lgi'
local Gtk = lgi.require'Gtk'
local class = Gtk.AboutDialogClass()
-- Prints yes
if class:find_property('license') then print('yes') end
-- Does not print anything
if class:find_property('unknown') then print('yes') end

How to pass variable by reference in Corona

I'm using Corona SDK.
I want to write a function which receives component as parameter and removes it like that:
function removeComponent(component)
if component then component:removeSelf() end
component = nil
end
Well, it works but my parameter does not get nil after using this function. Probably I have to pass it by reference, but I'm not sure it is possible with Corona.
This does not really make sense as presented in your example.
What exactly are you trying to accomplish? Is component a global ? Or a key in a table?
In your example, component is the name of a local variable in your function. Your component = nil only removes the value from the local variable, and thus will be lost.
If you want to have global effects, you'd need to pass the name of the variable you'd want to eliminate as string:
function removeComponent(component)
if _G[component] then -- exists globally?
_G[component]:removeSelf()
end
_G[component] = nil
end
Note that this style of programming (using the global table for this kind of things) is generally not a good idea. In the best case it can surprise you, in the worst case you end up zapping things like standard functions as print.
Therefore I'd recommend puttign things in their own table, and passing it on to the function.
Lua doesn't support passing by reference, but since it does support return values you can always achieve what you want using this idiomatic approach:
function removeComponent(component)
if component then component:removeSelf() end
return nil
end
And then call it like this:
a = removeComponent(a)
Edit: It's worth pointing out too that since Lua supports multiple return values and multiple assignments, you never actually need pass-by-reference. If you need several items updated, pass them in and return them and then do the call as
a,b = myFunction(a,b)
Its not different really than any other language. Passing by a value by reference (in C++ for example) would not stop any program from holding another copy of this same value elsewhere.
I know nothing of Corona, but this isn't really a Corona question so much as a Lua style question. However, if I had wrote it, I would ensure that the 'component' userdata or underlying value would clear itself up. If the userdata was accessed again, it should throw an error complaining about re-using a dead userdata.
I have written this code:
local component = display.newCircle(100, 100, 100);
local function removeComponent(c)
if component then component:removeSelf() end
component = nil
end
removeComponent(component)
if component == nil then print("Component is nil") else print("Component is not nil") end
And it prints "Component is nil". Perhaps you have a copy of your component somewere else or may be you forget to call function removeComponent or something else. Need to see more of your code

Declaring Lua Functions and referencing with correct name

What is the difference between the following Lua scripts in terms of function scope. How would it effect the need to require 'calculator' in some other Lua script. And how would it be referenced in say a LuaState.getGlobal(function_name). What would be its proper function name? Also any comment on advantages/disadvantages of the declaration approaches.
A) Calculator.lua
function foo(n)
return n+1;
end
B) Calculator.lua
calc= {}
function calc.foo(n)
return n+1;
end
C) Calculator.lua
function foo(n)
return n+1;
end
function calculator()
calc = {}
calc.foo=foo
return calc
end
I don't know what it is you mean exactly by the "scope" of these scripts. Exactly what these scripts do depends on how they're being executed. You could give them a different environment, thus changing what they think of as "globals".
So, I will explain what each of these scripts does based on the assumption that you are loading them with dofile, dostring, or something of the like. That is, you're applying them to the global environment.
A)
This creates a single global variable, foo, which is a function.
B)
This creates a single global variable, calc, which is a table. This table has a single entry, with the key foo, who's value is a function.
C)
This creates two global variables. foo is a function. calculator is also a function. Each call to calculator will cause the global variable calc to be overwritten. The new value of calc will be a table that has a single entry, with the key foo, who's value is a copy of what is stored in the global variable foo.
It's hard to say what the "advantages" of method C are, since it makes no sense. It creates two functions instead of one, and that second function keeps creating new tables.
B is just a "namespace" scoped version of A. The general expectation with Lua modules is that including them will usually create some table that will contain all of the functions in that module, to avoid name conflicts with existing global state. In that regard, B may be better. But it depends mostly on what this script will be used for.
Personally, for simple shell scripts and utility scripts, I don't bother with proper module scoping. When I do make a proper module, I generally use the module Lua function.
Not exactly an answer, but a comment on semantics - in Lua, you do not declare a function, you create it. The function becomes available at the time the function(...) ... end is executed. How it is available depends on where you store it.
You have to remember that:
function myfun(foo) print('foo') end
is just syntactic sugar for:
myfun = function(foo) print('foo') end
If you do not do anything special, myfun becomes a global variable stored in the global state (accessible through _G). If you say local myfun before actually calling function myfun() end, the function (actually a closure) will be stored in the local variable and available only to the scope of the local variable.
If you use require, it just finds the file and loads it once. It doesn't do anything fancy with the module like hiding globals, etc. So if you write function foo() end in your module Calculator.lua, then calling require 'Calculator' will create a function in global foo, which you can access using LuaState.getGlobal("foo"). If you create a table of functions (step B), you have to use 2 steps:
L.getGlobal("calc") -- pushes the "calc" global (a table) to the stack
L.getField(-1, "foo") -- gets the "foo" field from the table

Use of metatables in Lua

I'm trying to implement a object notation in Lua scripts.
Here is what I succeeded to do with the C API:
I created a new global table "Test" as a class and added a field "new" in it, pointing to a function written in C
i.e I can do this in lua code: "local obj = Test.new()" (it calls the function "new")
The "new" C function creates and returns a new table, and registers functions in it as fields (e.g "add", "count"...)
i.e I can do this: "obj:add("mike")" and "obj:count()" (obj is passed as first arguments with the ":" notation)
2 questions:
1) Everything works as expected, but the thing I'm wondering is: What is the advantage of using metatables in my case?
I see everywhere that metatables can help me to achieve what I tried to do, but I don't understand where they would be useful?
Adding fields to tables as methods isn't correct?
How could metatables help me (If added as my tables metatables)?
2) In fact I'm trying to reproduce the behaviour of C++ in Lua here.
For example, when I write this in C++: "Test *obj = new Test();"
I expect C++ and the constructor of Test to return me a pointer of an instance of Test.
This is exactly what I'm trying Lua to do for me.
The thing is that I use a table in this case, as the return of "new", but not a pointer so I can call methods on it later with Lua (using its fields), like a standard C++ object (with the operator ->).
To be able to retreive the actual pointer of my class in the C fonctions, I added a field "ptr" (light uservalue) to the table returned by "new". Without it, I would have been able to manipulate only the Lua table in my C function, nothing more (so no more method calls on the real pointer).
My second question is, Is it the right way to do it?
Do you have better idea on how to be able to manipulate my pointer everywhere without this "ptr" field?
Thank you,
Nicolas.
The main reason is that you get the __index metamethod.
Without it, every instance of a object has to have all the functions associated with it: which can make tables why large; and use a lot of memory.
local methods = {
foo = function() return "foo" end ;
bar = function() return "bar" end ;
bob = function() return "bob" end ;
hen = function() return "hen" end ;
}
So you have either
function new_no_mt ( )
local t = {}
for k , v in pairs ( methods ) do t [ k ] = v end
return t
end
vs
local mt = { __index = methods ; }
function new_mt ( )
return setmetatable ( { } , mt )
end
There are other benefits too;
defining operators;
easy type comparison via comparing metatables.
Changing method in metatable changes it for all objects, but changing it on one object only changes it for that object.
Otherwise, what you are trying to do sounds like the perfect situation for userdata.
userdata can only be indexed when you have an __index metatmethod (theres no table to put methods in)
What is the advantage of using metatables in my case?
Here's one.
Test.new = function() end
I just destroyed your ability to create new Test objects globally. If you had protected Test with a metatable, I would have had to really work to be able to do that.
Here's another:
local myTest = Test()
You can't do that without a metatable (overload the __call metamethod). And it looks much more natural for Lua syntax than calling Test.new.
And another:
local testAdd = Test() + Test()
Operator overloading. You can't do that without metatables.
Also:
This is exactly what I'm trying Lua to do for me.
Here's a tip: don't.
Different languages are different for a reason. You should do things in Lua the Lua way, not the C++ way. I can understand wanting to provide certain C++ mechanisms (like overloading and so forth), but you shouldn't use new just because that's what C++ uses.
Also, there are plenty of libraries that do this work for you. SWIG and Luabind are two big ones.

Resources