File size: 3,339 Bytes
2130399 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
""" Generic Base Class for interfacing with a soar agent's input/output links
A Connector can be added to a SoarClient and can handle input/output
while taking care of specific SML calls and event registering
"""
from __future__ import print_function
import traceback, sys
class AgentConnector(object):
""" Base Class for handling input/output for a soar agent
Input:
on_input_phase will be automatically called before each input phase
Output:
call add_output_command to add the name of an output-link command to look for
on_output_event will then be called if such a command is added by the agent
Look at LanguageConnector for an example of an AgentConnector used in practice
"""
def __init__(self, client):
""" Initialize the Connector (but won't register event handlers until connect)
client should be an instance of SoarClient
"""
self.client = client
self.connected = False
self.output_handler_ids = { }
def add_output_command(self, command_name):
""" Will cause the connector to handle commands with the given name on the output-link """
if self.connected:
self.output_handler_ids[command_name] = self.client.agent.AddOutputHandler(
command_name, AgentConnector._output_event_handler, self)
else:
self.output_handler_ids[command_name] = -1
def connect(self):
""" Adds event handlers, automatically called by the SoarClient """
if self.connected:
return
for command_name in self.output_handler_ids:
self.output_handler_ids[command_name] = self.client.agent.AddOutputHandler(
command_name, AgentConnector._output_event_handler, self)
self.connected = True
def disconnect(self):
""" Removes event handlers, automatically called by the SoarClient """
if not self.connected:
return
for command_name in self.output_handler_ids:
self.client.agent.RemoveOutputHandler(self.output_handler_ids[command_name])
self.output_handler_ids[command_name] = -1
self.connected = False
def on_init_soar(self):
""" Override to handle an init-soar event (remove references to SML objects """
pass
def on_input_phase(self, input_link):
""" Override to update working memory, automatically called before each input phase """
pass
def on_output_event(self, command_name, root_id):
""" Override to handle output commands with the given name (added by add_output_command)
root_id is the root Identifier of the command (e.g. (<output-link> ^command_name <root_id>)
"""
pass
@staticmethod
def _output_event_handler(self, agent_name, att_name, wme):
""" OutputHandler callback for when a command is put on the output link """
try:
if wme.IsJustAdded() and wme.IsIdentifier():
root_id = wme.ConvertToIdentifier()
self.on_output_event(att_name, root_id)
except:
self.client.print_handler("ERROR IN OUTPUT EVENT HANDLER")
self.client.print_handler(traceback.format_exc())
self.client.print_handler("--------- END ---------------")
|