I've been hacking away for the past 2-3 hours on a flexible, object-oriented way to implement touchscreen buttons for ComputerCraft. I think I've gotten the main meat of the code down, two classes (Point and Button), implementation, searching and finding functions, button lookup table which can be altered with two simple functions, AddButton() and RemoveButton().
For those who are interested, check the spoiler below...
Just as a note, this code is currently untested, so I'm not sure if it works yet, but I tried to follow the Lua docs and various bits I researched as best as I could. I wanted to go with an object-oriented approach because, as a C# programmer, its the paradigm I'm most used to and the one with which I'm most familiar. I also tried to implement as much run-time type checking as I could, so I could prevent those sneaky little type-related bugs I know can come up if you're not careful, especially with a language that's got more flexible types like Lua.
Anyone spot any problems? Suggestions? Comments? Criticisms? Anyone else come up with a way to make touchscreen monitor buttons for ComputerCraft easier to deal with?
[ETA]
I probably should've commented that code better...alas, spending most of my time working on a programming team consisting of exactly one person (myself), tis not something I'm wholly used to. I will once I've gotten things working and tested, at least.
The whole reason I'm doing this, myself, is to make a monster farming room setup as thus:
Computer 0: The main input computer, hooked up to the touch screen monitor. Whenever a button is clicked, it sends a given message (the evt_msg of the Button class) to the spawn control computer.
Spawn Control Computer: Upon receiving a message, it will have a pre-loaded list associating the messages with colors of RedPower insulated wiring, each one connected to its own, unique creature spawner thru bundled cabling.
Though, this system DOES have one limitation: I'd only be able to have up to 16 spawners connected to the Spawn Control Computer. However, I -could- redirect the rednet messages that Computer 0 normally sends to the SCC to a message interpreting/routing computer, which will associate the received message with a given computer, and pass it along to that computer to toggle the desired spawner.
For those who are interested, check the spoiler below...
Code:
-- BEGIN Point class
Point = { }
Point.__index = Point
function Point.create( x, y )
assert( type( x ) == "number", "Point.create() expects argument 'x' to be number or nil." )
assert( type( y ) == "number", "Point.create() expects argument 'y' to be number or nil." )
local pt = { }
setmetatable( pt, Point )
pt.x = x
pt.y = y
return pt
end
function Point:setX( x )
assert( type( x ) == "number", "Point.setX() expects a number or nil." )
self.x = x
end
function Point:setY( y )
assert( type( y ) == "number", "Point.setY() expects a number or nil." )
self.y = y
end
function Point:getX()
return self.x
end
function Point:getY()
return self.y
end
-- END Point class
-- BEGIN Button class
Button = { }
Button.__index = Button
function Button.create( location, text, event_msg, text_color, back_color )
assert( type( location ) == "Point", "Button constructor expects a Point as first argument." )
assert( type( text ) == "string", "Button constructor expects a string as second argument." )
assert( type( event_msg ) == "string", "Button constructor expects a string as third argument." )
assert( type( text_color ) == "string", "Button constructor expects a string as the fourth argument." )
assert( type( back_color ) == "string", "Button constructor expects a string as the fifth argument." )
local btn = { }
setmetatable( btn, Button )
btn.loc:setX( location:getX() )
brn.loc:setY( location:getY() )
btn.text = text
btn.evt_msg = event_msg -- Message to be passed along whenever Button is clicked
btn.text_color = text_color
btn.back_color = back_color
return btn
end
function Button:setLoc( location )
assert( type( location ) == "Point", "Button:setLoc() expects a Point." )
self.loc:setX( location:getX() )
self.loc:setY( location:getY() )
end
function Button:getLoc()
return self.loc
end
function Button:setText( txt )
assert( type( txt ) == "string", "Button:setText() expects a string." )
self.text = txt
end
function Button:getText()
return self.text
end
function Button:setEventMessage( msg )
assert( type( msg ) == "string", "Button:setEventMessage() expects a string." )
self.evt_msg = msg
end
function Button:getEventMessage()
return self.evt_msg
end
button_table = { }
table_size = 0
function SearchButtonTableByText( text )
assert( type( text ) == "string", "SearchButtonTableByText() expects a string." )
if ( table_size < 1 ) then
return false
else if ( table_size == 1 ) then
if ( button_table[1]:getText() == text ) then
return true
else
return false
end
else
for i = 1, table_size do
if ( button_table[i]:getText() == text ) then
return true
end
end
return false
end
end
function SearchButtonTableByLoc( location )
assert( type( location ) == "Point", "SearchButtonTableByLoc() expects a Point." )
if ( table_size < 1 ) then
return false
else if ( table_size == 1 ) then
if ( button_table[1]:getLoc() == location ) then
return true
else
return false
end
else
for i = 1, table_size do
if ( button_table[i]:getLoc() == location ) then
return true
end
end
return false
end
end
function FindButtonByText( text )
assert( type( text ) == "string", "FindButtonByText() expects a string." )
if ( table_size < 1 ) then
return nil
else if ( table_size == 1 ) then
if ( button_table[1]:getText() == text ) then
return 1
else
return nil
end
else
for i = 1, table_size do
if ( button_table[i]:getText() == text ) then
return i
end
end
return nil
end
end
function FindButtonByLoc( location )
assert( type( location ) == "Point", "FindButtonByLoc() expects a Point." )
if ( table_size < 1 ) then
return nil
else if ( table_size == 1 ) then
if ( button_table[1]:getLoc() == location ) then
return 1
else
return nil
end
else
for i = 1, table_size do
if ( button_table[i]:getLoc() == location ) then
return i
end
end
return nil
end
end
-- AddButton( Button button )
-- Adds a button to the button list, if the text of
-- the passed button doesn't match any other, and if
-- it does not have the same location.
function AddButton( button )
assert( type( button ) == "Button", "AddButton() expects a Button." )
if ( SearchButtonTableByText( button:getText() ) == false ) then
if ( SearchButtonTableByLoc( button:getLoc() ) == false ) then
table.insert( button_list, button )
table_size = table_size + 1
return true
else
return false
end
else
return false
end
end
function RemoveButton( button )
assert( type( button ) == "Button", "RemoveButton() expects a Button." )
if ( FindByText( button:getText() ) != nil ) then
if ( FindByLoc( button:getLoc() ) != nil ) then
table.remove( button_list, FindByText( button:getText() ) )
table_size = table_size - 1
return true
else
return false
end
else
return false
end
end
Just as a note, this code is currently untested, so I'm not sure if it works yet, but I tried to follow the Lua docs and various bits I researched as best as I could. I wanted to go with an object-oriented approach because, as a C# programmer, its the paradigm I'm most used to and the one with which I'm most familiar. I also tried to implement as much run-time type checking as I could, so I could prevent those sneaky little type-related bugs I know can come up if you're not careful, especially with a language that's got more flexible types like Lua.
Anyone spot any problems? Suggestions? Comments? Criticisms? Anyone else come up with a way to make touchscreen monitor buttons for ComputerCraft easier to deal with?
[ETA]
I probably should've commented that code better...alas, spending most of my time working on a programming team consisting of exactly one person (myself), tis not something I'm wholly used to. I will once I've gotten things working and tested, at least.
The whole reason I'm doing this, myself, is to make a monster farming room setup as thus:
Computer 0: The main input computer, hooked up to the touch screen monitor. Whenever a button is clicked, it sends a given message (the evt_msg of the Button class) to the spawn control computer.
Spawn Control Computer: Upon receiving a message, it will have a pre-loaded list associating the messages with colors of RedPower insulated wiring, each one connected to its own, unique creature spawner thru bundled cabling.
Though, this system DOES have one limitation: I'd only be able to have up to 16 spawners connected to the Spawn Control Computer. However, I -could- redirect the rednet messages that Computer 0 normally sends to the SCC to a message interpreting/routing computer, which will associate the received message with a given computer, and pass it along to that computer to toggle the desired spawner.