Soar Kernel  9.3.2 08-06-12
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
io_soar.h
Go to the documentation of this file.
1 /*************************************************************************
2  * PLEASE SEE THE FILE "license.txt" (INCLUDED WITH THIS SOFTWARE PACKAGE)
3  * FOR LICENSE AND COPYRIGHT INFORMATION.
4  *************************************************************************/
5 
6 /* =======================================================================
7  io_soar.h
8 
9  General Soar I/O System Routines
10 
11  User-defined Soar I/O routines should be added at system startup time
12  via calls to add_input_function() and add_output_function(). These
13  calls add things to the system's list of (1) functions to be called
14  every input cycle, and (2) symbol-to-function mappings for output
15  commands. File io.cpp contains the system I/O mechanism itself (i.e.,
16  the stuff that calls the input and output functions), plus the text
17  I/O routines.
18 
19  Init_soar_io() does what it say. Do_input_cycle() and do_output_cycle()
20  perform the entire input and output cycles -- these routines are called
21  once per elaboration cycle. (once per Decision cycle in Soar 8).
22  The output module is notified about WM changes via a call to
23  inform_output_module_of_wm_changes().
24 ======================================================================= */
25 
26 #ifndef IO_H
27 #define IO_H
28 
29 #include "callback.h"
30 
31 #ifdef __cplusplus
32 //extern "C"
33 //{
34 #endif
35 
36 typedef char Bool;
37 typedef unsigned char byte;
38 typedef struct cons_struct cons;
39 typedef struct wme_struct wme;
40 typedef struct agent_struct agent;
42 typedef cons list;
43 typedef union symbol_union Symbol;
44 
45 typedef void * soar_callback_data;
46 typedef void * soar_call_data;
47 
48 extern void init_soar_io (agent* thisAgent);
49 extern void do_input_cycle (agent* thisAgent);
50 extern void do_output_cycle (agent* thisAgent);
51 
52 extern void inform_output_module_of_wm_changes (agent* thisAgent,
53  ::list *wmes_being_added,
54  ::list *wmes_being_removed);
55 
57  char **text_read_position); /* in io.cpp */
58 
59 /* =======================================================================
60  Input Functions
61 
62  Input functions take one parameter--a mode (integer) indicating why the
63  function is being called. The mode is either TOP_STATE_JUST_CREATED,
64  NORMAL_INPUT_CYCLE, or TOP_STATE_JUST_REMOVED. In the input cycle
65  immediately following the installation of the top state, each input
66  function is called once with TOP_STATE_JUST_CREATED and then once with
67  NORMAL_INPUT_CYCLE. In the input cycle immediately following the removal
68  of the top state, the functions are called with TOP_STATE_JUST_REMOVED.
69  If the top state is *replaced*, the functions are called with
70  TOP_STATE_JUST_REMOVED, then TOP_STATE_JUST_CREATED, and then
71  NORMAL_INPUT_CYCLE.
72 
73  Input routines create, modify, and delete input structures via calls
74  to add_input_wme() and remove_input_wme(). The arguments to add_input_wme()
75  indicate the id/attr/value components of the wme to be added. Each of
76  these components must be either (1) the current value of the global
77  variable "top_state", or (2) the returned value from a call to
78  get_new_io_identifier(), get_io_sym_constant(), get_io_int_constant(),
79  or get_io_float_constant(). [The idea behind creating the components this
80  way is to avoid having I/O functions deal with the reference counts on
81  symbols.] For every call an I/O function makes to get_xxx(), it should
82  later call release_io_symbol(). Release_io_symbol() should *not* be
83  called with the value of "top_state"--*only* the components obtained via
84  get_xxx().
85 
86  The add_input_wme() routine returns a pointer to the wme added. The input
87  routine shouldn't use this pointer in any way except to save it around for
88  a later call to remove_input_wme(). Example:
89 
90  float current_sensor_value;
91  wme *w;
92  Symbol *s1,*s2;
93  ... insert code to read value into current_sensor_value here ...
94  s1 = get_io_sym_constant ("sensor-value");
95  s2 = get_io_float_constant (current_sensor_value);
96  ... add to working memory (S1 ^sensor-value 37.5) ...
97  w = add_input_wme (top_state, s1, s2);
98  release_io_symbol (s1);
99  release_io_symbol (s2);
100 
101  On some later call, the input function might call remove_input_wme (w)
102  to remove (S1 ^sensor-value 37.5) from working memory.
103 
104  To remove an entire input structure, it is sufficient for the input
105  function to call remove_input_wme() on just the top link wme. The input
106  function need not call remove_input_wme() on each and every wme in the
107  structure. (Soar automagically garbage collects all the wmes in the
108  now-disconnected structure.) Note that when an input function is called
109  with TOP_STATE_JUST_REMOVED, all existing input structures have already
110  been garbage collected (since the top state no longer exists), so the
111  input function should never call remove_input_wme() when mode is
112  TOP_STATE_JUST_REMOVED. Remove_input_wme() normally returns TRUE,
113  indicating success. It returns FALSE if an error occurs (e.g., if the
114  wme argument isn't in WM).
115 ======================================================================= */
116 
117 #define TOP_STATE_JUST_CREATED 1
118 #define NORMAL_INPUT_CYCLE 2
119 #define TOP_STATE_JUST_REMOVED 3
120 
121 extern Symbol *get_new_io_identifier(agent* thisAgent, char first_letter) ;
122 extern Symbol *get_io_identifier (agent* thisAgent, char first_letter, uint64_t number);
123 extern Symbol *get_io_sym_constant (agent* thisAgent, char const *name);
124 extern Symbol *get_io_int_constant (agent* thisAgent, int64_t value);
125 extern Symbol *get_io_float_constant (agent* thisAgent, double value);
126 extern uint64_t release_io_symbol (agent* thisAgent, Symbol *sym);
127 
128 extern wme *add_input_wme (agent* thisAgent, Symbol *id, Symbol *attr, Symbol *value);
129 extern Bool remove_input_wme (agent* thisAgent, wme *w);
130 
131 /* =======================================================================
132  Output Functions
133 
134  Output functions take two parameters--a mode (integer) indicating why the
135  function is being called, and a pointer to a chain of io_wme structures.
136  The mode is either ADDED_OUTPUT_COMMAND (used when an output link is first
137  created), MODIFIED_OUTPUT_COMMAND (used when the transitive closure of an
138  existing link changes), or REMOVED_OUTPUT_COMMAND (used when the output
139  link is removed from working memory).
140 
141  The chain of io_wme structures is connected via the "next" fields in the
142  structures; for the last io_wme, next==NIL. When mode is either
143  ADDED_OUTPUT_COMMAND or MODIFIED_OUTPUT_COMMAND, this chain contains
144  all the wmes in the current transitive closure of the output link
145  (including the output link wme itself). When mode is
146  REMOVED_OUTPUT_COMMAND, the chain consists of just one io_wme--the top-level
147  ouput link being removed.
148 
149  Output functions should inspect the io_wme chain and take whatever
150  actions are appropriate. Note that Soar deallocates the io_wme chain
151  after calling the output function, so the output function is responsible
152  for saving any necessary information around for later.
153 
154  How can an output function examine the io_wme's? The io_wme structures
155  indicate the id/attr/value of the wmes in the output structure. See
156  the comments above for symtab.cpp for an explanation of the structure
157  of these symbols.
158 
159  Get_output_value() is a simple utility routine for finding things in
160  an io_wme chain. It takes "outputs" (the io_wme chain), and "id" and
161  "attr" (symbols to match against the wmes), and returns the value from
162  the first wme in the chain with a matching id and attribute. Either
163  "id" or "attr" (or both) can be specified as "don't care" by giving
164  NULL (0) pointers for them instead of pointers to symbols. If no matching
165  wme is found, the function returns a NULL pointer.
166 ======================================================================= */
167 
168 typedef char Bool;
169 
170 typedef struct io_wme_struct {
171  struct io_wme_struct *next; /* points to next io_wme in the chain */
172  Symbol *id; /* id, attribute, and value of the wme */
175  uint64_t timetag ; /* DJP: Added. Only guaranteed valid for an output wme. */
176 } io_wme;
177 
178 typedef struct output_link_struct {
179  struct output_link_struct *next, *prev; /* dll of all existing links */
180  byte status; /* current xxx_OL_STATUS */
181  wme *link_wme; /* points to the output link wme */
182  ::list *ids_in_tc; /* ids in TC(link) */
183  soar_callback *cb; /* corresponding output function */
184 } output_link;
185 
186 
187 #define ADDED_OUTPUT_COMMAND 1
188 #define MODIFIED_OUTPUT_COMMAND 2
189 #define REMOVED_OUTPUT_COMMAND 3
190 
191 typedef struct output_call_info_struct {
192  int mode;
195 
196 extern Symbol *get_output_value (io_wme *outputs, Symbol *id, Symbol *attr);
197 extern io_wme *get_io_wmes_for_output_link (agent* thisAgent, output_link *ol) ;
198 extern void deallocate_io_wme_list (agent* thisAgent, io_wme *iw) ;
199 
200 extern void add_input_function (agent * a, soar_callback_fn f,
201  soar_callback_data cb_data,
202  soar_callback_free_fn free_fn,
203  const char * name);
204 extern void remove_input_function (agent * a, const char * name);
205 extern void add_output_function (agent* thisAgent, soar_callback_fn f,
206  soar_callback_data cb_data,
207  soar_callback_free_fn free_fn,
208  int eventID,
209  const char * output_link_name);
210 extern void remove_output_function (agent* thisAgent, const char * name);
211 
212 #ifdef __cplusplus
213 //}
214 #endif
215 
216 #endif