00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "Link.h"
00023 #include "Ingredients.h"
00024 #include "Root.h"
00025 #include "BaseClasses.h"
00026 #include "ParseNode.h"
00027 #include "ASN1Codes.h"
00028 #include "Actions.h"
00029 #include "Engine.h"
00030 #include "Logging.h"
00031
00032 MHLink::MHLink()
00033 {
00034 m_EventData.m_Type = MHUnion::U_None;
00035 }
00036
00037 void MHLink::Initialise(MHParseNode *p, MHEngine *engine)
00038 {
00039 MHIngredient::Initialise(p, engine);
00040
00041 MHParseNode *pLinkCond = p->GetNamedArg(C_LINK_CONDITION);
00042 if (pLinkCond) {
00043 m_EventSource.Initialise(pLinkCond->GetArgN(0), engine);
00044 m_nEventType = (enum EventType)pLinkCond->GetArgN(1)->GetEnumValue();
00045
00046 if (pLinkCond->GetArgCount() >= 3) {
00047 MHParseNode *pEventData = pLinkCond->GetArgN(2);
00048 switch (pEventData->m_nNodeType) {
00049 case MHParseNode::PNBool: m_EventData.m_fBoolVal = pEventData->GetBoolValue(); m_EventData.m_Type = MHUnion::U_Bool; break;
00050 case MHParseNode::PNInt: m_EventData.m_nIntVal = pEventData->GetIntValue(); m_EventData.m_Type = MHUnion::U_Int; break;
00051 case MHParseNode::PNString: pEventData->GetStringValue(m_EventData.m_StrVal); m_EventData.m_Type = MHUnion::U_String; break;
00052 default: pEventData->Failure("Unknown type of event data");
00053 }
00054 }
00055 }
00056 else {
00057 MHParseNode *pEventSource = p->GetNamedArg(P_EVENT_SOURCE);
00058 if (! pEventSource) p->Failure("Missing :EventSource");
00059 m_EventSource.Initialise(pEventSource->GetArgN(0), engine);
00060 MHParseNode *pEventType = p->GetNamedArg(P_EVENT_TYPE);
00061 if (! pEventType) p->Failure("Missing :EventType");
00062 m_nEventType = (enum EventType)pEventType->GetArgN(0)->GetEnumValue();
00063 MHParseNode *pEventData = p->GetNamedArg(P_EVENT_DATA);
00064 if (pEventData) {
00065 MHParseNode *pEventDataArg = pEventData->GetArgN(0);
00066 switch (pEventDataArg->m_nNodeType) {
00067 case MHParseNode::PNBool: m_EventData.m_fBoolVal = pEventDataArg->GetBoolValue(); m_EventData.m_Type = MHUnion::U_Bool; break;
00068 case MHParseNode::PNInt: m_EventData.m_nIntVal = pEventDataArg->GetIntValue(); m_EventData.m_Type = MHUnion::U_Int; break;
00069 case MHParseNode::PNString: pEventDataArg->GetStringValue(m_EventData.m_StrVal); m_EventData.m_Type = MHUnion::U_String; break;
00070 default: pEventDataArg->Failure("Unknown type of event data");
00071 }
00072 }
00073 }
00074
00075 MHParseNode *pLinkEffect = p->GetNamedArg(C_LINK_EFFECT);
00076 m_LinkEffect.Initialise(pLinkEffect, engine);
00077 }
00078
00079 static const char *rchEventType[] =
00080 {
00081 "IsAvailable",
00082 "ContentAvailable",
00083 "IsDeleted",
00084 "IsRunning",
00085 "IsStopped",
00086 "UserInput",
00087 "AnchorFired",
00088 "TimerFired",
00089 "AsyncStopped",
00090 "InteractionCompleted",
00091 "TokenMovedFrom",
00092 "TokenMovedTo",
00093 "StreamEvent",
00094 "StreamPlaying",
00095 "StreamStopped",
00096 "CounterTrigger",
00097 "HighlightOn",
00098 "HighlightOff",
00099 "CursorEnter",
00100 "CursorLeave",
00101 "IsSelected",
00102 "IsDeselected",
00103 "TestEvent",
00104 "FirstItemPresented",
00105 "LastItemPresented",
00106 "HeadItems",
00107 "TailItems",
00108 "ItemSelected",
00109 "ItemDeselected",
00110 "EntryFieldFull",
00111 "EngineEvent",
00112 "FocusMoved",
00113 "SliderValueChanged"
00114 };
00115
00116
00117 int MHLink::GetEventType(const char *str)
00118 {
00119 for (int i = 0; i < (int)(sizeof(rchEventType)/sizeof(rchEventType[0])); i++) {
00120 if (strcasecmp(str, rchEventType[i]) == 0) return (i+1);
00121 }
00122 return 0;
00123 }
00124
00125 QString MHLink::EventTypeToString(enum EventType ev)
00126 {
00127 if (ev > 0 && ev <= (int)(sizeof(rchEventType)/sizeof(rchEventType[0]))) return rchEventType[ev-1];
00128 else return QString("Unknown event %1").arg(ev);
00129 }
00130
00131 void MHLink::PrintMe(FILE *fd, int nTabs) const
00132 {
00133 PrintTabs(fd, nTabs);
00134 fprintf(fd, "{:Link"); MHIngredient::PrintMe(fd, nTabs+1);
00135 PrintTabs(fd, nTabs+1); fprintf(fd, ":EventSource "); m_EventSource.PrintMe(fd, nTabs+1); fprintf(fd, "\n");
00136 MHASSERT(m_nEventType > 0 && m_nEventType <= (int)(sizeof(rchEventType)/sizeof(rchEventType[0])));
00137 PrintTabs(fd, nTabs+1); fprintf(fd, ":EventType %s\n", rchEventType[m_nEventType-1]);
00138
00139 switch (m_EventData.m_Type) {
00140 case MHUnion::U_Bool: PrintTabs(fd, nTabs+1); fprintf(fd, ":EventData %s\n", m_EventData.m_fBoolVal ? "true" : "false"); break;
00141 case MHUnion::U_Int: PrintTabs(fd, nTabs+1); fprintf(fd, ":EventData %d\n", m_EventData.m_nIntVal); break;
00142 case MHUnion::U_String: PrintTabs(fd, nTabs+1); fprintf(fd, ":EventData"); m_EventData.m_StrVal.PrintMe(fd, nTabs); fprintf(fd, "\n"); break;
00143 default: break;
00144 }
00145 PrintTabs(fd, nTabs+1); fprintf(fd, ":LinkEffect (\n");
00146 m_LinkEffect.PrintMe(fd, nTabs+2);
00147 PrintTabs(fd, nTabs+1); fprintf(fd, ")\n");
00148 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00149 }
00150
00151
00152 void MHLink::Activation(MHEngine *engine)
00153 {
00154 if (m_fRunning) return;
00155 MHIngredient::Activation(engine);
00156 m_fRunning = true;
00157 engine->AddLink(this);
00158 engine->EventTriggered(this, EventIsRunning);
00159 }
00160
00161 void MHLink::Deactivation(MHEngine *engine)
00162 {
00163 if (! m_fRunning) return;
00164 engine->RemoveLink(this);
00165 MHIngredient::Deactivation(engine);
00166 }
00167
00168
00169 void MHLink::Activate(bool fActivate, MHEngine *engine)
00170 {
00171 if (fActivate) {
00172 if (! m_fRunning) Activation(engine);
00173 }
00174 else {
00175 if (m_fRunning) Deactivation(engine);
00176 }
00177 }
00178
00179
00180
00181 void MHLink::MatchEvent(const MHObjectRef &sourceRefRef, enum EventType ev, const MHUnion &evData, MHEngine *engine)
00182 {
00183 if (m_fRunning && m_nEventType == ev && sourceRefRef.Equal(m_EventSource, engine)) {
00184 bool fMatch = false;
00185 switch (m_EventData.m_Type) {
00186 case MHUnion::U_None: fMatch = true; break;
00187 case MHUnion::U_Bool:
00188 fMatch = evData.m_Type == MHUnion::U_Bool && evData.m_fBoolVal == m_EventData.m_fBoolVal; break;
00189 case MHUnion::U_Int:
00190 fMatch = evData.m_Type == MHUnion::U_Int && evData.m_nIntVal == m_EventData.m_nIntVal; break;
00191 case MHUnion::U_String:
00192 fMatch = evData.m_Type == MHUnion::U_String && evData.m_StrVal.Equal(m_EventData.m_StrVal); break;
00193 default: fMatch = false; break;
00194 }
00195
00196 if (fMatch) {
00197 MHLOG(MHLogLinks, QString("Link fired - %1").arg(m_ObjectReference.Printable()));
00198 engine->AddActions(m_LinkEffect);
00199 }
00200 }
00201 }