957 posts
Location
Web Development
Posted 24 March 2015 - 02:13 AM
Do you find yourself making servers and clients often? (Pretend you do)
Do you want a way to quickly create a protocol for them? (Of course)
Then you need…
Protocol ManagerFeatures (Why you want it)Make a set list of messages the client and server will send,
then define functions to run when a message is received
DownloadOn Pastebin:
nps4PsMSIn a computer, run
pastebin get nps4PsMS pm
How to UseThe file has extensive documentationMake sure to read through it!Here is a quick example program that I wrote:
Spoiler
On a computer with a modem on the top:
(Listens for messages and reacts to them)
Spoiler
os.loadAPI("pm") --# Assumes API is called pm
pm.new("testProt",1,true) --# Creates new protocol called 'testProt', it is version 1, true makes it the 'defualt'
pm.addMessage("printHi", function() print("Hi") end) --# When it receives this message, it prints 'hi'
pm.addMessage("printArgs", function(...) print(...) end) --# When it receives this message, it prints the arguments (On one line with no spaces)
m = peripheral.wrap("top")
m.open(1) --# Remember to open channels BEFORE calling waitForMessages()
while true do
pm.waitForMessage() --# This accepts several arguments, but none are needed in this context, see file for documentation!
end
On another computer with a modem on the top:
(Sends the two messages, with a 2 second delay)
Spoiler
os.loadAPI("pm") --# Also needs the API, named 'pm'
pm.new("testProt",1,true) --# Protocol names and versions MUST match on both computers
m = peripheral.wrap("top")
pm.sendMessage(m,1,nil,"printHi") --# Sends first message
sleep(2) --# Waits 2 seconds
pm.sendMessage(m,1,nil,"printArgs","this","is","a","test") --# Sends second message, with several arguments
Bugs and SuggestionsPlease comment with any bugs or suggestions!
Edited on 03 May 2015 - 09:10 PM
808 posts
Posted 24 March 2015 - 05:27 AM
I like the idea, but I'd suggest having the new function return some kind of handle that has the _____Message functions and the event handling functions. Reason being, you don't want your programs handlers to continue running after program execution terminates.
957 posts
Location
Web Development
Posted 24 March 2015 - 10:40 PM
you don't want your programs handlers to continue running after program execution terminates
You lost me :P/>
Are you saying the API can keep running if the program calling it is terminated?
Or do you mean that variables will persist until the comp is restarted?
808 posts
Posted 25 March 2015 - 04:25 AM
you don't want your programs handlers to continue running after program execution terminates
You lost me :P/>
Are you saying the API can keep running if the program calling it is terminated?
Or do you mean that variables will persist until the comp is restarted?
If I write two programs that each use this API, where one adds a protocol, adds a message to listen for, does some stuff, then exits, and the other does the same, any messages on the first program's protocols will still trigger the first program. This is because your API uses the global space of its data, instead of just returning an object that encapsulates what a program would need, so that the program's listeners don't persist past the program's runtime.
957 posts
Location
Web Development
Posted 25 March 2015 - 10:28 PM
-snip-
Messages are stored by protocol name, and if two programs try to use the same name, it errors.
But I see your point, I'll probably do this for my
Screen API too
808 posts
Posted 25 March 2015 - 11:19 PM
-snip-
Messages are stored by protocol name, and if two programs try to use the same name, it errors.
But I see your point, I'll probably do this for my
Screen API too
That's not the issue I meant. If program A registers protocol A, and program B registers protocol B, then when program B calls pm.waitForMessage(), program A's registered callback functions will still get called if anything gets sent on protocol A, even if program A has terminated. This is undesirable.
957 posts
Location
Web Development
Posted 25 March 2015 - 11:59 PM
If program A registers protocol A, and program B registers protocol B, then when program B calls pm.waitForMessage(), program A's registered callback functions will still get called if anything gets sent on protocol A, even if program A has terminated
That shouldn't happen
waitForMessage() requires you to specify which protocol's messages to look for:
--# From the Pastebin, line 118
function waitForMessage(protocol,timeout,useRaw)
protocol = protocol or default
timeout = tonumber(timeout)
nAssert(protocolSets[protocol],"protocol doesn't exist",2)
local pull = useRaw and os.pullEventRaw or os.pullEvent
if timeout then local timer = os.startTimer(timeout) end
while true do
local eArgs = {pull()}
if eArgs[1] == "modem_message" then
if type(eArgs[5]) == "table" and eArgs[5][1] == protocol and eArgs[5][2] == protocolSets[protocol].version then --# The second statment checks that the same protocol sent it, the third then references protocolSets using the protocol name provided in the function call
if protocolSets[protocol][eArgs[5][3]] then
protocolSets[protocol][eArgs[5][3]](eArgs[4],eArgs[6],unpack(eArgs[5][4]))
end
end
elseif eArgs[1] == "timer" and eArgs[2] == timer then
return false
end
end
return false
end
808 posts
Posted 26 March 2015 - 12:52 AM
- snip -
Ah. Your example in the OP doesn't include that. Hence the confusion.
957 posts
Location
Web Development
Posted 26 March 2015 - 01:01 AM
- snip -
Ah. Your example in the OP doesn't include that. Hence the confusion.
Sorry for any confusion :)/>
I have no idea why but it worked when i tested itIt uses the 'defualt' protocol if you don't give it one
The default is set by 'new', thats why I passed true, to set it as the defualt
Even though it doens't look like I HAVE to, I might still change it to an object at some point
Edited on 26 March 2015 - 12:41 AM