Jump to content
The simFlight Network Forums

Specifiying function name for event.offset


Recommended Posts

I would like to be able to call event.offset(offset, type, "fn") where fn is a function in a Lua module included in the main program with a "require" statement. It is possible to do this by making "fn" the name of a function in the main program that in turn calls the function in the module, but that means that the main program has to know about details of the "required" module, and that's undesirable. That I can't make it work can be seen in the code that follows ... "Event proc not found". Is what I want possible using WideClient?

Richard

What follows are two very short Lua programs, one that resides in the modules subdirectory, and a "main" program to be run by WideClient.

--==========Start of file "modules\M.lua"==============

module(..., package.seeall)

function f(offset, value)
	print(string.format("heading %d", value))  -- ignoring scaling needed in the real code
end

-- this doesn't work
--event.offset(0x7CC, "UW", "f")
--==============end of file===============

-- Start of Initial.lua
require "M"

function doit(offset, value)
	M.f(offset, value)
end

-- these both print "type function"
print(string.format("Trying M.f, type %s", type(M.f)))
print(string.format('Trying _G["M"]["f"] , type %s', type(_G["M"]["f"])))

-- this works
event.offset(0x7CC, "UW", "doit")

-- these don't.  They both generate a compile time error 
--[[
********* LUA: "Initial" Log [from WideClient] *********
Date (dmy): 07/02/11, Time 16:46:36.415: Client name is FRANZ
  	546 LUA: beginning "C:\Do Flight\Initial.LUA"
  	561 LUA: Trying M.f, type function                           		-- from the print statement above
  	561 LUA: Trying _G["M"]["f"] , type function             		-- ditto
  	561 *** LUA Error: C:\Do Flight\Initial.LUA:27: Event proc not found
  	561 LUA: ended "C:\Do Flight\Initial.LUA"
********* LUA execution terminated: Log Closed *********
--]]
--[[  -- remove the comment delineators to see the error
event.offset(0x07CC, "UW", '_G["M"]["f"]')  -- heading bug
event.offset(0x07CC, "UW", "M.f")  -- heading bug
--]]
--===============end of file====================

Link to comment
Share on other sites

I would like to be able to call event.offset(offset, type, "fn") where fn is a function in a Lua module included in the main program with a "require" statement.

Hmm. I don't (yet) know how to do that. At present the procedure is obtained by using the C function "lua_getglobal". This references the globals index by LUA_GLOBALSINDEX. Evidently that doesn't contain all the names in modules even as a list named for the module, or if it does just using "getglobal" with the string name "m.fn" doesn't cut it.

I've had another read through the relevant sections of the Lua books I have and I don't think I understand the internal data structures well enough to know how to implement it. Obviously the interpreter must know where "m.f" is but how do I call it from C code? The lua_pcall function needs the function pushed onto the stack. I get that using lua_getglobal. Do you know how to make that work with functions in a module?

What happens if you define local names for the functions in the module, like

myf = m.fn

and then use "myf" as the function. Does that work?

Maybe I have to parse the string to separate "m" from "fn". Then get "m" as a global, check that it's a table (lua_istable) and then, if it is, see if I can access the field in it named "fn" and check that's a function. I might experiment on those lines. Of course it could go further. "m.t.fn" there t is a table of functions in module m. Et cetera. I'd have to keep going whilst I found tables till i found a function. Hmmm.

It is possible to do this by making "fn" the name of a function in the main program that in turn calls the function in the module, but that means that the main program has to know about details of the "required" module, and that's undesirable.

But that makes no sense. If you know "f" is a function in "M" then you can call it from a local function in the main program. What's the difference between doing that and making it a literal string in the event library call? Either way the main program has to know that function f is in module M.

What follows are two very short Lua programs, one that resides in the modules subdirectory, and a "main" program to be run by WideClient.

I assume you don't mean the FS modules folder? ;-)

Regards

Pete

Link to comment
Share on other sites

Hmm. I don't (yet) know how to do that. At present the procedure is obtained by using the C function "lua_getglobal". This references the globals index by LUA_GLOBALSINDEX. Evidently that doesn't contain all the names in modules even as a list named for the module, or if it does just using "getglobal" with the string name "m.fn" doesn't cut it.

I've had another read through the relevant sections of the Lua books I have and I don't think I understand the internal data structures well enough to know how to implement it. Obviously the interpreter must know where "m.f" is but how do I call it from C code? The lua_pcall function needs the function pushed onto the stack. I get that using lua_getglobal. Do you know how to make that work with functions in a module?

What happens if you define local names for the functions in the module, like

myf = m.fn

and then use "myf" as the function. Does that work?

Maybe I have to parse the string to separate "m" from "fn". Then get "m" as a global, check that it's a table (lua_istable) and then, if it is, see if I can access the field in it named "fn" and check that's a function. I might experiment on those lines. Of course it could go further. "m.t.fn" there t is a table of functions in module m. Et cetera. I'd have to keep going whilst I found tables till i found a function. Hmmm.

