00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "TokenGroup.h"
00024 #include "Presentable.h"
00025 #include "Ingredients.h"
00026 #include "Root.h"
00027 #include "BaseClasses.h"
00028 #include "ParseNode.h"
00029 #include "ASN1Codes.h"
00030 #include "Engine.h"
00031
00032 void MHTokenGroupItem::Initialise(MHParseNode *p, MHEngine *engine)
00033 {
00034
00035 m_Object.Initialise(p->GetSeqN(0), engine);
00036 if (p->GetSeqCount() > 1) {
00037 MHParseNode *pSlots = p->GetSeqN(1);
00038 for (int i = 0; i < pSlots->GetSeqCount(); i++) {
00039 MHParseNode *pAct = pSlots->GetSeqN(i);
00040 MHActionSequence *pActions = new MHActionSequence;
00041 m_ActionSlots.Append(pActions);
00042
00043 if (pAct->m_nNodeType != MHParseNode::PNNull) pActions->Initialise(pAct, engine);
00044 }
00045 }
00046 }
00047
00048 void MHTokenGroupItem::PrintMe(FILE *fd, int nTabs) const
00049 {
00050 PrintTabs(fd, nTabs); fprintf(fd, "( ");
00051 m_Object.PrintMe(fd, nTabs+1); fprintf(fd, "\n");
00052 if (m_ActionSlots.Size() != 0) {
00053 PrintTabs(fd, nTabs+1); fprintf(fd, ":ActionSlots (\n");
00054 for (int i = 0; i < m_ActionSlots.Size(); i++) {
00055 PrintTabs(fd, nTabs+2); fprintf(fd, "(\n");
00056 MHActionSequence *pActions = m_ActionSlots.GetAt(i);
00057 if (pActions->Size() == 0)
00058 { PrintTabs(fd, nTabs+2); fprintf(fd, "NULL\n"); }
00059 else pActions->PrintMe(fd, nTabs+2);
00060 PrintTabs(fd, nTabs+2); fprintf(fd, ")\n");
00061 }
00062 PrintTabs(fd, nTabs+1); fprintf(fd, ")\n");
00063 }
00064 PrintTabs(fd, nTabs); fprintf(fd, ")\n");
00065 }
00066
00067 void MHMovement::Initialise(MHParseNode *p, MHEngine *)
00068 {
00069 for (int i = 0; i < p->GetSeqCount(); i++) m_Movement.Append(p->GetSeqN(i)->GetIntValue());
00070 }
00071
00072 void MHMovement::PrintMe(FILE *fd, int nTabs) const
00073 {
00074 PrintTabs(fd, nTabs); fprintf(fd, "( ");
00075 for (int i = 0; i < m_Movement.Size(); i++) fprintf(fd, "%d ", m_Movement.GetAt(i));
00076 fprintf(fd, ")\n");
00077 }
00078
00079 MHTokenGroup::MHTokenGroup()
00080 {
00081 m_nTokenPosition = 1;
00082 }
00083
00084 void MHTokenGroup::Initialise(MHParseNode *p, MHEngine *engine)
00085 {
00086 MHPresentable::Initialise(p, engine);
00087 MHParseNode *pMovements = p->GetNamedArg(C_MOVEMENT_TABLE);
00088 if (pMovements) {
00089 for (int i = 0; i < pMovements->GetArgCount(); i++) {
00090 MHMovement *pMove = new MHMovement;
00091 m_MovementTable.Append(pMove);
00092 pMove->Initialise(pMovements->GetArgN(i), engine);
00093 }
00094 }
00095 MHParseNode *pTokenGrp = p->GetNamedArg(C_TOKEN_GROUP_ITEMS);
00096 if (pTokenGrp) {
00097 for (int i = 0; i < pTokenGrp->GetArgCount(); i++) {
00098 MHTokenGroupItem *pToken = new MHTokenGroupItem;
00099 m_TokenGrpItems.Append(pToken);
00100 pToken->Initialise(pTokenGrp->GetArgN(i), engine);
00101 }
00102 }
00103 MHParseNode *pNoToken = p->GetNamedArg(C_NO_TOKEN_ACTION_SLOTS);
00104 if (pNoToken) {
00105 for (int i = 0; i < pNoToken->GetArgCount(); i++) {
00106 MHParseNode *pAct = pNoToken->GetArgN(i);
00107 MHActionSequence *pActions = new MHActionSequence;
00108 m_NoTokenActionSlots.Append(pActions);
00109
00110 if (pAct->m_nNodeType != MHParseNode::PNNull) pActions->Initialise(pAct, engine);
00111 }
00112 }
00113 }
00114
00115
00116 void MHTokenGroup::PrintContents(FILE *fd, int nTabs) const
00117 {
00118 MHPresentable::PrintMe(fd, nTabs+1);
00119 if (m_MovementTable.Size() != 0) {
00120 PrintTabs(fd, nTabs+1); fprintf(fd, ":MovementTable (\n");
00121 for (int i = 0; i < m_MovementTable.Size(); i++) {
00122 m_MovementTable.GetAt(i)->PrintMe(fd, nTabs+2);
00123 }
00124 PrintTabs(fd, nTabs+1); fprintf(fd, ")\n");
00125 }
00126 if (m_TokenGrpItems.Size() != 0) {
00127 PrintTabs(fd, nTabs+1); fprintf(fd, ":TokenGroupItems (\n");
00128 for (int i = 0; i < m_TokenGrpItems.Size(); i++) {
00129 m_TokenGrpItems.GetAt(i)->PrintMe(fd, nTabs+2);
00130 }
00131 PrintTabs(fd, nTabs+1); fprintf(fd, ")\n");
00132 }
00133 if (m_NoTokenActionSlots.Size() != 0) {
00134 PrintTabs(fd, nTabs+1); fprintf(fd, ":NoTokenActionSlots (\n");
00135 for (int i = 0; i < m_NoTokenActionSlots.Size(); i++) {
00136 MHActionSequence *pActions = m_NoTokenActionSlots.GetAt(i);
00137 if (pActions->Size() == 0) { PrintTabs(fd, nTabs+2); fprintf(fd, "NULL "); }
00138 else pActions->PrintMe(fd, nTabs+2);
00139 }
00140 PrintTabs(fd, nTabs+1); fprintf(fd, ")\n");
00141 }
00142
00143 }
00144
00145 void MHTokenGroup::PrintMe(FILE *fd, int nTabs) const
00146 {
00147 PrintTabs(fd, nTabs); fprintf(fd, "{:TokenGroup ");
00148 PrintContents(fd, nTabs);
00149 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00150 }
00151
00152
00153 void MHTokenGroup::Activation(MHEngine *engine)
00154 {
00155 if (m_fRunning) return;
00156 MHPresentable::Activation(engine);
00157
00158
00159 for (int i = 0; i < m_TokenGrpItems.Size(); i++) {
00160 MHObjectRef *pObject = &m_TokenGrpItems.GetAt(i)->m_Object;
00161
00162
00163 if (pObject->IsSet())
00164 {
00165 try {
00166 engine->FindObject(m_TokenGrpItems.GetAt(i)->m_Object)->Activation(engine);
00167 } catch (char const *) {}
00168 }
00169 }
00170 engine->EventTriggered(this, EventTokenMovedTo, m_nTokenPosition);
00171 m_fRunning = true;
00172 engine->EventTriggered(this, EventIsRunning);
00173 }
00174
00175 void MHTokenGroup::Deactivation(MHEngine *engine)
00176 {
00177 if (! m_fRunning) return;
00178 engine->EventTriggered(this, EventTokenMovedFrom, m_nTokenPosition);
00179 MHPresentable::Deactivation(engine);
00180 }
00181
00182
00183 void MHTokenGroup::TransferToken(int newPos, MHEngine *engine)
00184 {
00185 if (newPos != m_nTokenPosition) {
00186 engine->EventTriggered(this, EventTokenMovedFrom, m_nTokenPosition);
00187 m_nTokenPosition = newPos;
00188 engine->EventTriggered(this, EventTokenMovedTo, m_nTokenPosition);
00189 }
00190 }
00191
00192
00193 void MHTokenGroup::CallActionSlot(int n, MHEngine *engine)
00194 {
00195 if (m_nTokenPosition == 0) {
00196 if (n > 0 && n <= m_NoTokenActionSlots.Size())
00197 engine->AddActions(*(m_NoTokenActionSlots.GetAt(n-1)));
00198 }
00199 else {
00200 if (m_nTokenPosition > 0 && m_nTokenPosition <= m_TokenGrpItems.Size()) {
00201 MHTokenGroupItem *pGroup = m_TokenGrpItems.GetAt(m_nTokenPosition-1);
00202 if (n > 0 && n <= pGroup->m_ActionSlots.Size())
00203 engine->AddActions(*(pGroup->m_ActionSlots.GetAt(n-1)));
00204 }
00205 }
00206 }
00207
00208 void MHTokenGroup::Move(int n, MHEngine *engine)
00209 {
00210 if (m_nTokenPosition == 0 || n < 1 || n > m_MovementTable.Size()) TransferToken(0, engine);
00211 else TransferToken(m_MovementTable.GetAt(n-1)->m_Movement.GetAt(m_nTokenPosition-1), engine);
00212 }
00213
00214
00215
00216
00217 MHListGroup::MHListGroup()
00218 {
00219 m_fWrapAround = false;
00220 m_fMultipleSelection = false;
00221 m_nFirstItem = 1;
00222 m_ItemList.setAutoDelete(true);
00223 m_nLastFirstItem = m_nFirstItem;
00224 m_nLastCount = 0;
00225 }
00226
00227 void MHListGroup::Initialise(MHParseNode *p, MHEngine *engine)
00228 {
00229 MHTokenGroup::Initialise(p, engine);
00230 MHParseNode *pPositions = p->GetNamedArg(C_POSITIONS);
00231 for (int i = 0; i < pPositions->GetArgCount(); i++) {
00232 MHParseNode *pPos = pPositions->GetArgN(i);
00233 QPoint pos(pPos->GetSeqN(0)->GetIntValue(), pPos->GetSeqN(1)->GetIntValue());
00234 m_Positions.Append(pos);
00235 }
00236 MHParseNode *pWrap = p->GetNamedArg(C_WRAP_AROUND);
00237 if (pWrap) m_fWrapAround = pWrap->GetArgN(0)->GetBoolValue();
00238 MHParseNode *pMultiple = p->GetNamedArg(C_WRAP_AROUND);
00239 if (pMultiple) m_fMultipleSelection = pMultiple->GetArgN(0)->GetBoolValue();
00240 }
00241
00242 void MHListGroup::PrintMe(FILE *fd, int nTabs) const
00243 {
00244 PrintTabs(fd, nTabs); fprintf(fd, "{:ListGroup ");
00245 MHTokenGroup::PrintContents(fd, nTabs);
00246 PrintTabs(fd, nTabs+1); fprintf(fd, ":Positions (");
00247 for (int i = 0; i < m_Positions.Size(); i++) {
00248 fprintf(fd, " ( %d %d )", m_Positions.GetAt(i).x(), m_Positions.GetAt(i).y());
00249 }
00250 fprintf(fd, ")\n");
00251 if (m_fWrapAround) { PrintTabs(fd, nTabs+1); fprintf(fd, ":WrapAround true\n"); }
00252 if (m_fMultipleSelection) { PrintTabs(fd, nTabs+1); fprintf(fd, ":MultipleSelection true\n"); }
00253 PrintTabs(fd, nTabs); fprintf(fd, "}\n");
00254 }
00255
00256 void MHListGroup::Preparation(MHEngine *engine)
00257 {
00258 MHTokenGroup::Preparation(engine);
00259 for (int i = 0; i < m_TokenGrpItems.Size(); i++) {
00260
00261 try {
00262 MHRoot *pItem = (MHRoot*)engine->FindObject(m_TokenGrpItems.GetAt(i)->m_Object);
00263 MHListItem *p;
00264 for (p = m_ItemList.first(); p != 0; p = m_ItemList.next()) {
00265 if (p->m_pVisible == pItem) break;
00266 }
00267 if (p == 0) m_ItemList.append(new MHListItem(pItem));
00268 }
00269 catch(...) {
00270 }
00271 }
00272 }
00273
00274 void MHListGroup::Destruction(MHEngine *engine)
00275 {
00276
00277 for (int j = 0; j < (int)m_ItemList.count(); j++) m_ItemList.at(j)->m_pVisible->ResetPosition();
00278 MHTokenGroup::Destruction(engine);
00279 }
00280
00281 void MHListGroup::Activation(MHEngine *engine)
00282 {
00283 m_fFirstItemDisplayed = m_fLastItemDisplayed = false;
00284 MHTokenGroup::Activation(engine);
00285 Update(engine);
00286 }
00287
00288
00289 void MHListGroup::Deactivation(MHEngine *engine)
00290 {
00291
00292 for (int j = 0; j < (int)m_ItemList.count(); j++) m_ItemList.at(j)->m_pVisible->Deactivation(engine);
00293 MHTokenGroup::Deactivation(engine);
00294 }
00295
00296
00297
00298 void MHListGroup::Update(MHEngine *engine)
00299 {
00300 if (m_ItemList.count() == 0) {
00301 if (m_fFirstItemDisplayed) {
00302 m_fFirstItemDisplayed = false;
00303 engine->EventTriggered(this, EventFirstItemPresented, false);
00304 }
00305 if (m_fLastItemDisplayed) {
00306 m_fLastItemDisplayed = false;
00307 engine->EventTriggered(this, EventLastItemPresented, false);
00308 }
00309 }
00310 else {
00311 for (int i = 0; i < (int)m_ItemList.count(); i++) {
00312 MHRoot *pVis = m_ItemList.at(i)->m_pVisible;
00313 int nCell = i+1 - m_nFirstItem;
00314 if (nCell >= 0 && nCell < m_Positions.Size()) {
00315 if (i == 0 && ! m_fFirstItemDisplayed) {
00316 m_fFirstItemDisplayed = true;
00317 engine->EventTriggered(this, EventFirstItemPresented, true);
00318 }
00319 if (i == (int)m_ItemList.count()-1 && ! m_fLastItemDisplayed) {
00320 m_fLastItemDisplayed = true;
00321 engine->EventTriggered(this, EventLastItemPresented, true);
00322 }
00323 try {
00324 pVis->SetPosition(m_Positions.GetAt(i-m_nFirstItem+1).x(), m_Positions.GetAt(i-m_nFirstItem+1).y(), engine);
00325 } catch(...) {}
00326 if (! pVis->GetRunningStatus()) pVis->Activation(engine);
00327 }
00328 else {
00329 if (i == 0 && m_fFirstItemDisplayed) {
00330 m_fFirstItemDisplayed = false;
00331 engine->EventTriggered(this, EventFirstItemPresented, false);
00332 }
00333 if (i == (int)m_ItemList.count()-1 && m_fLastItemDisplayed) {
00334 m_fLastItemDisplayed = false;
00335 engine->EventTriggered(this, EventLastItemPresented, false);
00336 }
00337 if (pVis->GetRunningStatus()) { pVis->Deactivation(engine); pVis->ResetPosition(); }
00338 }
00339 }
00340 }
00341
00342
00343 if (m_nLastFirstItem != m_nFirstItem) {
00344 engine->EventTriggered(this, EventHeadItems, m_nFirstItem);
00345 }
00346 if (m_nLastCount - m_nLastFirstItem != (int)m_ItemList.count() - m_nFirstItem) {
00347 engine->EventTriggered(this, EventTailItems, (int)m_ItemList.count() - m_nFirstItem);
00348 }
00349 m_nLastCount = m_ItemList.count();
00350 m_nLastFirstItem = m_nFirstItem;
00351 }
00352
00353
00354 void MHListGroup::AddItem(int nIndex, MHRoot *pItem, MHEngine *engine)
00355 {
00356
00357 for (MHListItem *p = m_ItemList.first(); p != 0; p = m_ItemList.next()) {
00358 if (p->m_pVisible == pItem) return;
00359 }
00360
00361 if (nIndex < 1 || nIndex > (int)m_ItemList.count()+1) return;
00362
00363 m_ItemList.insert(nIndex-1, new MHListItem(pItem));
00364 if (nIndex <= m_nFirstItem && m_nFirstItem < (int)m_ItemList.count()) m_nFirstItem++;
00365 Update(engine);
00366 }
00367
00368
00369 void MHListGroup::DelItem(MHRoot *pItem, MHEngine *)
00370 {
00371
00372 for (int i = 0; i < (int)m_ItemList.count(); i++) {
00373 if (m_ItemList.at(i)->m_pVisible == pItem) {
00374 m_ItemList.remove(i);
00375 pItem->ResetPosition();
00376 if (i+1 < m_nFirstItem && m_nFirstItem > 1) m_nFirstItem--;
00377 return;
00378 }
00379 }
00380 }
00381
00382
00383 void MHListGroup::Select(int nIndex, MHEngine *engine)
00384 {
00385 MHListItem *pListItem = m_ItemList.at(nIndex-1);
00386 if (pListItem == 0 || pListItem->m_fSelected) return;
00387 if (! m_fMultipleSelection) {
00388
00389 for (int i = 0; i < (int)m_ItemList.count(); i++)
00390 if (m_ItemList.at(i)->m_fSelected) Deselect(i+1, engine);
00391 }
00392 pListItem->m_fSelected = true;
00393 engine->EventTriggered(this, EventItemSelected, nIndex);
00394 }
00395
00396
00397 void MHListGroup::Deselect(int nIndex, MHEngine *engine)
00398 {
00399 MHListItem *pListItem = m_ItemList.at(nIndex-1);
00400 if (pListItem == 0 || ! pListItem->m_fSelected) return;
00401 pListItem->m_fSelected = false;
00402 engine->EventTriggered(this, EventItemDeselected, nIndex);
00403 }
00404
00405
00406 void MHListGroup::GetCellItem(int nCell, const MHObjectRef &itemDest, MHEngine *engine)
00407 {
00408 if (nCell < 1) nCell = 1;
00409 if (nCell > m_Positions.Size()) nCell = m_Positions.Size();
00410 int nVisIndex = nCell + m_nFirstItem - 2;
00411 if (nVisIndex >= 0 && nVisIndex < (int)m_ItemList.count()) {
00412 MHRoot *pVis = m_ItemList.at(nVisIndex)->m_pVisible;
00413 engine->FindObject(itemDest)->SetVariableValue(pVis->m_ObjectReference);
00414 }
00415 else engine->FindObject(itemDest)->SetVariableValue(MHObjectRef::Null);
00416 }
00417
00418 int MHListGroup::AdjustIndex(int nIndex)
00419 {
00420 int nItems = m_ItemList.count();
00421 if (nItems == 0) return 1;
00422 if (nIndex > nItems) return ((nIndex-1) % nItems) + 1;
00423 else if (nIndex < 0) return nItems - ((-nIndex) % nItems);
00424 else return nIndex;
00425 }
00426
00427 void MHListGroup::GetListItem(int nCell, const MHObjectRef &itemDest, MHEngine *engine)
00428 {
00429 if (m_fWrapAround) nCell = AdjustIndex(nCell);
00430 if (nCell < 1 || nCell > (int)m_ItemList.count()) return;
00431 engine->FindObject(itemDest)->SetVariableValue(m_ItemList.at(nCell-1)->m_pVisible->m_ObjectReference);
00432 }
00433
00434 void MHListGroup::GetItemStatus(int nCell, const MHObjectRef &itemDest, MHEngine *engine)
00435 {
00436 if (m_fWrapAround) nCell = AdjustIndex(nCell);
00437 if (nCell < 1 || nCell > (int)m_ItemList.count()) return;
00438 engine->FindObject(itemDest)->SetVariableValue(m_ItemList.at(nCell-1)->m_fSelected);
00439 }
00440
00441 void MHListGroup::SelectItem(int nCell, MHEngine *engine)
00442 {
00443 if (m_fWrapAround) nCell = AdjustIndex(nCell);
00444 if (nCell < 1 || nCell > (int)m_ItemList.count()) return;
00445 Select(nCell, engine);
00446 }
00447
00448 void MHListGroup::DeselectItem(int nCell, MHEngine *engine)
00449 {
00450 if (m_fWrapAround) nCell = AdjustIndex(nCell);
00451 if (nCell < 1 || nCell > (int)m_ItemList.count()) return;
00452 Deselect(nCell, engine);
00453 }
00454
00455 void MHListGroup::ToggleItem(int nCell, MHEngine *engine)
00456 {
00457 if (m_fWrapAround) nCell = AdjustIndex(nCell);
00458 if (nCell < 1 || nCell > (int)m_ItemList.count()) return;
00459 if (m_ItemList.at(nCell-1)->m_fSelected) Deselect(nCell, engine); else Select(nCell, engine);
00460 }
00461
00462 void MHListGroup::ScrollItems(int nCell, MHEngine *engine)
00463 {
00464 nCell += m_nFirstItem;
00465 if (m_fWrapAround) nCell = AdjustIndex(nCell);
00466 if (nCell < 1 || nCell > (int)m_ItemList.count()) return;
00467 m_nFirstItem = nCell;
00468 Update(engine);
00469 }
00470
00471 void MHListGroup::SetFirstItem(int nCell, MHEngine *engine)
00472 {
00473 if (m_fWrapAround) nCell = AdjustIndex(nCell);
00474 if (nCell < 1 || nCell > (int)m_ItemList.count()) return;
00475 m_nFirstItem = nCell;
00476 Update(engine);
00477 }
00478
00479
00480
00481
00482 void MHAddItem::Initialise(MHParseNode *p, MHEngine *engine)
00483 {
00484 MHElemAction::Initialise(p, engine);
00485 m_Index.Initialise(p->GetArgN(1), engine);
00486 m_Item.Initialise(p->GetArgN(2), engine);
00487 }
00488
00489 void MHAddItem::PrintArgs(FILE *fd, int) const
00490 {
00491 m_Index.PrintMe(fd, 0);
00492 m_Item.PrintMe(fd, 0);
00493 }
00494
00495 void MHAddItem::Perform(MHEngine *engine)
00496 {
00497 MHObjectRef item;
00498 m_Item.GetValue(item, engine);
00499 Target(engine)->AddItem(m_Index.GetValue(engine), engine->FindObject(item), engine);
00500 }
00501
00502 void MHGetListActionData::Initialise(MHParseNode *p, MHEngine *engine)
00503 {
00504 MHElemAction::Initialise(p, engine);
00505 m_Index.Initialise(p->GetArgN(1), engine);
00506 m_Result.Initialise(p->GetArgN(2), engine);
00507 }
00508
00509 void MHGetListActionData::PrintArgs(FILE *fd, int) const
00510 {
00511 m_Index.PrintMe(fd, 0);
00512 m_Result.PrintMe(fd, 0);
00513 }