Remote agent/Agent interface: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
(Go solution)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(9 intermediate revisions by 5 users not shown)
Line 1:
{{draft task}}
{{draft task}}In [[Remote agent]], a component is described that marshals commands and events between a stream and a program that issues commands and processes the resulting events. Using the protocol definition described there, build this component in a fashion idiomatic and natural to your language.
 
In [[Remote agent]], a component is described that marshals commands and events between a stream and a program that issues commands and processes the resulting events.
 
 
;Task:
Using the protocol definition described there, build this component in a fashion idiomatic and natural to your language.
<br><br>
 
=={{header|C}}==
Line 5 ⟶ 12:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package ifc
 
// Streamer interface type defines how agent and world talk to each other.
Line 42 ⟶ 49:
EvNoBallInSector = 's'
EvNoBallInAgent = 'a'
)</langsyntaxhighlight>
Above is the interface package defining the abstract interface. Below is an example of a driver program that supplies a concrete implementation of the interface. This implementation uses Go channels to run a simulation in a single process. A different implementation might produce two executables that would run on different processes or different machines. It would use the same interface however.
<langsyntaxhighlight lang="go">package main
 
import (
Line 92 ⟶ 99:
// point. The program terminates immediately when World returns.
world.World(chanStreamer{"world", cmd, ev})
}</langsyntaxhighlight>
A separate file, but still part of the driver, contains human readable text for commands and events. Alternatively, this file could be included with the interface package for maintainability, but technically it is not a required part of the abstract interface used by the agent and world simulator.
<langsyntaxhighlight lang="go">package main
 
import "ra/ifc"
Line 120 ⟶ 127:
ifc.EvNoBallInSector: "event no ball in sector",
ifc.EvNoBallInAgent: "event no ball in agent",
}</langsyntaxhighlight>
 
 
=={{header|Julia}}==
See [[Remote agent/Agent_interface/Julia]]
 