But that makes no sense. If you know "f" is a function in "M" then you can call it from a local function in the main program. What's the difference between doing that and making it a literal string in the event library call? Either way the main program has to know that function f is in module M.

I assume you don't mean the FS modules folder? ;-)

Regards

Pete

Last things first, correct, I don't mean the FS modules folder, but one I created as a sub directory of the folder in which WideClient is located. Then "require" knows where to look without my doing anything with the package loaded/loadlib/etc code. I'm very new to Lua and there are vast areas in which mis-understanding could get me lost for a long time<g>. Which means I know nothing about the C code underlying Lua.

A quick test says that "myf = M.f" does work. But I don't want the top level code to know what's in M, so to speak. I'll have to experiment more with name passing though my data structures, though I may not have time to do so for a day. Since myf = M.f worked (at least once<g>), I'm wondering if the code in the event library (or the C code it calls) does some massaging of the string function, like removing brackets, dots, and the like, to make it a simple name.I have experimented a bit with printing out environments and it looks as if everything is where one expects it (and event.offset should be able to see the modular structure). Too bad the error message doesn't say which proc not found.

Richard

Link to comment
Share on other sites

Last things first, correct, I don't mean the FS modules folder, but one I created as a sub directory of the folder in which WideClient is located. Then "require" knows where to look without my doing anything with the package loaded/loadlib/etc code. I'm very new to Lua and there are vast areas in which mis-understanding could get me lost for a long time<g>. Which means I know nothing about the C code underlying Lua.

A quick test says that "myf = M.f" does work. But I don't want the top level code to know what's in M, so to speak. I'll have to experiment more with name passing though my data structures, though I may not have time to do so for a day. Since myf = M.f worked (at least once<g>), I'm wondering if the code in the event library (or the C code it calls) does some massaging of the string function, like removing brackets, dots, and the like, to make it a simple name.I have experimented a bit with printing out environments and it looks as if everything is where one expects it (and event.offset should be able to see the modular structure). Too bad the error message doesn't say which proc not found.

Richard

Found a comment that says that Lua_getglobal does not handle "." Maybe it doesn't handle "[]" notation either.

Link to comment
Share on other sites

A quick test says that "myf = M.f" does work.

Okay. That helps. Probabably if I parse the string "M.f" and step down through tables it will work. I'll try it and let you know.

But I don't want the top level code to know what's in M, so to speak.

So if it doesn't know that "f" is in "M" how does it know to use the string "M.f" in the event function?

Since myf = M.f worked (at least once<g>), I'm wondering if the code in the event library (or the C code it calls) does some massaging of the string function, like removing brackets, dots, and the like, to make it a simple name.

No, it's my code. I'm calling a function called "getglobal" which takes the name and returns the function pointer for me to call. "M.f" is not a function name but a table name (M) and a function name "f".

I think it's just that the getglobal call doesn't parse the name to separate table pointer and content. I'll need to do that in my code I think.

Too bad the error message doesn't say which proc not found.

Unless you put everything on one line, surely the line number is a BIG clue? I use "ultraedit32" as my editor and that provides line numbers.

Regards

Pete

Link to comment
Share on other sites

Okay. That helps. Probably if I parse the string "M.f" and step down through tables it will work. I'll try it and let you know.

Yes, it works. I've allowed functions in tables ("M.fn") and functions in tables in tables, etc ( "M.t.fn" etc), up to a limit of 63 characters between the "".

Facility added in FSUIPC 3.989x, 4.662 and WideClient 6.843 now available from the Download Links subforum.

Regards

Pete

Link to comment
Share on other sites

Yes, it works. I've allowed functions in tables ("M.fn") and functions in tables in tables, etc ( "M.t.fn" etc), up to a limit of 63 characters between the "".

Facility added in FSUIPC 3.989x, 4.662 and WideClient 6.843 now available from the Download Links subforum.

Regards

Pete

Ah, how pleasant. That works very nicely. Code is much cleaner now. I just ran across this note on stack overflow. I imagine this is what you're doing. This function is really useful at runtime to construct function "pointers" when you have the name (string) and the name of the module (string) in which the function resides. Of course, often, the module name is the file name, but probably it's better if that doesn't appear in the code explicitly. Something like

module(..., package.seeall)
modname = ... .. "."   --best use of 5 periods in a Lua statement!?

fn = findfunction(modname .. "some function name as string")
--pass this fn in data structures and it can be used without needing to resolve the "." structure

On an irrelevant matter, yes I do use an editor with line numbers. After over three decades of Unix, I'm a vi addict and so use gvim. Newer editors handle class structure and the like better, but ...

Richard

Link to comment
Share on other sites

I just ran across this note on stack overflow. I imagine this is what you're doing.

No. My code is in C and calls the exported C routines in the Lua interpreter -- I just split off the names using the '.' delimiter and use "lua_getfield", iteratively whilst they refer to tables (checked using "lua_istable") till I reach a function (checked by using "lua_isfunction").

Previously I was just using "lua_getglobal" (which is a special case of "lua_getfield") and "lua_isfunction". It's very similar still except for burrowing through tables.

Regards

Pete

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.