This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Ditto8353's profile picture

[Lua][Help] Program Structure

Started by Ditto8353, 17 October 2012 - 03:04 PM
Ditto8353 #1
Posted 17 October 2012 - 05:04 PM
I figured I would start my first major project, a single terminal to control all turtles connected to it via rednet. I'm sure it's been done before, but not by me, and I have been bored.

What I am asking for is some help figuring out the structure of the program to achieve maximum efficiency. Currently my structure is as follows:

Classes:
Turtle - Used to remember turtles connected to the system as well as track position and issue commands.
Menu - Used to handle menu navigation, display, and execution.

local turtles = Turtle:new()
local menu = Menu:new({"Accept New Turtle",getTurtle},{"Quit",os.shutdown})
while true do
	 local evt = {os.pullEvent()}
	 EventHandler[evt[1]](evt,menu)
end

This is my first sticking point. EventHandler is a table such as {["key"] = func} where func is a function designed to handle all "key" events. However, I must pass the menu to this function in order to properly call Menu:up() which moves the menu selection up, not a major issue, but I then have to return that menu in order to keep an up-to-date version to send to the next "key" event. When this is combined with the fact that I must send the 'turtle' table to the menu in order to properly call turtle functions from the menu, it becomes less and less efficient, and even more convoluted.

I have been contemplating a few solutions, but since I am fairly new to the Lua language and environment I would like some more experienced opinions.
1. Global turtle table and menu table.
[indent=1]This looks like the simplest option so far, but I do not fully understand the effects this could have of the program's efficiency.[/indent]
2. Move logic into Menu class.
[indent=1]This looks to be the most efficient to me, but if I introduce sub-menus then I will run into the same problem again.[/indent]
3. Any other suggestions?
Ditto8353 #2
Posted 17 October 2012 - 09:01 PM
A decent amount of views, but no suggestions.

One sad little bump before I let it die.
Lyqyd #3
Posted 17 October 2012 - 10:37 PM
I'd separate things out a bit more. The menu should be fairly task-agnostic and autonomous. You give it a simple table of options, it gives back the index of the chosen entry.

You will probably want to separate out your rednet handler if you need to be able to respond to incoming traffic while in the menus. This is relatively simple to do, just hook os.pullEvent before you start the rest of your program.

Alternatively, you could use a simpler menu system, encasing each menu in a function call in the main program. Handle rednet_message events in each of these in a single function. This does simplify things greatly.

It would help to know more about how the workflow in the program is intended to go.
CoolisTheName007 #4
Posted 19 October 2012 - 10:12 PM
Global variables would do the job, because then you would be passing a reference to the table, to the event handler, not duplicating the table.
In fact, I don't understand why using local variables would complicate anything, since in your case they are tables, and so variables are just pointers to the table in question. Event Handler and menu shouldn't need to return them, only to modify them. Example of this property of tables.:

local a=1
--integers,strings and bools: one variable (the name) points to a object, that is uniquely determined by his value
function b(r)
	r=2
end
print(a)
b(a)
print(a)
--tables are different: multiple variables can point to the same table, and you can have two different tables with the same index/value pairs
ocal a={1,2}
function b(r)
	r[1]=2 --the value at index 1 of whatever r is pointing at is altered to 2
end
print(a[1])
b(a)--passes the variable a to b
print(a[1])
--if you create a new table inside the function b, the variable r points to a different table
local a={1,2}
function b(r)
	r={2,3}
end
print(a[1])
b(a)
print(a[1])
Output:
1
1
1
1
1
2
Sammich Lord #5
Posted 19 October 2012 - 11:10 PM
Well this is actually quite simple. Have everything be in parallel so you can receive info from turtles and still be in the menu. Have a table of all connected turtles and a table for all receive and sent commands.(So you can keep track and view history from the menu.) Then have the menu have some simple buttons to ping, issue commands, and add/remove turtles from the main database of turtles. You will also want to ping each turtle about every 5 seconds to ensure they are still connected. I would suggest having everything color-coded and have a nice display to display the history of commands and connected turtles.