#include "T2CrossEquipArray.h" #include "T2FInfoAreaIterator.h" #include "T2FloorInfo.h" #include "T2FloorPtrList.h" #include "T2Mover.h" #include "T2MoverRoutingTable.h" #include "T2RoutingTable.h" #include "T2RoutingTableElem.h" #include "T2Tenant.h" T2RoutingTable::T2RoutingTable(T2FloorInfo* inFloorInfo, T2FloorPtrList* inFloorPtrList, int inWhichTable) : LArray(sizeof(T2MoverRoutingTable *)) { mAttributeMask = kMoverAttrRoutingTable0 << inWhichTable; mFloorPtrList = inFloorPtrList; mFloorInfo = inFloorInfo; } /*virtual*/ T2RoutingTable::~T2RoutingTable() { LArrayIterator iterator(*this); T2MoverRoutingTable *theTable; while (iterator.Next(&theTable)) delete theTable; } void T2RoutingTable::FloorAdded() { LArrayIterator iterator(*this); T2MoverRoutingTable *theTable; while (iterator.Next(&theTable)) theTable->AddItems(1); } void T2RoutingTable::FloorRemoved(int inFloorID) { LArrayIterator iterator(*this); T2MoverRoutingTable *theTable; while (iterator.Next(&theTable)) theTable->RemoveItem(inFloorID); } BOOL T2RoutingTable::IsRelatedMover(T2Mover* inMover) const { return inMover->IsSetAttribute(mAttributeMask); } void T2RoutingTable::MoverAdded(T2Mover* inMover, BOOL inFlag) { if (IsRelatedMover(inMover)) { AddItem(inMover); if (inFlag) { T2MoverRoutingTable *theTable = GetItem(inMover); if (theTable) { theTable->SetStopFloor(); Update(); } } } } void T2RoutingTable::MoverRemoved(T2Mover* inMover, BOOL inFlag) { if (IsRelatedMover(inMover)) { RemoveItem(inMover); if (inFlag) FullUpdate(); } } void T2RoutingTable::MoverModified(T2Mover* inMover, BOOL inFlag) { if (IsRelatedMover(inMover)) { if (inFlag) { FullUpdate(); } else { T2MoverRoutingTable *theTable = GetItem(inMover); if (theTable) { theTable->SetStopFloor(); Update(); } } } } void T2RoutingTable::AddItem(T2Mover* inMover) { T2MoverRoutingTable *theMoverRoutingTable = new T2MoverRoutingTable(mFloorInfo, mFloorPtrList, inMover); #line 162 _ASSERT(theMoverRoutingTable != NULL); InsertItemsAt(1, mItemCount + 1, &theMoverRoutingTable); } void T2RoutingTable::RemoveItem(T2Mover* inMover) { RemoveItemsAt(1, GetIndex(inMover)); } T2MoverRoutingTable* T2RoutingTable::GetItem(T2Mover* inMover) const { T2MoverRoutingTable *theMoverRoutingTable = NULL; LArrayIterator iterator(*this); T2MoverRoutingTable *item; while (!theMoverRoutingTable && iterator.Next(&item)) { if (item->GetMover() == inMover) theMoverRoutingTable = item; } return theMoverRoutingTable; } BOOL T2RoutingTable::GetElem(T2Mover* inMover, int inFloor, T2RoutingTableElem& outElem) const { BOOL ok = false; T2MoverRoutingTable *theMoverRoutingTable = GetItem(inMover); if (theMoverRoutingTable && theMoverRoutingTable->GetItem(inFloor, outElem)) ok = true; return ok; } int T2RoutingTable::GetIndex(T2Mover* inMover) const { int result = 0; int unused = 0; LArrayIterator iterator(*this); int i = 1; T2MoverRoutingTable *theMoverRoutingTable; while (result == 0 && iterator.Next(&theMoverRoutingTable)) { if (theMoverRoutingTable->GetMover() == inMover) result = i; else i++; } return result; } void T2RoutingTable::Update() { BOOL working = true; while (working) { working = false; LArrayIterator iterator1(*this); T2MoverRoutingTable *table1; while (iterator1.Next(&table1)) { LArrayIterator iterator2(*this); T2MoverRoutingTable *table2; while (iterator2.Next(&table2)) { if (table1 != table2) working |= table1->Update(table2); } } } } void T2RoutingTable::FullUpdate() { ClearData(); LArrayIterator iterator(*this); T2MoverRoutingTable *theMoverRoutingTable; while (iterator.Next(&theMoverRoutingTable)) theMoverRoutingTable->SetStopFloor(); Update(); } void T2RoutingTable::ClearData() { LArrayIterator iterator(*this); T2MoverRoutingTable *theMoverRoutingTable; while (iterator.Next(&theMoverRoutingTable)) theMoverRoutingTable->ClearData(); } BOOL T2RoutingTable::CheckRoute(POINT inFromPt, POINT inToPt, unsigned int inSearchScore) const { BOOL result = false; T2Tenant *nextFloor = mFloorInfo->GetFloor(inToPt.y, inToPt.x); int nextFloorIdx = mFloorPtrList->GetIndex(nextFloor); if (nextFloorIdx) { T2Tenant *prevFloor = mFloorInfo->GetFloor(inFromPt.y, inFromPt.x); if (prevFloor) { if (prevFloor == nextFloor) { if (abs(inFromPt.x - inToPt.x) <= inSearchScore) result = true; } else { unsigned int prevFloorID = prevFloor->GetEquipID(); LArrayIterator iterator(*prevFloor->GetCEArray()); unsigned int moverID; while (!result && iterator.Next(&moverID)) { T2Mover *theMover = mFloorInfo->GetMover(moverID); if (theMover && IsRelatedMover(theMover)) { T2MoverRoutingTable *theMoverRoutingTable = GetItem(theMover); if (theMoverRoutingTable) { unsigned int distance; if (theMoverRoutingTable->GetNextRoute(inFromPt, prevFloorID, inToPt, nextFloorIdx, distance)) { if (distance <= inSearchScore) result = true; } } } } } } } return result; } BOOL T2RoutingTable::IsConnectRouteFromLobby(POINT inPt) const { BOOL result = false; T2Tenant *floor = mFloorInfo->GetFloor(inPt.y, inPt.x); int floorIndex = mFloorPtrList->GetIndex(floor); if (floorIndex) { T2Tenant *lobby = mFloorInfo->GetTenant(1000); if (lobby) { LArrayIterator iterator(*lobby->GetCEArray()); unsigned int moverID; while (!result && iterator.Next(&moverID)) { T2Mover *theMover = mFloorInfo->GetMover(moverID); if (theMover && IsRelatedMover(theMover)) { T2MoverRoutingTable *theMoverRoutingTable = GetItem(theMover); if (theMoverRoutingTable) result = theMoverRoutingTable->IsConnectRoute(floorIndex); } } } } return result; } BOOL T2RoutingTable::GetNextRoute(POINT inFromPt, POINT& ioToPt) const { BOOL result = false; POINT toPt = ioToPt; T2Tenant *destFloor = mFloorInfo->GetFloor(toPt.y, toPt.x); int destFloorIdx = mFloorPtrList->GetIndex(destFloor); if (destFloorIdx) { T2Tenant *srcFloor = mFloorInfo->GetFloor(inFromPt.y, inFromPt.x); if (srcFloor) { unsigned int optimalScore = 100000; T2Mover *optimalMover = NULL; int srcFloorIdx = srcFloor->GetEquipID(); LArrayIterator iterator(*srcFloor->GetCEArray()); unsigned int theMoverID; while (iterator.Next(&theMoverID)) { T2Mover *theMover = mFloorInfo->GetMover(theMoverID); if (theMover && IsRelatedMover(theMover)) { T2MoverRoutingTable *theMoverRoutingTable = GetItem(theMover); if (theMoverRoutingTable) { POINT thisPt = toPt; unsigned int thisScore; if (theMoverRoutingTable->GetNextRoute(inFromPt, srcFloorIdx, thisPt, destFloorIdx, thisScore)) { if (thisScore < optimalScore) { optimalScore = thisScore; optimalMover = theMover; ioToPt = thisPt; result |= true; } } } } } } } return result; } T2Tenant* T2RoutingTable::SelectNearTenant(POINT inPt, unsigned int inSearchScore) const { T2Tenant *selectedTenant = NULL; T2Tenant *theFloor = mFloorInfo->GetFloor(inPt.y, inPt.x); if (theFloor) { T2CrossEquipArray *theCEArray = theFloor->GetCEArray(); if (theCEArray) { unsigned int first; unsigned int numOfCE = theCEArray->GetCount(); if (numOfCE != 0) first = (rand() % numOfCE) + 1; else first = 1; T2Mover *theMover = NULL; for (unsigned int i = 0; !theMover && i < numOfCE; i++) { int index = first + i; if (index > numOfCE) index -= numOfCE; unsigned int theMoverID; theCEArray->FetchItemAt(index, &theMoverID); theMover = mFloorInfo->GetMover(theMoverID); if (theMover && !IsRelatedMover(theMover)) theMover = NULL; } T2Tenant *flr = NULL; unsigned int maxHDistance = inSearchScore; int hPos = inPt.x; if (theMover) { T2MoverRoutingTable *theMoverRoutingTable = GetItem(theMover); if (theMoverRoutingTable) flr = theMoverRoutingTable->SelectNearFloor(inPt, hPos, maxHDistance); } if (!flr) flr = theFloor; selectedTenant = SelectNearTenant(flr, hPos, maxHDistance); } } return selectedTenant; } T2Tenant* T2RoutingTable::SelectNearTenant(T2Tenant* inTenant, int inH, unsigned int inSearchScore) const { T2Tenant *selectedTenant = NULL; RECT searchRect; inTenant->GetEquipArea(searchRect); searchRect.top = searchRect.bottom - 1; searchRect.left = inH - inSearchScore; searchRect.right = inH + inSearchScore; T2FInfoAreaIterator iterator(*mFloorInfo, searchRect); T2Tenant *theTenant; int count = 0; while (iterator.NextTenant(theTenant)) { if (!theTenant->IsFloor() && !theTenant->IsBind() && theTenant->IsTherePeople()) count++; } if (count > 0) { int randomIndex = rand() % count; int i = 0; iterator.Reset(); while (!selectedTenant && iterator.NextTenant(theTenant)) { if (!theTenant->IsFloor() && !theTenant->IsBind() && theTenant->IsTherePeople()) { if (i == randomIndex) selectedTenant = theTenant; else i++; } } } return selectedTenant; }