Posted 04 December 2013 - 11:11 PM
Note: I will be using the terms "screen" and "monitor" non-interchangably here. A monitor is a hardware device, a screen is something you display on a monitor.
Background:
I'm building a program that is designed to have several "screens" it can display on a network of wired monitors. Each monitor can have it's own seperate display and ends up acting kinda like a touchscreen thin client connected to the "mainframe" (the actual computer). The whole thing is being built as modular as possible with the code split up and organized into multiple files
The idea is that each of these screens will be loaded as an API and have common functions like scrn1.draw(), button handlers, etc. This way I can keep them in seperate files and the main program is mostly just a loader and contains the event loop. The first goal is to make it act as an elevator controller, where all I need to do is connect a new monitor to the network and follow on-screen instructions to set up the new stop. I'm trying to keep it open-ended though, so if later I want to be able to stick power level monitors or liquid level monitors or anything else all i have to do is program a new screen to fit the templete I've made for myself and plop it in a folder where the main program will automatically load it up. In fact, thanks to Pastebin, I can just upload it to my account, stick it's ID in the main updater program on that same account, and the system will do the rest the next time it's chunk is reloaded. Plug and play on all possible levels, because I am lazy.
Question:
The issue I'm having (at the moment) is thus:
I'm loading the screen APIs with the code below. Is there a way to access those APIs programmatically?
This is all well and good when you know ahead of time that you're going to be putting a file called "config" in your lib folder and after calling loadAPIs("lib") you then directly write config.foo() into your code. But how can I call functions from apis that don't exist when I write the main program? os.loadAPI doesn't return anything or I could just stick pointers to the API into a table like "screens = {lst = <pointer that I'm not getting>}".
Worst-case scenario I know I could make an API of APIs where all it is is a list of variables that point to the screen APIs, but that requires manual editing of more files and I am LAZY… The point is to make adding new content as simple as possible. New monitors are plug-and-play, new screens should be too. Especially if I release this once it's in a release worthy state and other people want to write or modify screens for it.
Not only that, but if I do it that way then my "intro screen" has to be it's own separate entity outside the autoload system.
For the record, I do have the groundwork for this laid and tested: http://imgur.com/fa0JYKT (Not visible to the left is a mockup of my planned elevator shaft, with several more screens with working click counts)
Here I'm using placeholder code to simply write text to the monitors. In full-on go mode instead of m.write("New screen!") it will actually call the initialization screen with the monitor and it's associated data table as arguments. Choosing a screen there will change the active screen variable and tell the main program that that monitor needs to be redrawn. Most screens will even include a button to return to the selection screen. As such, at this point it's just a matter of writing the screens themselves and a way to select them. Admittedly there's a lot of work to be done there and I'm sure I'll need to ask more questions later.
Background:
I'm building a program that is designed to have several "screens" it can display on a network of wired monitors. Each monitor can have it's own seperate display and ends up acting kinda like a touchscreen thin client connected to the "mainframe" (the actual computer). The whole thing is being built as modular as possible with the code split up and organized into multiple files
The idea is that each of these screens will be loaded as an API and have common functions like scrn1.draw(), button handlers, etc. This way I can keep them in seperate files and the main program is mostly just a loader and contains the event loop. The first goal is to make it act as an elevator controller, where all I need to do is connect a new monitor to the network and follow on-screen instructions to set up the new stop. I'm trying to keep it open-ended though, so if later I want to be able to stick power level monitors or liquid level monitors or anything else all i have to do is program a new screen to fit the templete I've made for myself and plop it in a folder where the main program will automatically load it up. In fact, thanks to Pastebin, I can just upload it to my account, stick it's ID in the main updater program on that same account, and the system will do the rest the next time it's chunk is reloaded. Plug and play on all possible levels, because I am lazy.
Question:
The issue I'm having (at the moment) is thus:
I'm loading the screen APIs with the code below. Is there a way to access those APIs programmatically?
function loadAPIs(dir) --Loads all files in a directory
local lst = fs.list(dir)
for i = 1, #lst do
print("Attpemting to load API: " .. lst[i])
os.loadAPI(dir.."/"..lst[i])
end -- for
end -- function()
This is all well and good when you know ahead of time that you're going to be putting a file called "config" in your lib folder and after calling loadAPIs("lib") you then directly write config.foo() into your code. But how can I call functions from apis that don't exist when I write the main program? os.loadAPI doesn't return anything or I could just stick pointers to the API into a table like "screens = {lst = <pointer that I'm not getting>}".
Worst-case scenario I know I could make an API of APIs where all it is is a list of variables that point to the screen APIs, but that requires manual editing of more files and I am LAZY… The point is to make adding new content as simple as possible. New monitors are plug-and-play, new screens should be too. Especially if I release this once it's in a release worthy state and other people want to write or modify screens for it.
Not only that, but if I do it that way then my "intro screen" has to be it's own separate entity outside the autoload system.
For the record, I do have the groundwork for this laid and tested: http://imgur.com/fa0JYKT (Not visible to the left is a mockup of my planned elevator shaft, with several more screens with working click counts)
Here I'm using placeholder code to simply write text to the monitors. In full-on go mode instead of m.write("New screen!") it will actually call the initialization screen with the monitor and it's associated data table as arguments. Choosing a screen there will change the active screen variable and tell the main program that that monitor needs to be redrawn. Most screens will even include a button to return to the selection screen. As such, at this point it's just a matter of writing the screens themselves and a way to select them. Admittedly there's a lot of work to be done there and I'm sure I'll need to ask more questions later.