00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "compat.h"
00023
00024 #include "Link.h"
00025 #include "Ingredients.h"
00026 #include "Root.h"
00027 #include "BaseClasses.h"
00028 #include "ParseNode.h"
00029 #include "ASN1Codes.h"
00030 #include "Actions.h"
00031 #include "Engine.h"
00032 #include "Logging.h"
00033
00034 MHLink::MHLink()
00035 {
00036 m_EventData.m_Type = MHUnion::U_None;
00037 m_nEventType = EventIsAvailable;
00038 }
00039
00040 void MHLink::Initialise(MHParseNode *p, MHEngine *engine)
00041 {
00042 MHIngredient::Initialise(p, engine);
00043
00044 MHParseNode *pLinkCond = p->GetNamedArg(C_LINK_CONDITION);
00045
00046 if (pLinkCond)
00047 {
00048 m_EventSource.Initialise(pLinkCond->GetArgN(0), engine);
00049 m_nEventType = (enum EventType)pLinkCond->GetArgN(1)->GetEnumValue();
00050
00051 if (pLinkCond->GetArgCount() >= 3)
00052 {
00053 MHParseNode *pEventData = pLinkCond->GetArgN(2);
00054
00055 switch (pEventData->m_nNodeType)
00056 {
00057 case MHParseNode::PNBool:
00058 m_EventData.m_fBoolVal = pEventData->GetBoolValue();
00059 m_EventData.m_Type = MHUnion::U_Bool;
00060 break;
00061 case MHParseNode::PNInt:
00062 m_EventData.m_nIntVal = pEventData->GetIntValue();
00063 m_EventData.m_Type = MHUnion::U_Int;
00064 break;
00065 case MHParseNode::PNString:
00066 pEventData->GetStringValue(m_EventData.m_StrVal);
00067 m_EventData.m_Type = MHUnion::U_String;
00068 break;
00069 default:
00070 pEventData->Failure("Unknown type of event data");
00071 }
00072 }
00073 }
00074 else
00075 {
00076 MHParseNode *pEventSource = p->GetNamedArg(P_EVENT_SOURCE);
00077
00078 if (! pEventSource)
00079 {
00080 p->Failure("Missing :EventSource");
00081 }
00082 else
00083 {
00084 m_EventSource.Initialise(pEventSource->GetArgN(0), engine);
00085 }
00086
00087 MHParseNode *pEventType = p->GetNamedArg(P_EVENT_TYPE);
00088
00089 if (! pEventType)
00090 {
00091 p->Failure("Missing :EventType");
00092 }
00093 else
00094 {
00095 m_nEventType = (enum EventType)pEventType->GetArgN(0)->GetEnumValue();
00096 }
00097
00098 MHParseNode *pEventData = p->GetNamedArg(P_EVENT_DATA);
00099
00100 if (pEventData)
00101 {
00102 MHParseNode *pEventDataArg = pEventData->GetArgN(0);
00103
00104 switch (pEventDataArg->m_nNodeType)
00105 {
00106 case MHParseNode::PNBool:
00107 m_EventData.m_fBoolVal = pEventDataArg->GetBoolValue();
00108 m_EventData.m_Type = MHUnion::U_Bool;
00109 break;
00110 case MHParseNode::PNInt:
00111 m_EventData.m_nIntVal = pEventDataArg->GetIntValue();
00112 m_EventData.m_Type = MHUnion::U_Int;
00113 break;
00114 case MHParseNode::PNString:
00115 pEventDataArg->GetStringValue(m_EventData.m_StrVal);
00116 m_EventData.m_Type = MHUnion::U_String;
00117 break;
00118 default:
00119 pEventDataArg->Failure("Unknown type of event data");
00120 }
00121 }
00122 }
00123
00124 MHParseNode *pLinkEffect = p->GetNamedArg(C_LINK_EFFECT);
00125
00126 if (pLinkEffect)
00127 {
00128 m_LinkEffect.Initialise(pLinkEffect, engine);
00129 }
00130 }
00131
00132 static const char *rchEventType[] =
00133 {
00134 "IsAvailable",
00135 "ContentAvailable",
00136 "IsDeleted",
00137 "IsRunning",
00138 "IsStopped",
00139 "UserInput",
00140 "AnchorFired",
00141 "TimerFired",
00142 "AsyncStopped",
00143 "InteractionCompleted",
00144 "TokenMovedFrom",
00145 "TokenMovedTo",
00146 "StreamEvent",
00147 "StreamPlaying",
00148 "StreamStopped",
00149 "CounterTrigger",
00150 "HighlightOn",
00151 "HighlightOff",
00152 "CursorEnter",
00153 "CursorLeave",
00154 "IsSelected",
00155 "IsDeselected",
00156 "TestEvent",
00157 "FirstItemPresented",
00158 "LastItemPresented",
00159 "HeadItems",
00160 "TailItems",
00161 "ItemSelected",
00162 "ItemDeselected",
00163 "EntryFieldFull",
00164 "EngineEvent",
00165 "FocusMoved",
00166 "SliderValueChanged"
00167 };
00168
00169
00170 int MHLink::GetEventType(const char *str)
00171 {
00172 for (int i = 0; i < (int)(sizeof(rchEventType) / sizeof(rchEventType[0])); i++)
00173 {
00174 if (strcasecmp(str, rchEventType[i]) == 0)
00175 {
00176 return (i + 1);
00177 }
00178 }
00179
00180 return 0;
00181 }
00182
00183 QString MHLink::EventTypeToString(enum EventType ev)
00184 {
00185 if (ev > 0 && ev <= (int)(sizeof(rchEventType) / sizeof(rchEventType[0])))
00186 {
00187 return rchEventType[ev-1];
00188 }
00189 else
00190 {
00191 return QString("Unknown event %1").arg(ev);
00192 }
00193 }
00194
00195 void MHLink::PrintMe(FILE *fd, int nTabs) const
00196 {
00197 PrintTabs(fd, nTabs);
00198 fprintf(fd, "{:Link");
00199 MHIngredient::PrintMe(fd, nTabs + 1);
00200 PrintTabs(fd, nTabs + 1);
00201 fprintf(fd, ":EventSource ");
00202 m_EventSource.PrintMe(fd, nTabs + 1);
00203 fprintf(fd, "\n");
00204 MHASSERT(m_nEventType > 0 && m_nEventType <= (int)(sizeof(rchEventType) / sizeof(rchEventType[0])));
00205 PrintTabs(fd, nTabs + 1);
00206 fprintf(fd, ":EventType %s\n", rchEventType[m_nEventType-1]);
00207
00208
00209 switch (m_EventData.m_Type)
00210 {
00211 case MHUnion::U_Bool:
00212 PrintTabs(fd, nTabs + 1);
00213 fprintf(fd, ":EventData %s\n", m_EventData.m_fBoolVal ? "true" : "false");
00214 break;
00215 case MHUnion::U_Int:
00216 PrintTabs(fd, nTabs + 1);
00217 fprintf(fd, ":EventData %d\n", m_EventData.m_nIntVal);
00218 break;
00219 case MHUnion::U_String:
00220 PrintTabs(fd, nTabs + 1);
00221 fprintf(fd, ":EventData");
00222 m_EventData.m_StrVal.PrintMe(fd, nTabs);
00223 fprintf(fd, "\n");
00224 break;
00225 default:
00226 break;
00227 }
00228
00229 PrintTabs(fd, nTabs + 1);
00230 fprintf(fd, ":LinkEffect (\n");
00231 m_LinkEffect.PrintMe(fd, nTabs + 2);
00232 PrintTabs(fd, nTabs + 1);
00233 fprintf(fd, ")\n");
00234 PrintTabs(fd, nTabs);
00235 fprintf(fd, "}\n");
00236 }
00237
00238
00239 void MHLink::Activation(MHEngine *engine)
00240 {
00241 if (m_fRunning)
00242 {
00243 return;
00244 }
00245
00246 MHIngredient::Activation(engine);
00247 m_fRunning = true;
00248 engine->AddLink(this);
00249 engine->EventTriggered(this, EventIsRunning);
00250 }
00251
00252 void MHLink::Deactivation(MHEngine *engine)
00253 {
00254 if (! m_fRunning)
00255 {
00256 return;
00257 }
00258
00259 engine->RemoveLink(this);
00260 MHIngredient::Deactivation(engine);
00261 }
00262
00263
00264 void MHLink::Activate(bool fActivate, MHEngine *engine)
00265 {
00266 if (fActivate)
00267 {
00268 if (! m_fRunning)
00269 {
00270 Activation(engine);
00271 }
00272 }
00273 else
00274 {
00275 if (m_fRunning)
00276 {
00277 Deactivation(engine);
00278 }
00279 }
00280 }
00281
00282
00283
00284 void MHLink::MatchEvent(const MHObjectRef &sourceRefRef, enum EventType ev, const MHUnion &evData, MHEngine *engine)
00285 {
00286 if (m_fRunning && m_nEventType == ev && sourceRefRef.Equal(m_EventSource, engine))
00287 {
00288 bool fMatch = false;
00289
00290 switch (m_EventData.m_Type)
00291 {
00292 case MHUnion::U_None:
00293 fMatch = true;
00294 break;
00295 case MHUnion::U_Bool:
00296 fMatch = evData.m_Type == MHUnion::U_Bool && evData.m_fBoolVal == m_EventData.m_fBoolVal;
00297 break;
00298 case MHUnion::U_Int:
00299 fMatch = evData.m_Type == MHUnion::U_Int && evData.m_nIntVal == m_EventData.m_nIntVal;
00300 break;
00301 case MHUnion::U_String:
00302 fMatch = evData.m_Type == MHUnion::U_String && evData.m_StrVal.Equal(m_EventData.m_StrVal);
00303 break;
00304 default:
00305 fMatch = false;
00306 break;
00307 }
00308
00309
00310 if (fMatch)
00311 {
00312 MHLOG(MHLogLinks, QString("Link fired - %1").arg(m_ObjectReference.Printable()));
00313 engine->AddActions(m_LinkEffect);
00314 }
00315 }
00316 }