=={{header|Phix}}==
=== abstract interface ===
Modify this to include one of the two concrete implementations below (but not both!)
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Remote_Agent_Interface.exw
-- =======================================
--
-- First, a handful of common constants, just to avoid the duplication:</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">enum</span> <span style="color: #000000;">North</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">East</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">South</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">West</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">constant</span> <span style="color: #000000;">dxy</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},{-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}}</span>
<span style="color: #000080;font-style:italic;">-- and some display/progress routines:</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">args</span><span style="color: #0000FF;">={})</span>
<span style="color: #7060A8;">position</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">,</span><span style="color: #000000;">args</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">pause</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">what</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">yoffset</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">fn</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">sequence</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">balls</span><span style="color: #0000FF;">},</span> <span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ball</span><span style="color: #0000FF;">}}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">yoffset</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s -- x:%2d, y:%2d, ball:%c, d:%d "</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">what</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ball</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">}))</span>
<span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"^&gt;v&lt;"</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">yoffset</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">yoffset</span><span style="color: #0000FF;">,</span><span style="color: #000000;">40</span><span style="color: #0000FF;">,</span><span style="color: #000000;">balls</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">event</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"(after "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">event</span><span style="color: #0000FF;">&</span><span style="color: #008000;">" accepted by %s)"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">what</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">pause</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">die</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- (to avoid clobbering the above display)</span>
<span style="color: #7060A8;">position</span><span style="color: #0000FF;">(</span><span style="color: #000000;">35</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #000000;">msg</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000080;font-style:italic;">--
-- Only one of the following should be included, the other(s) commented out:
--</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">Remote_Agent_Interface_Direct</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #000080;font-style:italic;">--include Remote_Agent_Interface_IPC.e
--include Remote_Agent_Interface_Xxx.e -- (no such file, see below)
--
-- each of the above must implement
--
-- global procedure register_world(integer accept_command, get_event, get_world=0)
-- global procedure register_agent(integer get_command, accept_event, get_agent=0)
--
-- The four mandatory and two optional routines to be provided are described below.
-- Note that Remote_Agent_Interface_Direct returns control immediately,
-- to one, whereas Remote_Agent_Interface_IPC does not, see below.
--
-- Remote_Agent_Interface_Direct.e includes both
-- Remote_Agent_Simulator.exw and
-- Remote_Agent_Agent_Logic.exw, and operates as a fully complete and
-- standalone program whichever of the three .exw files are invoked.
-- (Running &gt;1 of them effectively runs the same program &gt;1 times.)
--
-- Remote_Agent_Interface_IPC.e includes neither, and instead both of
-- Remote_Agent_Simulator.exw and
-- Remote_Agent_Agent_Logic.exw must be run separately.
-- (Running Remote_Agent_Interface.exw does nothing in that case.)
--
-- The idea is that further Remote_Agent_Interface_Xxx.e could be written
-- to implement pipes, sockets, files, etc. and nothing in either of the
-- other two .exw would need changing for them to work like IPC.e does.
--
-- There would of course be no problem with world/agent including those
-- files directly, as long as they are kept in sync, but of course that
-- way would lose the "no modification whatsoever to switch" aspect.
--
-- The Direct version checks whether both register_world and register_client
-- have been invoked before starting a single event loop, otherwise returns
-- control immediately, effectively terminating one of world/client, whereas
-- the IPC way sets up separate event loops in/for both register_world and
-- register_client, and only returns control on game over (if even that).
--
-- Both world/client must operate reactively and maintain any internal state
-- that requires. For instance when the server receives a "forward" command
-- it cannot send color; send ball; send stop; but must instead rely on
-- being later asked for those events, and deliver them in order.
--
-- Both get_event() and get_command() must be a parameterless function that
-- returns a single byte, and both accept_command() and accept_event() must
-- be a procedure that accepts a single byte. As you should expect you use
-- () to invoke them, and omit the () when just passing their ids about.
-- The get_xxxx() routines, if provided, should return the current state
-- in a suitable format for use as per fn() in show() above.
--</span>
<!--</syntaxhighlight>-->
 
=== Interface_Direct ===
This implementation of the above interface is a single standalone program
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Remote_Agent_Interface_Direct.e
-- ============================================
--</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">Remote_Agent_Simulator</span><span style="color: #0000FF;">.</span><span style="color: #000000;">exw</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">Remote_Agent_Agent_Logic</span><span style="color: #0000FF;">.</span><span style="color: #000000;">exw</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">accept_command</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_world</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">get_command</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">accept_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_agent</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main_event_loop</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">handshake</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_event</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">handshake</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">65</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"server handshake recieved"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">handshake</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_command</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">handshake</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">65</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"agent handshake recieved"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">command</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_command</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"agent"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">22</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_agent</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">accept_command</span><span style="color: #0000FF;">(</span><span style="color: #000000;">command</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"world"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">command</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_world</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">event</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_event</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'+'</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- game over</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"world"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_world</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"agent"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">22</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_agent</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">66</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"game over"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">accept_event</span><span style="color: #0000FF;">(</span><span style="color: #000000;">event</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"world"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_world</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"agent"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">event</span><span style="color: #0000FF;">,</span><span style="color: #000000;">22</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_agent</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- stop</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">register_world</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">_accept_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">_get_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">_get_world</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">accept_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_world</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">_accept_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">_get_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">_get_world</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">get_command</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">main_event_loop</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">register_agent</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">_get_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">_accept_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">_get_agent</span><span style="color: #0000FF;">=</span><span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">get_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">accept_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_agent</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">_get_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">_accept_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">_get_agent</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">accept_command</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">main_event_loop</span><span style="color: #0000FF;">()</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<!--</syntaxhighlight>-->
 
=== Interface_IPC ===
This implementation of the above interface lets two separate programs communicate using ipc
<!--<syntaxhighlight lang="phix">(notonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Remote_Agent_Interface_IPC.e
-- =========================================
--</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">\</span><span style="color: #000000;">ipc</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #000080;font-style:italic;">-- The shared memory contains two bytes:
-- byte[1] (command) can only be set by the agent and cleared by the world,
-- byte[2] ( event ) can only be set by the world and cleared by the agent.</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">ra</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"remote_agent"</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">pSharedMem</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sm_open</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ra</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SM_OPEN_FAIL</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">pSharedMem</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sm_create</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ra</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"unable to create shared memory"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">poke2</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- initialised to zero bytes</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">send_command_via_ipc</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">command</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">peek</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">,</span><span style="color: #000000;">command</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">get_command_from_ipc</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">command</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">command</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">peek</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">command</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">command</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">send_event_via_ipc</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">peek</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">event</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">get_event_from_ipc</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">event</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">event</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">peek</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">sleep</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0.1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">poke</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pSharedMem</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">event</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">game_over</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">32</span><span style="color: #0000FF;">,</span><span style="color: #000000;">62</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"game over"</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">register_world</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">accept_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_world</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">event</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_event</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">die</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rw1"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">send_event_via_ipc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">event</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">command</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_command_from_ipc</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">command</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">die</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rw2"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">60</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"server handshake recieved"</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- server loop:</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">command</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_command_from_ipc</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">command</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'+'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">game_over</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">accept_command</span><span style="color: #0000FF;">(</span><span style="color: #000000;">command</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"world"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">command</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_world</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">event</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_event</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">send_event_via_ipc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">event</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- stop</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">register_agent</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">get_command</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">accept_event</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">get_agent</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">command</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_command</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">command</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">die</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"ra1"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">send_command_via_ipc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">command</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">event</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_event_from_ipc</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">!=</span><span style="color: #008000;">'A'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">die</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"ra2"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">show_at</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">60</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"agent handshake recieved"</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- agent loop:</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">command</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_command</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">send_command_via_ipc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">command</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">event</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_event_from_ipc</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'+'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">send_command_via_ipc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">event</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"agent"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">,</span><span style="color: #000000;">22</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_agent</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">game_over</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">accept_event</span><span style="color: #0000FF;">(</span><span style="color: #000000;">event</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"agent"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">event</span><span style="color: #0000FF;">,</span><span style="color: #000000;">22</span><span style="color: #0000FF;">,</span><span style="color: #000000;">get_agent</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">event</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- stop</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<!--</syntaxhighlight>-->
 
=={{header|PicoLisp}}==
Line 127 ⟶ 403:
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
 
oo::class create AgentAPI {
Line 250 ⟶ 526:
 
# Export as package
package provide RC::RemoteAgent 1</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
Unlike the Go entry, I've placed the 'human readable text' code inside the 'ifc' module and have also placed a basic logging facility in there too as its called by both the 'world' and 'agent' modules. It always prints to stdout.
 
I've changed the 'handshake' symbol from "A" to "H" to distinguish it from 'evAgentFull'.
 
The 'driver code' has been moved to the [[Remote_agent/Simulation]] task.
<syntaxhighlight lang="wren">/* ifc.wren */
 
import "./fmt" for Fmt
 
// The Streamer abstract class defines how agent and world talk to each other.
// If implemented in Wren, send and rec will be synchronous blocking operations.
class Streamer {
send(ch) {}
rec() {}
}
 
// The agent and world send and receive single characters, out of the set of
// constants defined here.
class Ifc {
static handshake { "H" }
static cmdForward { "^" }
static cmdRight { ">" }
static cmdLeft { "<" }
static cmdGet { "@" }
static cmdDrop { "!" }
static evGameOver { "+" }
static evStop { "." }
static evColorRed { "R" }
static evColorGreen { "G" }
static evColorYellow { "Y" }
static evColorBlue { "B" }
static evBallRed { "r" }
static evBallGreen { "g" }
static evBallYellow { "y" }
static evBallBlue { "b" }
static evBump { "|" }
static evSectorFull { "S" }
static evAgentFull { "A" }
static evNoBallInSector { "s" }
static evNoBallInAgent { "a" }
 
// Human readable text for the above commands and events.
static init_() {
__hrText = {
handshake : "handshake",
cmdForward : "command forward",
cmdRight : "command turn right",
cmdLeft : "command turn left",
cmdGet : "command get",
cmdDrop : "command drop",
evGameOver : "event game over",
evStop : "event stop",
evColorRed : "event color red",
evColorGreen : "event color green",
evColorYellow : "event color yellow",
evColorBlue : "event color blue",
evBallRed : "event ball red",
evBallGreen : "event ball green",
evBallYellow : "event ball yellow",
evBallBlue : "event ball blue",
evBump : "event bump",
evSectorFull : "event sector full",
evAgentFull : "event agent full",
evNoBallInSector : "event no ball in sector",
evNoBallInAgent : "event no ball in agent"
}
}
 
static text { __hrText }
}
 
class Log {
static prefix=(p) { __prefix = Fmt.swrite("$06d: ", p) }
 
static print(s) { System.print(__prefix + s) }
 
static fatal(s) { Fiber.abort(s) }
}
 
Ifc.init_()</syntaxhighlight>
9,488

edits