00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #include "soarkernel.h"
00056 #include "soar_core_api.h"
00057 #include "callback.h"
00058
00059 extern soar_global_callback_array soar_global_callbacks;
00060 extern unsigned long soar_global_callback_error;
00061
00062 char *soar_callback_names[] = {
00063 "none",
00064 "system-startup",
00065 "system-termination",
00066 "before-init-soar",
00067 "after-init-soar",
00068 "after-halt-soar",
00069 "before-schedule-cycle",
00070 "after-schedule-cycle",
00071 "before-decision-cycle",
00072 "after-decision-cycle",
00073 "before-input-phase",
00074 "input-phase-cycle",
00075 "after-input-phase",
00076 "before-preference-phase-cycle",
00077 "after-preference-phase-cycle",
00078 "before-wm-phase-cycle",
00079 "after-wm-phase-cycle",
00080 "before-output-phase",
00081 "output-phase",
00082 "after-output-phase",
00083 "before-decision-phase-cycle",
00084 "after-decision-phase-cycle",
00085 "wm-changes",
00086 "create-new-context",
00087 "pop-context-stack",
00088 "create-new-attribute-impasse",
00089 "remove-attribute-impasse",
00090 "production-just-added",
00091 "production-just-about-to-be-excised",
00092 "firing",
00093 "retraction",
00094 "system-parameter-changed",
00095 "print",
00096 "log",
00097 "ask"
00098 #ifdef ATTENTION_LAPSE
00099 "init-lapse-duration"
00100 #endif
00101
00102
00103
00104 };
00105
00106 void soar_init_callbacks(soar_callback_agent the_agent)
00107 {
00108 SOAR_CALLBACK_TYPE ct;
00109
00110 for (ct = 1; ct < NUMBER_OF_CALLBACKS; ct++) {
00111 ((agent *) the_agent)->soar_callbacks[ct] = (list *) NIL;
00112 }
00113 ((agent *) the_agent)->callback_error = 0;
00114 }
00115
00116 void soar_init_global_callbacks(void)
00117 {
00118 SOAR_GLOBAL_CALLBACK_TYPE gct;
00119
00120 for (gct = 1; gct < NUMBER_OF_GLOBAL_CALLBACKS; gct++) {
00121 soar_global_callbacks[gct] = (list *) NIL;
00122 }
00123 }
00124
00125 void soar_callback_data_free_string(soar_callback_data data)
00126 {
00127 free((char *) data);
00128 }
00129
00130 char *soar_callback_enum_to_name(SOAR_CALLBACK_TYPE i, bool monitorable_only)
00131 {
00132 int limit;
00133
00134 if (monitorable_only) {
00135 limit = NUMBER_OF_MONITORABLE_CALLBACKS;
00136 } else {
00137 limit = NUMBER_OF_CALLBACKS;
00138 }
00139
00140 if ((0 < i) && (i < limit)) {
00141 return soar_callback_names[i];
00142 }
00143 return NULL;
00144 }
00145
00146 bool soar_exists_callback(soar_callback_agent the_agent, SOAR_CALLBACK_TYPE callback_type)
00147 {
00148 list *cb_cons;
00149
00150 if ((agent *) the_agent == NULL)
00151 return FALSE;
00152
00153 cb_cons = ((agent *) the_agent)->soar_callbacks[callback_type];
00154
00155 if (cb_cons == NULL) {
00156 return FALSE;
00157 }
00158
00159 return TRUE;
00160 }
00161
00162 soar_callback *soar_exists_callback_id(soar_callback_agent the_agent,
00163 SOAR_CALLBACK_TYPE callback_type, soar_callback_id id)
00164 {
00165 cons *c;
00166
00167 if ((agent *) the_agent == NULL)
00168 return FALSE;
00169
00170 for (c = ((agent *) the_agent)->soar_callbacks[callback_type]; c != NIL; c = c->rest) {
00171 soar_callback *cb;
00172
00173 cb = (soar_callback *) c->first;
00174
00175 if (!strcmp(cb->id, id)) {
00176 return cb;
00177 }
00178 }
00179
00180 return NULL;
00181 }
00182
00183 void soar_destroy_callback(soar_callback * cb)
00184 {
00185 if (cb->id) {
00186 free((char *) cb->id);
00187 }
00188 if (cb->free_function) {
00189 cb->free_function(cb->data);
00190 }
00191 free((void *) cb);
00192 }
00193
00194 void soar_invoke_callbacks(soar_callback_agent the_agent, SOAR_CALLBACK_TYPE callback_type, soar_call_data call_data)
00195 {
00196 cons *c;
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 #ifndef NO_TIMING_STUFF
00210 switch (callback_type) {
00211
00212
00213
00214
00215
00216 #ifndef FEW_CALLBACKS
00217
00218 case BEFORE_DECISION_CYCLE_CALLBACK:
00219 case BEFORE_INPUT_PHASE_CALLBACK:
00220 case AFTER_INPUT_PHASE_CALLBACK:
00221
00222 case BEFORE_OUTPUT_PHASE_CALLBACK:
00223 case AFTER_OUTPUT_PHASE_CALLBACK:
00224
00225 case BEFORE_PREFERENCE_PHASE_CALLBACK:
00226 case AFTER_PREFERENCE_PHASE_CALLBACK:
00227
00228 case BEFORE_WM_PHASE_CALLBACK:
00229 case AFTER_WM_PHASE_CALLBACK:
00230
00231 case BEFORE_DECISION_PHASE_CALLBACK:
00232 case AFTER_DECISION_PHASE_CALLBACK:
00233 #endif
00234
00235 #ifndef NO_ADC_CALLBACK
00236 case AFTER_DECISION_CYCLE_CALLBACK:
00237
00238 #ifndef KERNEL_TIME_ONLY
00239
00240
00241 stop_timer(¤t_agent(start_phase_tv),
00242 ¤t_agent(decision_cycle_phase_timers[current_agent(current_phase)]));
00243 #endif
00244
00245 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(total_kernel_time));
00246 #ifndef KERNEL_TIME_ONLY
00247 start_timer(¤t_agent(start_phase_tv));
00248 #endif
00249 break;
00250
00251 #endif
00252
00253 #ifndef NO_IO_CALLBACKS
00254 case INPUT_PHASE_CALLBACK:
00255
00256
00257 #ifndef KERNEL_TIME_ONLY
00258 stop_timer(¤t_agent(start_phase_tv),
00259 ¤t_agent(decision_cycle_phase_timers[current_agent(current_phase)]));
00260 #endif
00261
00262 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(total_kernel_time));
00263 start_timer(¤t_agent(start_kernel_tv));
00264 break;
00265 #endif
00266 default:
00267 break;
00268
00269 }
00270
00271 #endif
00272
00273
00274 for (c = ((agent *) the_agent)->soar_callbacks[callback_type]; c != NIL; c = c->rest) {
00275 soar_callback *cb;
00276
00277 cb = (soar_callback *) c->first;
00278 cb->function(the_agent, cb->data, call_data);
00279 }
00280
00281
00282
00283 #ifndef NO_TIMING_STUFF
00284 switch (callback_type) {
00285
00286 #ifndef FEW_CALLBACKS
00287
00288 case BEFORE_DECISION_CYCLE_CALLBACK:
00289 case BEFORE_INPUT_PHASE_CALLBACK:
00290 case AFTER_INPUT_PHASE_CALLBACK:
00291 case BEFORE_OUTPUT_PHASE_CALLBACK:
00292 case AFTER_OUTPUT_PHASE_CALLBACK:
00293 case BEFORE_PREFERENCE_PHASE_CALLBACK:
00294 case AFTER_PREFERENCE_PHASE_CALLBACK:
00295 case BEFORE_WM_PHASE_CALLBACK:
00296 case AFTER_WM_PHASE_CALLBACK:
00297 case BEFORE_DECISION_PHASE_CALLBACK:
00298 case AFTER_DECISION_PHASE_CALLBACK:
00299 #endif
00300
00301 #ifndef NO_ADC_CALLBACK
00302
00303 case AFTER_DECISION_CYCLE_CALLBACK:
00304
00305 #ifndef KERNEL_TIME_ONLY
00306 stop_timer(¤t_agent(start_phase_tv), ¤t_agent(monitors_cpu_time[current_agent(current_phase)]));
00307 #endif
00308
00309 start_timer(¤t_agent(start_kernel_tv));
00310 #ifndef KERNEL_TIME_ONLY
00311 start_timer(¤t_agent(start_phase_tv));
00312 #endif
00313 break;
00314
00315 #endif
00316
00317 #ifndef NO_IO_CALLBACKS
00318 case INPUT_PHASE_CALLBACK:
00319
00320 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(input_function_cpu_time));
00321 start_timer(¤t_agent(start_kernel_tv));
00322 #ifndef KERNEL_TIME_ONLY
00323 start_timer(¤t_agent(start_phase_tv));
00324 #endif
00325 break;
00326 #endif
00327 default:
00328 break;
00329
00330 }
00331
00332 #endif
00333
00334
00335
00336 }
00337
00338 void soar_invoke_first_callback(soar_callback_agent the_agent,
00339 SOAR_CALLBACK_TYPE callback_type, soar_call_data call_data)
00340 {
00341 list *head;
00342
00343
00344
00345 #ifndef NO_TIMING_STUFF
00346 switch (callback_type) {
00347
00348 #ifndef FEW_CALLBACKS
00349
00350 case BEFORE_DECISION_CYCLE_CALLBACK:
00351 case BEFORE_INPUT_PHASE_CALLBACK:
00352 case AFTER_INPUT_PHASE_CALLBACK:
00353
00354 case BEFORE_OUTPUT_PHASE_CALLBACK:
00355 case AFTER_OUTPUT_PHASE_CALLBACK:
00356
00357 case BEFORE_PREFERENCE_PHASE_CALLBACK:
00358 case AFTER_PREFERENCE_PHASE_CALLBACK:
00359
00360 case BEFORE_WM_PHASE_CALLBACK:
00361 case AFTER_WM_PHASE_CALLBACK:
00362
00363 case BEFORE_DECISION_PHASE_CALLBACK:
00364 case AFTER_DECISION_PHASE_CALLBACK:
00365
00366 #endif
00367
00368 #ifndef NO_ADC_CALLBACK
00369 case AFTER_DECISION_CYCLE_CALLBACK:
00370
00371
00372 #ifndef KERNEL_TIME_ONLY
00373 stop_timer(¤t_agent(start_phase_tv),
00374 ¤t_agent(decision_cycle_phase_timers[current_agent(current_phase)]));
00375 #endif
00376 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(total_kernel_time));
00377 #ifndef KERNEL_TIME_ONLY
00378 start_timer(¤t_agent(start_phase_tv));
00379 #endif
00380 break;
00381 #endif
00382
00383 #ifndef NO_IO_CALLBACKS
00384 case INPUT_PHASE_CALLBACK:
00385
00386
00387 #ifndef KERNEL_TIME_ONLY
00388 stop_timer(¤t_agent(start_phase_tv),
00389 ¤t_agent(decision_cycle_phase_timers[current_agent(current_phase)]));
00390 #endif
00391
00392 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(total_kernel_time));
00393 start_timer(¤t_agent(start_kernel_tv));
00394 break;
00395 #endif
00396 default:
00397 break;
00398
00399 }
00400
00401 #endif
00402
00403
00404 head = ((agent *) the_agent)->soar_callbacks[callback_type];
00405
00406 if (head != NULL) {
00407 soar_callback *cb;
00408
00409 cb = (soar_callback *) head->first;
00410 cb->function(the_agent, cb->data, call_data);
00411 }
00412
00413
00414
00415 #ifndef NO_TIMING_STUFF
00416 switch (callback_type) {
00417
00418 #ifndef FEW_CALLBACKS
00419
00420 case BEFORE_DECISION_CYCLE_CALLBACK:
00421 case BEFORE_INPUT_PHASE_CALLBACK:
00422 case AFTER_INPUT_PHASE_CALLBACK:
00423 case BEFORE_OUTPUT_PHASE_CALLBACK:
00424 case AFTER_OUTPUT_PHASE_CALLBACK:
00425 case BEFORE_PREFERENCE_PHASE_CALLBACK:
00426 case AFTER_PREFERENCE_PHASE_CALLBACK:
00427 case BEFORE_WM_PHASE_CALLBACK:
00428 case AFTER_WM_PHASE_CALLBACK:
00429 case BEFORE_DECISION_PHASE_CALLBACK:
00430 case AFTER_DECISION_PHASE_CALLBACK:
00431
00432 #endif
00433 #ifndef NO_ADC_CALLBACK
00434 case AFTER_DECISION_CYCLE_CALLBACK:
00435 #ifndef KERNEL_TIME_ONLY
00436 stop_timer(¤t_agent(start_phase_tv), ¤t_agent(monitors_cpu_time[current_agent(current_phase)]));
00437 #endif
00438 start_timer(¤t_agent(start_kernel_tv));
00439 #ifndef KERNEL_TIME_ONLY
00440 start_timer(¤t_agent(start_phase_tv));
00441 #endif
00442 break;
00443 #endif
00444
00445 #ifndef NO_IO_CALLBACKS
00446 case INPUT_PHASE_CALLBACK:
00447
00448 stop_timer(¤t_agent(start_kernel_tv), ¤t_agent(input_function_cpu_time));
00449 start_timer(¤t_agent(start_kernel_tv));
00450 #ifndef KERNEL_TIME_ONLY
00451 start_timer(¤t_agent(start_phase_tv));
00452 #endif
00453 break;
00454 #endif
00455 default:
00456 break;
00457
00458 }
00459
00460 #endif
00461
00462
00463
00464 }
00465
00466 bool soar_exists_global_callback(SOAR_GLOBAL_CALLBACK_TYPE callback_type)
00467 {
00468 list *cb_cons;
00469
00470 cb_cons = soar_global_callbacks[callback_type];
00471
00472 if (cb_cons == NULL) {
00473 return FALSE;
00474 }
00475
00476 return TRUE;
00477 }
00478
00479 void soar_invoke_global_callbacks(soar_callback_agent a, SOAR_CALLBACK_TYPE callback_type, soar_call_data call_data)
00480 {
00481 cons *c;
00482
00483
00484
00485
00486
00487
00488 for (c = soar_global_callbacks[callback_type]; c != NIL; c = c->rest) {
00489 soar_callback *cb;
00490
00491 cb = (soar_callback *) c->first;
00492 cb->function(a, cb->data, call_data);
00493 }
00494
00495 }