256 lines
5.4 KiB
C++
256 lines
5.4 KiB
C++
#include "stdafx.h"
|
|
#include "acp_base.h"
|
|
#ifdef ACTIVE_EDITOR
|
|
|
|
#include "itf/CPAWData.hpp"
|
|
#pragma warning(disable:4355)
|
|
CPA_WalkDataMgr::CPA_WalkDataMgr():WalkData(this, NULL) {
|
|
|
|
for (iVoid=0; iVoid<MAX_WALKDATA_ELEMENT; iVoid++) {
|
|
aWD [iVoid].ItsData = NULL;
|
|
aWD [iVoid].backnext = NO_ID;
|
|
aWD [iVoid].backprev = NO_ID;
|
|
aWD [iVoid].next = NO_ID;
|
|
aWD [iVoid].prev = NO_ID;
|
|
}
|
|
iVoid = 0;
|
|
iCount = 0;
|
|
}
|
|
|
|
CPA_WalkDataMgr::~CPA_WalkDataMgr() {
|
|
int i;
|
|
for (i=iCurrent; i!=NO_ID; i=aWD[i].backprev) {
|
|
delete ((WalkData *)aWD[i].ItsData);
|
|
}
|
|
}
|
|
|
|
void CPA_WalkDataMgr::InsertElement (CPA_DLLBase *pDLL, void *ItsData) {
|
|
GoElement (pDLL);
|
|
WalkData *pWDToInsertTo = (WalkData *)aWD[iCurrent].ItsData;
|
|
#ifdef CHECK // check if occurence already exists.
|
|
if (!pWDToInsertTo->CheckAndGoElement (ItsData)) {
|
|
pWDToInsertTo->InsertVoidElement (ItsData);
|
|
UpdateIVoid();
|
|
}
|
|
#else
|
|
pWDToInsertTo->InsertVoidElement (ItsData);
|
|
UpdateIVoid();
|
|
#endif
|
|
}
|
|
|
|
void CPA_WalkDataMgr::ActiveElement (CPA_DLLBase *pDLL) {
|
|
GoElement (pDLL);
|
|
ActiveCurrent();
|
|
}
|
|
|
|
/******************** private *******************/
|
|
|
|
void CPA_WalkDataMgr::UpdateAll () {
|
|
int i;
|
|
for (i=iCurrent; i!=NO_ID; i=aWD[i].backprev) {
|
|
((WalkData *)aWD[i].ItsData)->UpdateList();
|
|
}
|
|
}
|
|
|
|
void CPA_WalkDataMgr::UpdateIVoid() {
|
|
int i, j;
|
|
WalkData *pWD;
|
|
|
|
if (iCount!=MAX_WALKDATA_ELEMENT-1) {
|
|
iVoid = ++iCount;
|
|
}
|
|
else {// take an element already used
|
|
i=iLastUsed;
|
|
do {
|
|
pWD = (WalkData *)aWD[i].ItsData;
|
|
i=aWD[i].next;
|
|
}
|
|
while (pWD->iCurrent==NO_ID);
|
|
j = pWD->iLastUsed;
|
|
iVoid = j;
|
|
|
|
// tell DLL that the data is no longer of use.
|
|
pWD->MyDLL->fn_vEraseWalkDataStructure (aWD[j].ItsData);
|
|
|
|
// update list
|
|
if (j == pWD->iCurrent) // this WD had only one element
|
|
pWD->iCurrent = NO_ID;
|
|
else { // update the element linked to the one we took
|
|
pWD->iLastUsed = aWD[j].next;
|
|
aWD[pWD->iLastUsed].prev = NO_ID;
|
|
aWD[pWD->iLastUsed].backprev = NO_ID;
|
|
}
|
|
// clean new Void element (for safety)
|
|
aWD[j].next = aWD[j].prev = NO_ID;
|
|
aWD[j].backnext = aWD[j].backprev = NO_ID;
|
|
}
|
|
}
|
|
|
|
int CPA_WalkDataMgr::FindOrCreateWalkData (CPA_DLLBase *pDLL) {
|
|
int i, iInsertNode;
|
|
|
|
for (i=iCurrent; i!=NO_ID; i=aWD[i].backprev) {
|
|
if (((WalkData *)aWD[i].ItsData)->MyDLL == pDLL) {
|
|
iInsertNode = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i==NO_ID) { // New Node
|
|
iInsertNode = iVoid;
|
|
InsertVoidElement((void *)new WalkData (this, pDLL));
|
|
UpdateIVoid();
|
|
}
|
|
return (iInsertNode);
|
|
}
|
|
|
|
void CPA_WalkDataMgr::GoElement (CPA_DLLBase *pDLL) {
|
|
int iNew;
|
|
UpdateAll ();
|
|
iNew = FindOrCreateWalkData (pDLL);
|
|
if (iNew != iCurrent) Go (iNew);
|
|
UpdateList ();
|
|
}
|
|
|
|
inline void CPA_WalkDataMgr::ActiveCurrent() {
|
|
((WalkData *)aWD[iCurrent].ItsData)->BackActive();
|
|
}
|
|
|
|
void CPA_WalkDataMgr::DBackward() {
|
|
if (iCurrent!=NO_ID)
|
|
if (((WalkData *)aWD[iCurrent].ItsData)->Backward())
|
|
ActiveCurrent();
|
|
}
|
|
|
|
void CPA_WalkDataMgr::DForward() {
|
|
if (iCurrent!=NO_ID)
|
|
if (((WalkData *)aWD[iCurrent].ItsData)->Forward())
|
|
ActiveCurrent();
|
|
}
|
|
|
|
void CPA_WalkDataMgr::EBackward() {
|
|
if (Backward ())
|
|
ActiveCurrent();
|
|
}
|
|
|
|
void CPA_WalkDataMgr::EForward() {
|
|
if (Forward ())
|
|
ActiveCurrent();
|
|
}
|
|
|
|
/************************* WalkData ************************/
|
|
|
|
WalkData::WalkData(CPA_WalkDataMgr *aWDM, CPA_DLLBase *pDLL) {
|
|
MyWDM = aWDM;
|
|
aWD = aWDM->aWD; // ne changera pas
|
|
iCurrent = NO_ID;
|
|
iFirst = NO_ID;
|
|
iLast = NO_ID;
|
|
iLastUsed = NO_ID;
|
|
MyDLL = pDLL;
|
|
}
|
|
|
|
inline void WalkData::ABLink (int a, int b) {aWD[a].next = b; aWD[b].prev = a;BLink(a,b);}
|
|
inline void WalkData::BLink (int a, int b) {aWD[a].backnext = b; aWD[b].backprev = a;}
|
|
|
|
void WalkData::UpdateList(){
|
|
int i;
|
|
if ((iCurrent==NO_ID) || (iLast==iCurrent)) return;
|
|
|
|
for (i=iLast; i!=NO_ID; i=aWD[i].backnext) { // updatelist
|
|
aWD[i].prev = aWD[i].backprev;
|
|
aWD[i].next = aWD[i].backnext;
|
|
};
|
|
iLast = iCurrent;
|
|
}
|
|
|
|
int WalkData::CheckAndGoElement (void *ItsData) {
|
|
int i;
|
|
for (i=iCurrent; i!=NO_ID; i=aWD[i].prev) {
|
|
if ((aWD[i].ItsData == ItsData) && (aWD[i].ItsData == ItsData)) {
|
|
if (i!=iCurrent) Go(i);
|
|
UpdateList();
|
|
return (TRUE);
|
|
}
|
|
}
|
|
return (FALSE);
|
|
}
|
|
|
|
void WalkData::InsertVoidElement (void *ItsData) {
|
|
UpdateList();
|
|
|
|
iLast = iFirst = MyWDM->iVoid;
|
|
|
|
if (iCurrent!=NO_ID)
|
|
ABLink (iCurrent, iFirst);
|
|
else {
|
|
iLastUsed = iFirst;
|
|
aWD[iFirst].prev = NO_ID;
|
|
aWD[iFirst].backprev = NO_ID;
|
|
}
|
|
aWD[iFirst].aWalkData = this;
|
|
aWD[iFirst].ItsData = ItsData;
|
|
aWD[iFirst].next = NO_ID;
|
|
aWD[iFirst].backnext = NO_ID;
|
|
|
|
iCurrent = iFirst;
|
|
|
|
}
|
|
|
|
int WalkData::Backward() {
|
|
int iNew;
|
|
|
|
if (iCurrent==NO_ID) return (FALSE);
|
|
|
|
iNew = aWD[iCurrent].prev;
|
|
if (iNew == NO_ID) return (FALSE);
|
|
|
|
Go (iNew);
|
|
return (TRUE);
|
|
}
|
|
|
|
int WalkData::Forward() {
|
|
int iNew;
|
|
|
|
if (iCurrent==NO_ID) return (FALSE);
|
|
|
|
iNew = aWD[iCurrent].next;
|
|
if (iNew == NO_ID) return (FALSE);
|
|
|
|
Go (iNew);
|
|
return (TRUE);
|
|
}
|
|
|
|
void WalkData::Go(int iNew) { // iNew must not be iCurrent nor NO_ID
|
|
int i, j, k;
|
|
|
|
j = aWD[iNew].backprev;
|
|
k = aWD[iNew].backnext;
|
|
if (j!=NO_ID)
|
|
BLink (j, k);
|
|
else {
|
|
aWD[k].backprev = NO_ID;
|
|
if (iLast==iNew) iLast = k;
|
|
else j=k; // to update iLast correctly
|
|
}
|
|
if (iLastUsed==iNew) iLastUsed = k;
|
|
|
|
BLink (iCurrent, iNew);
|
|
aWD[iNew].backnext = NO_ID;
|
|
iCurrent = iNew;
|
|
|
|
// update iLast if needed
|
|
for (i=j; (i!=iLast) && (i!=NO_ID); i=aWD[i].backnext);
|
|
if (i==iLast) iLast = j;
|
|
}
|
|
|
|
void WalkData::BackActive () {
|
|
if (iCurrent==NO_ID)
|
|
MyDLL->fn_vBackActiveMe (NULL);
|
|
else
|
|
MyDLL->fn_vBackActiveMe (aWD[iCurrent].ItsData);
|
|
}
|
|
|
|
#endif
|
|
|