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

Protocol Manager

Started by HPWebcamAble, 24 March 2015 - 01:13 AM
HPWebcamAble #1
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 Manager


Features (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


Download

On Pastebin: nps4PsMS

In a computer, run

pastebin get nps4PsMS pm


How to Use

The file has extensive documentation
Make sure to read through it!


Here is a quick example program that I wrote:
SpoilerOn 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 Suggestions

Please comment with any bugs or suggestions!
Edited on 03 May 2015 - 09:10 PM
ElvishJerricco #2
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.
HPWebcamAble #3
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?
ElvishJerricco #4
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.
HPWebcamAble #5
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
ElvishJerricco #6
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.
HPWebcamAble #7
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
ElvishJerricco #8
Posted 26 March 2015 - 12:52 AM
- snip -

Ah. Your example in the OP doesn't include that. Hence the confusion.
HPWebcamAble #9
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 it

It 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