diff options
Diffstat (limited to 'src/T2DLL/T2RoutingTable.cpp')
-rw-r--r-- | src/T2DLL/T2RoutingTable.cpp | 360 |
1 files changed, 340 insertions, 20 deletions
diff --git a/src/T2DLL/T2RoutingTable.cpp b/src/T2DLL/T2RoutingTable.cpp index 8380825..c6ae7fa 100644 --- a/src/T2DLL/T2RoutingTable.cpp +++ b/src/T2DLL/T2RoutingTable.cpp @@ -1,82 +1,402 @@ +#include "T2FInfoAreaIterator.h" +#include "T2FloorInfo.h" +#include "T2FloorPtrList.h" +#include "T2Mover.h" +#include "T2MoverRoutingTable.h" #include "T2RoutingTable.h" +#include "T2Tenant.h" -T2RoutingTable::T2RoutingTable(T2FloorInfo*, T2FloorPtrList*, int) { +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) { +void T2RoutingTable::FloorRemoved(int inFloorID) { + LArrayIterator iterator(*this); + T2MoverRoutingTable *theTable; + + while (iterator.Next(&theTable)) + theTable->RemoveItem(inFloorID); } -int T2RoutingTable::IsRelatedMover(T2Mover*) const { +BOOL T2RoutingTable::IsRelatedMover(T2Mover* inMover) const { + return inMover->IsSetAttribute(mAttributeMask); } -void T2RoutingTable::MoverAdded(T2Mover*, int) { +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*, int) { +void T2RoutingTable::MoverRemoved(T2Mover* inMover, BOOL inFlag) { + if (IsRelatedMover(inMover)) { + RemoveItem(inMover); + + if (inFlag) + FullUpdate(); + } } -void T2RoutingTable::MoverModified(T2Mover*, int) { +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*) { +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*) { +void T2RoutingTable::RemoveItem(T2Mover* inMover) { + RemoveItemsAt(1, GetIndex(inMover)); } -T2MoverRoutingTable* T2RoutingTable::GetItem(T2Mover*) const { +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; } -int T2RoutingTable::GetElem(T2Mover*, int, T2RoutingTableElem&) const { +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*) const { +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(); } -int T2RoutingTable::CheckRoute(POINT, POINT, unsigned int) const { +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; } -int T2RoutingTable::IsConnectRouteFromLobby(POINT) const { +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; } -int T2RoutingTable::GetNextRoute(POINT, POINT&) const { +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, unsigned int) const { +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*, int, unsigned int) const { +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; } + + T2RoutingTableElem::T2RoutingTableElem() { + mNextFloorID = 0; + mScore = 0; + mTime = 0; + mFinalHPos = 0; } T2RoutingTableElem::~T2RoutingTableElem() { } -int T2RoutingTableElem::IsStopFloor() const { +BOOL T2RoutingTableElem::IsStopFloor() const { + return ((mNextFloorID != 0) && (mScore == 0)); } -void T2RoutingTableElem::SetTable(unsigned int, int) { +void T2RoutingTableElem::SetTable(unsigned int inNextFloorID, int inFinalHPos) { + mNextFloorID = inNextFloorID; + mScore = 0; + mTime = 0; + mFinalHPos = inFinalHPos; } -int T2RoutingTableElem::IsSetTable(unsigned int, unsigned int, int, int) { +BOOL T2RoutingTableElem::IsSetTable(unsigned int inNextFloorID, unsigned int inScore, int inTime, int inFinalHPos) { + BOOL result = false; + + if (mNextFloorID == 0 || mScore > inScore) { + mNextFloorID = inNextFloorID; + mScore = inScore; + mTime = inTime; + mFinalHPos = inFinalHPos; + result = true; + } + + return result; } -int T2RoutingTableElem::HasNextRoute(unsigned int) const { +BOOL T2RoutingTableElem::HasNextRoute(unsigned int inFloorID) const { + return (mNextFloorID != 0) && (mNextFloorID != inFloorID); } |