""" 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. ( ^command_name ) """ 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 ---------------")