libtrigger.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 652 行 · 第 1/2 页
C
652 行
oaa_Id(&me);
from_me_list =
icl_NewList(
icl_NewCons(
icl_NewStruct("from", 1,
icl_CopyTerm(me)),
NULL));
res = oaa_Interpret(term, from_me_list, NULL);
icl_Free(from_me_list);
icl_Free(me);
return res;
}
/*****************************************************************************
* name: oaa_update_trigger
* purpose: NOT IMPLEMENTED YET
****************************************************************************/
int oaa_update_trigger(char *mode, char* type, ICLTerm* condition, ICLTerm* action,
ICLTerm* in_params, ICLTerm** out_params){
ICLTerm *t1 = NULL, *local_condition = NULL;
ICLTerm *params = NULL, *params1 = NULL, *params2 = NULL;
ICLTerm *new_addr = NULL, *addr = NULL;
ICLTerm *me = NULL;
ICLTerm *updaters1 = NULL, *requestees1 = NULL;
ICLTerm *updaters2 = NULL, *requestees2 = NULL;
ICLTerm *reflexive_true = icl_NewTermFromData("reflexive(true)", 15);
ICLTerm *updaters = (ICLTerm *)NULL;
ICLTerm *requestees = (ICLTerm *)NULL;
ICLTerm* solvables = NULL;
int res = FALSE, self = FALSE;
/* If type is "comm" and InCondition does not unify with event(_,_) */
if (STREQ(mode, "comm") && !icl_Unify(condition, t1 = icl_NewTermFromData("event(A,B)", 10), NULL)) {
local_condition = icl_NewStruct("event", 2, condition, icl_NewVar("X"));
}
else {
local_condition = icl_CopyTerm(condition);
}
icl_Free(t1);
/* in_params might be a variable */
if (icl_IsList(in_params)) {
icl_standardize_params(in_params, 0, ¶ms);
}
else {
params = icl_NewList(NULL);
}
/* is there a specific address ? */
if (!icl_param_arg("address", NULL, params, &addr)) {
addr = icl_NewList(NULL);
}
/* decide whether or not to update locally: */
if (oaa_PrimaryAddress(&me) &&
icl_Member(me, addr, NULL)) {
icl_ListDelete(addr, me, &new_addr);
t1 = icl_NewStruct("address", 1, icl_CopyTerm(addr));
replace_element(t1, params,
icl_NewStruct("address", 1, new_addr), ¶ms1);
icl_Free(t1);
self = TRUE;
} else {
new_addr = icl_CopyTerm(addr);
params1 = icl_CopyTerm(params);
}
if ((!addr->p) &&
icl_GetParamValue(reflexive_true, params1, NULL)) {
ICLTerm *write = icl_NewStr("write");
ICLTerm *real_clause, *real_matched;
/* do NOT use remove_element here: */
icl_ListDelete(params1, reflexive_true, ¶ms2);
solvables = valid_oaa_solvables();
if (oaa_data_matches_solvables(local_condition, solvables, write, &real_clause,
&real_matched))
self = TRUE;
icl_Free(write);
} else {
params2 = params1;
}
icl_Free(reflexive_true);
/* update locally if appropriate */
if (self) {
requestees1 = icl_NewList(icl_NewCons(icl_CopyTerm(me), NULL));
if (STREQ(mode, "add"))
res = oaa_add_trigger_local(type, local_condition, action, params2);
else if (STREQ(mode, "remove"))
res = oaa_remove_trigger_local(type, local_condition, action, params2);
if(res) {
updaters1 = icl_NewList(icl_NewCons(icl_CopyTerm(me), NULL));
} else {
updaters1 = icl_NewList(NULL);
}
} else {
requestees1 = icl_NewList(NULL);
updaters1 = icl_NewList(NULL);
}
icl_Free(me);
/* Update remotely if appropriate:
*/
if (oaa_class("leaf") && ((!addr->p) || (new_addr->p))) {
ICLTerm *reply;
char *goalIdStr = new_goal_id();
/* Send the ev_update_data event to the Facilitator
*/
ICLTerm* toBeSent = icl_NewStruct("ev_update_trigger", 6,
icl_NewStr(goalIdStr), icl_NewStr(mode),
icl_NewStr(type), icl_CopyTerm(local_condition),
icl_CopyTerm(action), params2);
oaa_PostEvent(toBeSent, ICL_EMPTY);
/* In the return event, Requestees2 lists all agents to whom
* the update request wassent; Updaters2 lists those who succeeded
*/
requestees2 = icl_NewList(NULL);
updaters2 = icl_NewList(NULL);
if (!(icl_param_arg("reply", NULL, params, &reply) &&
(STREQ("asynchronous", icl_Str(reply)) ||
STREQ("none", icl_Str(reply)))) ) {
ICLTerm *ev_reply_updated =
icl_NewStruct("ev_trigger_updated", 8, icl_NewVar("G"),
icl_NewStr(mode), icl_NewStr(type),
icl_CopyTerm(local_condition), icl_CopyTerm(action), icl_CopyTerm(params2),
icl_NewVar("Requestees"), icl_NewVar("Updaters"));
oaa_poll_until_event(ev_reply_updated, NULL);
icl_Free(ev_reply_updated);
}
icl_Free(toBeSent);
}
icl_Free(addr);
icl_Free(new_addr);
/*
* The following section replaces a variable parameter value in the
* parameter list for return to the calling function
*/
icl_append_to_list(updaters1, updaters2, &updaters);
icl_Free(updaters1);
icl_Free(updaters2);
/* Return Updaters if requested:
*/
t1 = icl_NewStruct("get_satisfiers", 1,
updaters);
icl_replace_param_value(t1, params);
icl_Free(t1); /* frees updaters too */
/* Return Requestees if requested:
*/
icl_append_to_list(requestees1, requestees2, &requestees);
icl_replace_param_value((t1 = icl_NewStruct("get_address", 1,
requestees)),
params);
icl_Free(requestees1);
icl_Free(requestees2);
icl_Free(t1);
if (out_params) {
*out_params = params;
}
if(params2 == params1) {
icl_Free(params2);
}
else {
icl_Free(params2);
icl_Free(params1);
}
icl_Free(local_condition);
icl_Free(params);
return TRUE;
};
/**
* Adds a trigger according to parameters.
* <p>Type = comm, data, task, time</p>
* <p>Condition= comm:event to match, data:data to match, task:solvable to call
* time:@@</p>
* <p>Action = Can be any of these:</p>
* <ul>
* <li>oaa_Solve(Goal, Params)</li>
* <li>oaa_Interpret(Goal, Params)</li>
* <li>Goal [passed to oaa_Interpret with default params]</li>
* </ul>
* <p>Params =</p>
* <ul>
* <li>address(X): a list including 'self', 'parent', and/or the
* addresses of other client agents. Default: see below.</li>
* <li>test(T): additional tests before trigger will fire [@@needs work?]</li>
* <li>on(OP) : operation check: on(add), on(remove), on(receive), etc.</li>
* <li>recurrence(R): when, whenever, or integer (# of times to execute)</li>
* <li>reply({true,none}): When a trigger is being added on</li>
* a remote agent or agents, this tells whether reply message(s) are
* desired.</li>
* <li>block(Mode) : true: Block until the reply arrives.
* : false: Don't block. In
* this case, the reply events
* can be handled by the user's app_do_event callback</li>
* Default: true. Note that reply(none) overrides
* block(true).</li>
* <li>get_address(X): Returns a list of addresses (ids) of agents that
* were sent the request.</li>
* <li>get_satisfiers(X): Returns a list of addresses (ids) of agents that
* successfully completed the request.</p>
* </ul>
*
* <p>Default destination for triggers:</p>
* <ul>
* <li>Data triggers: all agents with solvables matching the Condition
* field.</li>
* <li>All other types: the local agent</li>
* </ul>
*/
int oaa_AddTrigger(char *type, ICLTerm *condition, ICLTerm *action,
ICLTerm *initial_params, ICLTerm **out_params) {
return oaa_update_trigger("add", type, condition, action,
initial_params, out_params);
}
/**
* Removes a trigger from a local or remote agent.
*/
int oaa_RemoveTrigger(char *type, ICLTerm *condition,
ICLTerm *action, ICLTerm *initial_params,
ICLTerm **out_params) {
return oaa_update_trigger("remove", type, condition, action,
initial_params, out_params);
}
int oaa_add_trigger_local(char *type, ICLTerm *condition, ICLTerm *action,
ICLTerm *params)
{
static int cntr = 0;
char trigger_id[32];
int res;
ICLTerm *t1;
ICLTerm *trigger;
sprintf(trigger_id, "trg%d", cntr++);
t1 = icl_NewList(NULL);
trigger = icl_NewStruct("oaa_trigger", 5,
icl_NewStr(trigger_id),
icl_NewStr(type),
icl_CopyTerm(condition),
icl_CopyTerm(action),
icl_CopyTerm(params));
res = oaa_add_data_local(trigger, t1);
icl_Free(t1);
icl_Free(trigger);
return res;
}
int oaa_remove_trigger_local(char *type, ICLTerm *condition, ICLTerm *action,
ICLTerm *params)
{
int res;
ICLTerm *tid_var = icl_NewVar("_trigger_id");
ICLTerm *trigger_term = icl_NewStruct("oaa_trigger", 5, tid_var,
icl_NewStr(type),
icl_CopyTerm(condition),
icl_CopyTerm(action),
icl_CopyTerm(params));
ICLTerm *t1;
t1 = icl_NewList(NULL);
res = oaa_remove_data_local(trigger_term, t1);
icl_Free(trigger_term);
icl_Free(tid_var);
icl_Free(t1);
return res;
}
/**
* Removes a local trigger given its unique identifier.
*/
int oaa_remove_local_trigger_by_id(ICLTerm *trigger_id)
{
ICLTerm *dummyvar = icl_NewVar("_");
ICLTerm *trigger_term = icl_NewStruct("oaa_trigger", 5,
icl_CopyTerm(trigger_id),
icl_CopyTerm(dummyvar),
icl_CopyTerm(dummyvar),
icl_CopyTerm(dummyvar),
icl_CopyTerm(dummyvar));
ICLTerm *t1;
t1 = icl_NewList(NULL);
oaa_remove_data_local(trigger_term, t1);
icl_Free(trigger_term);
icl_Free(dummyvar);
icl_Free(t1);
return TRUE;
}
/**
* @defgroup Triggers Triggers
*
* Contains C versions of the trigger functions for the Open Agent
* Architecture.
*
* @{
*/
/**
* @file libtrigger.h
* Contains C versions of the trigger functions for the Open Agent
* Architecture.
*/
/**
* @file libtrigger.c
*/
/** @} */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?