reman3/Rayman_X/cpa/tempgrp/ITF/CpaListB.cpp

1455 lines
49 KiB
C++

//*****************************************************************************
//* CpaListB.cpp *
//*****************************************************************************
//* *
//* Functions of the CPA_BaseObjectList class : list of CPA_BaseObject with *
//* different sort orders and fast search functions. *
//* *
//*****************************************************************************
//* Author : Yann Le Tensorer, Alexis Vaisse *
//*****************************************************************************
#include "stdafx.h"
#ifdef ACTIVE_EDITOR
#include "itf/CPAListB.hpp"
#include "itf/CPABaseO.hpp"
#define C_lSizeIncrease 16 // When the array must be reallocated, we add space for 16 more objects
#define stricmp __asmstricmp
//*****************************************************************************
//********** Construction and destruction **********
//*****************************************************************************
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - constructor
//-----------------------------------------------------------------------------
CPA_BaseObjectList::CPA_BaseObjectList (const CString _csTypeName /* = "" */)
{
m_csTypeName = _csTypeName;
m_szTypeName = (char *) (LPCTSTR) m_csTypeName;
m_lNumberOfObjects = 0;
m_lMaxNumberOfObjects = 0;
m_lCurrentUniqueIndex = 0;
for (int i = E_lo_First ; i <= E_lo_Last ; i ++)
m_Array [i] = NULL;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - destructor
//-----------------------------------------------------------------------------
CPA_BaseObjectList::~CPA_BaseObjectList ()
{
DeleteAllElements ();
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - ReallocArray
// Change the size of the arrray
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::ReallocArray (long _lNewSize)
{
for (int i = E_lo_First ; i <= E_lo_Last ; i ++)
{
if (_lNewSize == 0)
{
if (m_Array [i] != NULL)
{
free (m_Array [i]);
m_Array [i] = NULL;
}
}
else
{
if (m_Array [i] == NULL)
m_Array [i] = (tdp_BaseObjectPointer *) malloc ( sizeof (tdp_BaseObjectPointer) * _lNewSize);
else m_Array [i] = (tdp_BaseObjectPointer *) realloc (m_Array [i] , sizeof (tdp_BaseObjectPointer) * _lNewSize);
}
}
m_lMaxNumberOfObjects = _lNewSize;
if (m_lNumberOfObjects > m_lMaxNumberOfObjects) m_lNumberOfObjects = m_lMaxNumberOfObjects;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - DeleteAllElements
// Empty the list but do not delete the CPA_BaseObject
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::DeleteAllElements ()
{
ReallocArray (0);
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - DeleteAllObjects
// Empty the list and delete all CPA_BaseObject
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::DeleteAllObjects ()
{
// Delete all objects using object order (any order could workd)
for (long i = 0 ; i < m_lNumberOfObjects ; i ++)
delete m_Array [E_lo_Object] [i];
DeleteAllElements ();
}
//*****************************************************************************
//********** Low level functions **********
//*****************************************************************************
//=============================================================================
// asm defined stricmp to fasten a little bit the very very slow function
// written by microsoft...
//=============================================================================
int __asmstricmp(char * a, char * b)
{
char retour;
_asm
{
mov eax,a
mov ebx,b
boucle:
mov ecx,dword ptr[eax]
mov edx,dword ptr[ebx]
;============= first word
cmp cl,97
jge sub32cl
cmp dl,97
jge sub32dl
jmp suite
sub32cl:
sub cl,32
cmp dl,97
jl suite
sub32dl:
sub dl,32
suite:
sub cl,dl
cmp dl,0
je fin
cmp cl,0
jne fin
cmp ch,97
jge sub32ch
cmp dh,97
jge sub32dh
jmp suite2
sub32ch:
sub ch,32
cmp dh,97
jl suite2
sub32dh:
sub dh,32
suite2:
sub ch,dh
cmp dh,0
je fin2
cmp ch,0
jne fin2
;================ end first word
shr ecx,16
shr edx,16
;============= second word
cmp cl,97
jge sub32clx
cmp dl,97
jge sub32dlx
jmp suitex
sub32clx:
sub cl,32
cmp dl,97
jl suitex
sub32dlx:
sub dl,32
suitex:
sub cl,dl
cmp dl,0
je fin
cmp cl,0
jne fin
cmp ch,97
jge sub32chx
cmp dh,97
jge sub32dhx
jmp suite2x
sub32chx:
sub ch,32
cmp dh,97
jl suite2x
sub32dhx:
sub dh,32
suite2x:
sub ch,dh
cmp dh,0
je fin2
cmp ch,0
jne fin2
;================ end second word
add eax,4
add ebx,4
jmp boucle
fin:
mov retour,cl
jmp VraieFin
fin2:
mov retour,ch
VraieFin:
}
return (int)retour;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lDichoSearchName
// Low level function to find an object with a given name in a given list
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lDichoSearchName(CPA_BaseObject** _p_oList, unsigned long _ulListSize, char* _NameToFind,BOOL* _bFound,CPA_BaseObject* _p_oAdress)
{
unsigned long Haut=-1;
unsigned long Bas=_ulListSize;
unsigned long Milieu=(Haut+Bas)>>1;
long signe;
while (Bas!=Haut+1)
{
signe=stricmp((_p_oList[Milieu]->fn_p_szGetName()),_NameToFind);
/* This is used to continue search on adress if wanted */
if (signe==0 && _p_oAdress!=NULL) signe=(long)(_p_oList[Milieu]-_p_oAdress);
if (signe<0)
{
Haut=Milieu;
Milieu=(Bas+Milieu)>>1;
}
else
if (signe>0)
{
Bas=Milieu;
Milieu=(Haut+Milieu)>>1;
}
else
{
*_bFound=TRUE;
return Milieu;
}
};
*_bFound=FALSE;
return Bas;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lDichoSearchType
// Low level function to find an object with a given type in a given list
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lDichoSearchType(CPA_BaseObject** _p_oList, unsigned long _ulListSize, char* _TypeToFind,BOOL* _bFound,CPA_BaseObject* _p_oAdress)
{
unsigned long Haut=-1;
unsigned long Bas=_ulListSize;
unsigned long Milieu=(Haut+Bas)>>1;
long signe;
while (Bas!=Haut+1)
{
signe=stricmp((_p_oList[Milieu]->fn_p_szGetType()),_TypeToFind);
/* This is used to continue search on adress if wanted */
if (signe==0 && _p_oAdress!=NULL) signe=(long)(_p_oList[Milieu]-_p_oAdress);
if (signe<0)
{
Haut=Milieu;
Milieu=(Bas+Milieu)>>1;
}
else
if (signe>0)
{
Bas=Milieu;
Milieu=(Haut+Milieu)>>1;
}
else
{
*_bFound=TRUE;
return Milieu;
}
};
*_bFound=FALSE;
return Bas;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lDichoSearchData
// Low level function to find an object with a given data in a given list
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lDichoSearchData(CPA_BaseObject** _p_oList, unsigned long _ulListSize, void* _DataToFind,BOOL* _bFound,CPA_BaseObject* _p_oAdress)
{
unsigned long Haut=-1;
unsigned long Bas=_ulListSize;
unsigned long Milieu=(Haut+Bas)>>1;
long signe;
while (Bas!=Haut+1)
{
signe=(long)_p_oList[Milieu]->GetData()-(long)_DataToFind;
/* This is used to continue search on adress if wanted */
if (signe==0 && _p_oAdress!=NULL) signe=(long)(_p_oList[Milieu]-_p_oAdress);
if (signe<0)
{
Haut=Milieu;
Milieu=(Bas+Milieu)>>1;
}
else
if (signe>0)
{
Bas=Milieu;
Milieu=(Haut+Milieu)>>1;
}
else
{
*_bFound=TRUE;
return Milieu;
}
};
*_bFound=FALSE;
return Bas;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lDichoSearchOwner
// Low level function to find an object with a given owner in a given list
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lDichoSearchOwner(CPA_BaseObject** _p_oList, unsigned long _ulListSize, CPA_BaseObject* _OwnerToFind,BOOL* _bFound,CPA_BaseObject* _p_oAdress)
{
unsigned long Haut=-1;
unsigned long Bas=_ulListSize;
unsigned long Milieu=(Haut+Bas)>>1;
long signe;
while (Bas!=Haut+1)
{
signe=(long)(_p_oList[Milieu]->GetOwner()-_OwnerToFind);
/* This is used to continue search on adress if wanted */
if (signe==0 && _p_oAdress!=NULL) signe=(long)(_p_oList[Milieu]-_p_oAdress);
if (signe<0)
{
Haut=Milieu;
Milieu=(Bas+Milieu)>>1;
}
else
if (signe>0)
{
Bas=Milieu;
Milieu=(Haut+Milieu)>>1;
}
else
{
*_bFound=TRUE;
return Milieu;
}
};
*_bFound=FALSE;
return Bas;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lDichoSearchBaseObject
// Low level function to find the index of an object in a given list
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lDichoSearchBaseObject(CPA_BaseObject** _List, unsigned long _ListSize, CPA_BaseObject* _BaseObjectToFind,BOOL* _bFound)
{
unsigned long Haut=-1;
unsigned long Bas=_ListSize;
unsigned long Milieu=(Haut+Bas)>>1;
long signe;
while (Bas!=Haut+1)
{
signe=(long)(_List[Milieu]-_BaseObjectToFind);
if (signe<0)
{
Haut=Milieu;
Milieu=(Bas+Milieu)>>1;
}
else
if (signe>0)
{
Bas=Milieu;
Milieu=(Haut+Milieu)>>1;
}
else
{
*_bFound=TRUE;
return Milieu;
}
}
*_bFound=FALSE;
return Bas;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lDichoSearchNamesTypesOwners
// Low level function to find objects which have a given name, an optional type and an optional owner
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lDichoSearchNamesTypesOwners(
CPA_List<CPA_BaseObject> *_p_oReturnList,
CPA_BaseObject** _p_oList,
unsigned long _ulListSize,
BOOL* _p_bFound,
char* _Name,
char* _type,
CPA_BaseObject* _Owner)
{
int Count=0;
BOOL CountOnly;
int index,i;
/* Avoid crashes, please do not replace with ASSERT... */
if (_p_bFound==NULL || !stricmp(_Name,"") || _p_oList== NULL || ((long)_ulListSize)<=0)
{
if (_p_bFound!=NULL) *_p_bFound=FALSE;
return 0;
}
if (_p_oReturnList==NULL)
CountOnly=TRUE;
else
CountOnly=FALSE;
/* we search the name in the sorted list */
index=fn_lDichoSearchName(_p_oList,_ulListSize,_Name,_p_bFound);
if (*_p_bFound)
{
i=index;
/* we search the same names before */
while (i>=0 && !stricmp(_p_oList[i]->fn_p_szGetName(),_Name))
{
/* also test Type if _Type!=NULL*/
if (!stricmp(_type,"") || !stricmp(_p_oList[i]->fn_p_szGetType(),_type))
{
/* also test Owner if _Owner!=NO_CRITERIA*/
if (_Owner==NO_CRITERIA || (_p_oList[i]->GetOwner()==_Owner))
{
if (CountOnly==FALSE) _p_oReturnList->AddTail(_p_oList[i]);
Count++;
}
}
i--;
}
i=index+1;
/* we search the same names after */
while ((i<(long)_ulListSize) && !stricmp(_p_oList[i]->fn_p_szGetName(),_Name) )
{
/* also test Type if _Type!=NULL*/
if (!stricmp(_type,"") || !stricmp(_p_oList[i]->fn_p_szGetType(),_type))
{
/* also test Owner if _Type!=NULL*/
if (_Owner==NO_CRITERIA || (_p_oList[i]->GetOwner()==_Owner))
{
if (CountOnly==FALSE) _p_oReturnList->AddTail(_p_oList[i]);
Count++;
}
}
i++;
}
}
if (Count==0) *_p_bFound=FALSE;
return Count;
};
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lDichoSearchNameTypeOwner
// Low level function to find an object which has a given name, an optional type and an optional owner
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lDichoSearchNameTypeOwner(
CPA_BaseObject** _p_oList,
unsigned long _ulListSize,
BOOL* _p_bFound,
char* _NameToFind,
char* _type,
CPA_BaseObject* _Owner
)
{
unsigned long Haut=-1;
unsigned long Bas=_ulListSize;
unsigned long Milieu=(Haut+Bas)>>1;
long signe;
long i;
/* Avoid crashes, please do not replace with ASSERT... */
if (_p_bFound==NULL || _p_oList== NULL || ((long)_ulListSize)<=0)
{
if (_p_bFound!=NULL) *_p_bFound=FALSE;
return 0;
}
while (Bas!=Haut+1)
{
signe=stricmp((_p_oList[Milieu]->fn_p_szGetName()),_NameToFind);
if (signe<0)
{
Haut=Milieu;
Milieu=(Bas+Milieu)>>1;
}
else
if (signe>0)
{
Bas=Milieu;
Milieu=(Haut+Milieu)>>1;
}
else
{
/* the name was found !*/
/* search for type and owner if necessary*/
i=Milieu;
while (i>=0 && !stricmp(_p_oList[i]->fn_p_szGetName(),_NameToFind))
{
/* also test Type if _Type!=NULL*/
if (!stricmp(_type,"") || !stricmp(_p_oList[i]->fn_p_szGetType(),_type))
{
/* also test Owner if _Owner!=NO_CRITERIA*/
if (_Owner==NO_CRITERIA || (_p_oList[i]->GetOwner()==_Owner))
{
*_p_bFound=TRUE;
return i;
}
}
i--;
}
i=Milieu+1;
/* we search the same names after */
while ((i<(long)_ulListSize) && !stricmp(_p_oList[i]->fn_p_szGetName(),_NameToFind))
{
/* also test Type if _Type!=NULL*/
if (!stricmp(_type,"") || !stricmp(_p_oList[i]->fn_p_szGetType(),_type))
{
/* also test Owner if _Type!=NULL*/
if (_Owner==NO_CRITERIA || (_p_oList[i]->GetOwner()==_Owner))
{
*_p_bFound=TRUE;
return i;
}
}
i++;
}
*_p_bFound=FALSE;
return Bas;
}
};
*_p_bFound=FALSE;
return Bas;
};
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lDichoSearchDataTypeOwner
// Low level function to find an object which has a given data, an optional type and an optional owner
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lDichoSearchDataTypeOwner(
CPA_BaseObject** _p_oList,
unsigned long _ulListSize,
BOOL* _p_bFound,
void* _data,
char* _type,
CPA_BaseObject* _Owner
)
{
unsigned long Haut=-1;
unsigned long Bas=_ulListSize;
unsigned long Milieu=(Haut+Bas)>>1;
long signe;
int i;
/* Avoid crashes, please do not replace with ASSERT... */
if (_p_bFound==NULL || _p_oList== NULL || ((long)_ulListSize)<=0)
{
if (_p_bFound!=NULL) *_p_bFound=FALSE;
return 0;
}
while (Bas!=Haut+1)
{
signe=(long)_p_oList[Milieu]->GetData()-(long)_data;
if (signe<0)
{
Haut=Milieu;
Milieu=(Bas+Milieu)>>1;
}
else
if (signe>0)
{
Bas=Milieu;
Milieu=(Haut+Milieu)>>1;
}
else
{
/* the data was found !*/
/* search for type and owner if necessary*/
i=Milieu;
while (i>=0 && _p_oList[i]->GetData()==_data)
{
/* also test Type if _Type!=NULL*/
if (!stricmp(_type,"") || !stricmp(_p_oList[i]->fn_p_szGetType(),_type))
{
/* also test Owner if _Owner!=NO_CRITERIA*/
if (_Owner==NO_CRITERIA || (_p_oList[i]->GetOwner()==_Owner))
{
*_p_bFound=TRUE;
return i;
}
}
i--;
}
i=Milieu+1;
/* we search the same datas after */
while ((i<(long)_ulListSize) && _p_oList[i]->GetData()==_data )
{
/* also test Type if _Type!=NULL*/
if (!stricmp(_type,"") || !stricmp(_p_oList[i]->fn_p_szGetType(),_type))
{
/* also test Owner if _Type!=NULL*/
if (_Owner==NO_CRITERIA || (_p_oList[i]->GetOwner()==_Owner))
{
*_p_bFound=TRUE;
return i;
}
}
i++;
}
*_p_bFound=FALSE;
return Bas;
}
};
*_p_bFound=FALSE;
return Bas;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lDichoSearchOwnersAndTypes
// Low level function to find objects which have a given owner and a given type
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lDichoSearchOwnersAndTypes(CPA_List<CPA_BaseObject> * _p_oReturnList, CPA_BaseObject** _p_oList, unsigned long _ulListSize, BOOL* _p_bFound, CPA_BaseObject* _Owner,char* _type)
{
int Count=0;
BOOL CountOnly;
int index,i;
/* Avoid crashes, please do not replace with ASSERT... */
if (_p_bFound==NULL || _Owner==NULL || _p_oList== NULL || ((long)_ulListSize)<=0)
{
if (_p_bFound!=NULL) *_p_bFound=FALSE;
return 0;
}
if (_p_oReturnList==NULL)
CountOnly=TRUE;
else
CountOnly=FALSE;
/* we search the owner in the sorted list */
index=fn_lDichoSearchOwner(_p_oList,_ulListSize,_Owner,_p_bFound);
if (*_p_bFound)
{
i=index;
/* we search the same owners before */
while (i>=0 && _p_oList[i]->GetOwner()==_Owner )
{
if (!stricmp(_type,"") || !stricmp(_p_oList[i]->fn_p_szGetType(),_type))
{
if (CountOnly==FALSE) _p_oReturnList->AddTail(_p_oList[i]);
Count++;
}
i--;
}
i=index+1;
/* we search the same owners after */
while (i<(long)_ulListSize && _p_oList[i]->GetOwner()==_Owner)
{
if (!stricmp(_type,"") || !stricmp(_p_oList[i]->fn_p_szGetType(),_type))
{
if (CountOnly==FALSE) _p_oReturnList->AddTail(_p_oList[i]);
Count++;
}
i++;
}
}
if (Count==0) *_p_bFound=FALSE;
return Count;
}
//*****************************************************************************
//********** Medium level functions **********
//*****************************************************************************
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - FindObjectWithType
// Return all the objects of the list with the given type
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::FindObjectWithType (CPA_List<CPA_BaseObject> * _p_oList , const CString _csTypeName)
{
char * szTypeNameToFind = (char *) (LPCTSTR) _csTypeName;
if (! m_csTypeName . IsEmpty ()) // All objects of the list have the same type
{
if (m_csTypeName . CompareNoCase (_csTypeName) != 0) return 0; // Not the same type --> no object found
// We just make a copy of the list
for (long i = 0 ; i < m_lNumberOfObjects ; i ++)
_p_oList -> AddTail (m_Array [E_lo_Edited] [i]);
return m_lNumberOfObjects;
}
else // Not all objects have the same type : we must check the type
{
long lNumberOfObjectFound = 0;
tdp_BaseObjectPointer * pBaseObjectPointer = m_Array [E_lo_Edited];
for (long i = m_lNumberOfObjects ; i > 0 ; i --)
{
if (stricmp ((* pBaseObjectPointer) -> fn_p_szGetType () , szTypeNameToFind) == 0)
{
_p_oList -> AddTail (* pBaseObjectPointer);
lNumberOfObjectFound ++;
}
pBaseObjectPointer ++;
}
return lNumberOfObjectFound;
}
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - FindIndex
// Return the index of an object into a list with a given order
// If the object is into the list, set _bExist to TRUE and return the index
// If not, set _bExist to FALSE and return the index where to insert the object
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::FindIndex (tdeListOrder _eListOrder , CPA_BaseObject * _p_oObject , BOOL * _bExist)
{
switch (_eListOrder)
{
case E_lo_Object : return fn_lDichoSearchBaseObject (m_Array [E_lo_Object] , m_lNumberOfObjects , _p_oObject , _bExist);
case E_lo_Type : return fn_lDichoSearchType (m_Array [E_lo_Type ] , m_lNumberOfObjects , _p_oObject -> fn_p_szGetType () , _bExist , _p_oObject);
case E_lo_Data : return fn_lDichoSearchData (m_Array [E_lo_Data ] , m_lNumberOfObjects , _p_oObject -> GetData () , _bExist , _p_oObject);
case E_lo_Owner : return fn_lDichoSearchOwner (m_Array [E_lo_Owner ] , m_lNumberOfObjects , _p_oObject -> GetOwner () , _bExist , _p_oObject);
case E_lo_Alpha : return fn_lDichoSearchName (m_Array [E_lo_Alpha ] , m_lNumberOfObjects , _p_oObject -> fn_p_szGetName () , _bExist , _p_oObject);
default : ASSERT (0);
* _bExist = FALSE;
return -1;
}
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - InsertObjectInList
// Insert the give object into the given list in the given position
// Shift the index after this position
// m_lNumberOfObjects has already been increased
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::InsertObjectInList (tdeListOrder _eListOrder , CPA_BaseObject * _p_oObject , long _lIndex)
{
// Shift the index after _lIndex
memmove (& m_Array [_eListOrder] [_lIndex + 1] , & m_Array [_eListOrder] [_lIndex] ,
(m_lNumberOfObjects - _lIndex - 1) * sizeof (tdp_BaseObjectPointer));
m_Array [_eListOrder] [_lIndex] = _p_oObject;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - RemoveObjectFromList
// Remove the given index from the given list
// Shift the index after this position
// m_lNumberOfObject has already been decreased
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::RemoveObjectFromList (tdeListOrder _eListOrder , long _lIndex)
{
// Shift the index after _lIndex
memmove (& m_Array [_eListOrder] [_lIndex] , & m_Array [_eListOrder] [_lIndex + 1] ,
(m_lNumberOfObjects - _lIndex) * sizeof (tdp_BaseObjectPointer));
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - MoveIndexInList
// Move an object from one position to another inside a given list
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::MoveIndexInList (tdeListOrder _eListOrder , long _lOldIndex , long _lNewIndex)
{
tdp_BaseObjectPointer pBaseObject = m_Array [_eListOrder] [_lOldIndex];
if (_lOldIndex < _lNewIndex)
{
memmove (& m_Array [_eListOrder] [_lOldIndex] , & m_Array [_eListOrder] [_lOldIndex + 1] ,
(_lNewIndex - _lOldIndex - 1) * sizeof (tdp_BaseObjectPointer));
m_Array [_eListOrder] [_lNewIndex - 1] = pBaseObject;
}
else
{
memmove (& m_Array [_eListOrder] [_lNewIndex + 1] , & m_Array [_eListOrder] [_lNewIndex] ,
(_lOldIndex - _lNewIndex) * sizeof (tdp_BaseObjectPointer));
m_Array [_eListOrder] [_lNewIndex] = pBaseObject;
}
}
//*****************************************************************************
//********** Type management **********
//*****************************************************************************
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_bIsOfType
// Return TRUE if the list is of the given type
//-----------------------------------------------------------------------------
BOOL CPA_BaseObjectList::fn_bIsOfType (const CString _csTypeName)
{
return m_csTypeName . CompareNoCase (_csTypeName) == 0;
}
//*****************************************************************************
//********** Add and remove objects **********
//*****************************************************************************
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_bAddObject
// Insert an object into the list.
// If the list has a type and the object has not the same type -> ASSERT
// If the object is already in the list, return FALSE
// Else insert the object into the list and return TRUE
//-----------------------------------------------------------------------------
BOOL CPA_BaseObjectList::fn_bAddObject (CPA_BaseObject * _p_oObject)
{
ASSERT (m_csTypeName . IsEmpty () || _p_oObject -> fn_bIsOfType (m_csTypeName));
long lIndex [C_lNumberOfLists];
for (int eListType = E_lo_First ; eListType <= E_lo_Last ; eListType ++)
{
BOOL bExist = FALSE;
// For the list with non specific order, we find the index where to insert the object
if (eListType == E_lo_Common) lIndex [eListType] = 0; // Beginning of the list
else
if (eListType == E_lo_Edited) lIndex [eListType] = m_lNumberOfObjects; // End of the list
else lIndex [eListType] = FindIndex ((tdeListOrder) eListType , _p_oObject , & bExist);
// If the object is already in the list, return FALSE
if (bExist) return FALSE;
}
// Increase the size of the array and check if the array is big enough
m_lNumberOfObjects ++;
if (m_lNumberOfObjects > m_lMaxNumberOfObjects)
ReallocArray ((m_lNumberOfObjects + C_lSizeIncrease - 1) / C_lSizeIncrease * C_lSizeIncrease);
for (eListType = E_lo_First ; eListType <= E_lo_Last ; eListType ++)
{
// Insert the object into the list
InsertObjectInList ((tdeListOrder) eListType , _p_oObject , lIndex [eListType]);
}
return TRUE; // The object has been inserted succesfully
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_bRemoveObject
// Remove an object from the list
// If the object is not into the list, return FALSE
// Else remove the object from the list and return TRUE
//-----------------------------------------------------------------------------
BOOL CPA_BaseObjectList::fn_bRemoveObject (CPA_BaseObject * _p_oObject)
{
long lIndex [C_lNumberOfLists];
for (int eListType = E_lo_First ; eListType <= E_lo_Last ; eListType ++)
{
BOOL bExist;
if (eListType == E_lo_Data || eListType == E_lo_Common || eListType == E_lo_Edited )
{ // For specific order (E_lo_Common and E_lo_Edited), dicho search does not exist
// For data order, we cannot use dicho search because this function can be called by destructor of CPA_BaseObject,
// and in this case, the GetData pure virtual function is no longer available
lIndex [eListType] = GetIndexOfObject (_p_oObject , (tdeListOrder) eListType);
bExist = lIndex [eListType] != -1;
}
else lIndex [eListType] = FindIndex ((tdeListOrder) eListType , _p_oObject , & bExist);
// If the object is not in the list, return FALSE
if (! bExist) return FALSE;
}
// Decrease the size of the array
m_lNumberOfObjects --;
for (eListType = E_lo_First ; eListType <= E_lo_Last ; eListType ++)
{
// Remove the object from the list
RemoveObjectFromList ((tdeListOrder) eListType , lIndex [eListType]);
}
// Check if one can decrease the maximum size of the array
if (m_lNumberOfObjects <= m_lMaxNumberOfObjects - C_lSizeIncrease)
ReallocArray ((m_lNumberOfObjects + C_lSizeIncrease - 1) / C_lSizeIncrease * C_lSizeIncrease);
return TRUE;
}
//*****************************************************************************
//********** Get functions **********
//*****************************************************************************
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - GetObjectWithIndex
// Return the object with the given index into the given sort order
//-----------------------------------------------------------------------------
CPA_BaseObject * CPA_BaseObjectList::GetObjectWithIndex (long _lIndex , tdeListOrder _eListOrder)
{
return m_Array [_eListOrder] [_lIndex];
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - GetIndexOfObject
// Return the index (between 0 et GetCount () - 1) of a given object
// for a specific order (must be E_lo_Common or E_lo_Edited) or for E_lo_Data
// If the object is not into the list, return -1
// Do not use this function too much, because it is slower than the others
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::GetIndexOfObject (CPA_BaseObject * _p_oObject , tdeListOrder _eListOrder)
{
ASSERT (_eListOrder == E_lo_Common || _eListOrder == E_lo_Edited || _eListOrder == E_lo_Data);
tdp_BaseObjectPointer * pBaseObjectPointer = m_Array [_eListOrder];
long i = m_lNumberOfObjects;
while (--i >= 0 && * (pBaseObjectPointer++) != _p_oObject) ;
if (i != -1) return m_lNumberOfObjects - i - 1;
else return -1;
}
//*****************************************************************************
//********** Search functions **********
//*****************************************************************************
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_bExist
// Return TRUE if the object is into the list
//-----------------------------------------------------------------------------
BOOL CPA_BaseObjectList::fn_bExist (CPA_BaseObject * _p_oObject)
{
BOOL bExist;
FindIndex (E_lo_Object , _p_oObject , & bExist);
return bExist;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_bExist
// Return TRUE if there is an object with the given name,
// eventually with the given type and the given owner into the list
//-----------------------------------------------------------------------------
BOOL CPA_BaseObjectList::fn_bExist (const CString _csObjectName ,
const CString _csTypeName /* = "" */ ,
CPA_BaseObject * _p_oOwner /* = NO_CRITERIA */)
{
return fn_p_oFindObject (_csObjectName , _csTypeName , _p_oOwner) != NULL;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_lFindObjects
// Find object from the list, put them into _p_oList
// and return the number of found objects
//-----------------------------------------------------------------------------
long CPA_BaseObjectList::fn_lFindObjects (CPA_List<CPA_BaseObject> * _p_oList ,
const CString _csObjectName ,
const CString _csTypeName /* = "" */ ,
CPA_BaseObject * _p_oOwner /* = NO_CRITERIA */)
{
if (_csObjectName . IsEmpty ()) // No name to search
{
if (_p_oOwner == NO_CRITERIA) return FindObjectWithType (_p_oList , _csTypeName); // Search with the type only
BOOL bExist;
return fn_lDichoSearchOwnersAndTypes (_p_oList , m_Array [E_lo_Owner] , m_lNumberOfObjects , & bExist , _p_oOwner ,
(char *) (LPCTSTR) _csTypeName);
}
else
{
BOOL bExist;
return fn_lDichoSearchNamesTypesOwners (_p_oList , m_Array [E_lo_Alpha] , m_lNumberOfObjects , & bExist ,
(char *) (LPCTSTR) _csObjectName , (char *) (LPCTSTR) _csTypeName , _p_oOwner);
}
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_p_oFindObject
// Find an object from the list with the given name,
// eventually the given type and the given owner
// If the object is into the list, return it else return NULL
//-----------------------------------------------------------------------------
CPA_BaseObject * CPA_BaseObjectList::fn_p_oFindObject (const CString _csObjectName ,
const CString _csTypeName /* = "" */ ,
CPA_BaseObject * _p_oOwner /* = NO_CRITERIA */)
{
ASSERT (_csObjectName && ! _csObjectName . IsEmpty ());
BOOL bExist;
long lIndex = fn_lDichoSearchNameTypeOwner (m_Array [E_lo_Alpha] , m_lNumberOfObjects , & bExist ,
(char *) (LPCTSTR) _csObjectName ,
(char *) (LPCTSTR) _csTypeName , _p_oOwner);
if (bExist) return m_Array [E_lo_Alpha] [lIndex];
else return NULL;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_p_oFindObject
// Find an object from the list with the given data,
// eventually the given type and the given owner
// If the object is into the list, return it else return NULL
//-----------------------------------------------------------------------------
CPA_BaseObject * CPA_BaseObjectList::fn_p_oFindObjectWithdData (void * _p_vData ,
const CString _csTypeName /* = "" */ ,
CPA_BaseObject * _p_oOwner /* = NO_CRITERIA */)
{
BOOL bExist;
long lIndex = fn_lDichoSearchDataTypeOwner (m_Array [E_lo_Data] , m_lNumberOfObjects , & bExist , _p_vData ,
(char *) (LPCTSTR) _csTypeName , _p_oOwner);
if (bExist) return m_Array [E_lo_Data] [lIndex];
else return NULL;
}
//*****************************************************************************
//********** Change order **********
//*****************************************************************************
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_vBeforeChangingObjectName
// Before changing the name of a CPA_BaseObject, one must
// call this function to reorganize the alphabetic order sorted list
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::fn_vBeforeChangingObjectName (CPA_BaseObject * _p_oObject , char * _szNewName)
{
// If old name and new name are equal, we do nothing
if (stricmp (_p_oObject -> fn_p_szGetName () , _szNewName) == 0) return;
BOOL bExist;
long lOldIndex = fn_lDichoSearchName (m_Array [E_lo_Alpha] , m_lNumberOfObjects , _p_oObject -> fn_p_szGetName () , & bExist , _p_oObject);
ASSERT (bExist); // The object must exist
long lNewIndex = fn_lDichoSearchName (m_Array [E_lo_Alpha] , m_lNumberOfObjects , _szNewName , & bExist , _p_oObject);
MoveIndexInList (E_lo_Alpha , lOldIndex , lNewIndex);
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_vBeforeChangingObjectData
// Before changing the data of a CPA_BaseObject, one must
// call this function to reorganize the list
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::fn_vBeforeChangingObjectData (CPA_BaseObject * _p_oObject , void * _pNewData)
{
// If old data and new data are equal, we do nothing
if (_p_oObject -> GetData () == _pNewData) return;
BOOL bExist;
long lOldIndex = fn_lDichoSearchData (m_Array [E_lo_Data] , m_lNumberOfObjects , _p_oObject -> GetData () , & bExist , _p_oObject);
ASSERT (bExist); // The object must exist
long lNewIndex = fn_lDichoSearchData (m_Array [E_lo_Data] , m_lNumberOfObjects , _pNewData , & bExist , _p_oObject);
MoveIndexInList (E_lo_Data , lOldIndex , lNewIndex);
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_vBeforeChangingObjectOwner
// Before changing the owner of a CPA_BaseObject, one must
// call this function to reorganize the list
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::fn_vBeforeChangingObjectOwner (CPA_BaseObject * _p_oObject , CPA_BaseObject * _pNewOwner)
{
// If old owner and new owner are equal, we do nothing
if (_p_oObject -> GetOwner () == _pNewOwner) return;
BOOL bExist;
long lOldIndex = fn_lDichoSearchOwner (m_Array [E_lo_Owner] , m_lNumberOfObjects , _p_oObject -> GetOwner () , & bExist , _p_oObject);
ASSERT (bExist); // The object must exist
long lNewIndex = fn_lDichoSearchOwner (m_Array [E_lo_Owner] , m_lNumberOfObjects , _pNewOwner , & bExist , _p_oObject);
MoveIndexInList (E_lo_Owner , lOldIndex , lNewIndex);
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_vExchangeObjectOrder
// Exchange two objects in a specific order (must be E_lo_Common or E_lo_Edited)
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::fn_vExchangeObjectOrder (long _lIndex1 , long _lIndex2 , tdeListOrder _eListOrder)
{
ASSERT (_eListOrder == E_lo_Common || _eListOrder == E_lo_Edited);
// Exchange the two pointers
tdp_BaseObjectPointer pPointer = m_Array [_eListOrder] [_lIndex1];
m_Array [_eListOrder] [_lIndex1] = m_Array [_eListOrder] [_lIndex2];
m_Array [_eListOrder] [_lIndex2] = pPointer;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_vChangeObjectOrder
// Change the position in a specific order sorted list of
// an object (which must already be in the list)
// Shift objects if necessary (must be E_lo_Common or E_lo_Edited)
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::fn_vChangeObjectOrder (long _lOldIndex , long _lNewIndex , tdeListOrder _eListOrder)
{
ASSERT (_eListOrder == E_lo_Common || _eListOrder == E_lo_Edited);
MoveIndexInList (_eListOrder , _lOldIndex , _lNewIndex);
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_bExchangeObjectOrder
// Exchange two objects in a specific order (must be E_lo_Common or E_lo_Edited)
// If you know the index of the two objects in the list (without calling the GetIndexOfObject function),
// call the fn_vExchangeObjectOrder function which is faster
// Return FALSE if one object is not in the list, else return TRUE
//-----------------------------------------------------------------------------
BOOL CPA_BaseObjectList::fn_bExchangeObjectOrder (CPA_BaseObject * _p_oObject1 , CPA_BaseObject * _p_oObject2 ,
tdeListOrder _eListOrder)
{
long lIndex1 = GetIndexOfObject (_p_oObject1 , _eListOrder);
long lIndex2 = GetIndexOfObject (_p_oObject2 , _eListOrder);
if (lIndex1 == -1 || lIndex2 == -1) return FALSE;
fn_vExchangeObjectOrder (lIndex1 , lIndex2 , _eListOrder);
return TRUE;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_bChangeObjectOrder
// Change the position in a specific order sorted list of an object.
// Shift objects if necessary (must be E_lo_Common or E_lo_Edited).
// If you know the old index if the object in the list (without calling the GetIndexOfObject function),
// call the fn_vChangeObjectOrder function which is faster
// Return FALSE if the object is not in the list, else return TRUE
//-----------------------------------------------------------------------------
BOOL CPA_BaseObjectList::fn_bChangeObjectOrder (CPA_BaseObject* _p_oObject , long _lNewIndex , tdeListOrder _eListOrder)
{
long lOldIndex = GetIndexOfObject (_p_oObject , _eListOrder);
if (lOldIndex == -1) return FALSE;
fn_vChangeObjectOrder (lOldIndex , _lNewIndex , _eListOrder);
return TRUE;
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_vReSortListWithAlphaOrder
// If some objects may have been renamed without calling the
// fn_vBeforeChangingObjectName function, call this function to sort the list
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::fn_vReSortListWithAlphaOrder ()
{
// We check if the list is sorted or not
BOOL bListSorted = TRUE;
tdp_BaseObjectPointer * pBaseObjectPointer = m_Array [E_lo_Alpha];
for (long i = 0 ; i < m_lNumberOfObjects - 1 ; i ++)
{
if (stricmp ((* pBaseObjectPointer) -> fn_p_szGetName () , (* (pBaseObjectPointer+1)) -> fn_p_szGetName ()) > 0)
{
bListSorted = FALSE;
break;
}
pBaseObjectPointer ++;
}
// If the list is already sorted, we do nothing
if (bListSorted) return;
// Else we resort the list
for (i = 1 ; i < m_lNumberOfObjects ; i ++)
{
// We take the object number i
CPA_BaseObject * pBaseObject = m_Array [E_lo_Alpha] [i];
BOOL bExist;
// We find the correct index
long lNewIndex = fn_lDichoSearchName (m_Array [E_lo_Alpha] , i , pBaseObject -> fn_p_szGetName () , & bExist , pBaseObject);
if (lNewIndex != i)
{
memmove (& m_Array [E_lo_Alpha] [lNewIndex + 1] , & m_Array [E_lo_Alpha] [lNewIndex] , (i - lNewIndex) * sizeof (tdp_BaseObjectPointer));
m_Array [E_lo_Alpha] [lNewIndex] = pBaseObject;
}
}
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_vReSortListWithDataOrder
// If data of some objects may have been changed without calling the
// fn_vBeforeChangingObjectData function, call this function to sort the list
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::fn_vReSortListWithDataOrder ()
{
// We check if the list is sorted or not
BOOL bListSorted = TRUE;
tdp_BaseObjectPointer * pBaseObjectPointer = m_Array [E_lo_Data];
for (long i = 0 ; i < m_lNumberOfObjects - 1 ; i ++)
{
if ((* pBaseObjectPointer) -> GetData () > (* (pBaseObjectPointer+1)) -> GetData ())
{
bListSorted = FALSE;
break;
}
pBaseObjectPointer ++;
}
// If the list is already sorted, we do nothing
if (bListSorted) return;
// Else we resort the list
for (i = 1 ; i < m_lNumberOfObjects ; i ++)
{
// We take the object number i
CPA_BaseObject * pBaseObject = m_Array [E_lo_Data] [i];
BOOL bExist;
// We find the correct index
long lNewIndex = fn_lDichoSearchData (m_Array [E_lo_Data] , i , pBaseObject -> GetData () , & bExist , pBaseObject);
if (lNewIndex != i)
{
memmove (& m_Array [E_lo_Data] [lNewIndex + 1] , & m_Array [E_lo_Data] [lNewIndex] , (i - lNewIndex) * sizeof (tdp_BaseObjectPointer));
m_Array [E_lo_Data] [lNewIndex] = pBaseObject;
}
}
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_vReSortListWithOwnerOrder
// If owner of some objects may have been changed without calling the
// fn_vBeforeChangingObjectOwner function, call this function to sort the list
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::fn_vReSortListWithOwnerOrder ()
{
// We check if the list is sorted or not
BOOL bListSorted = TRUE;
tdp_BaseObjectPointer * pBaseObjectPointer = m_Array [E_lo_Owner];
for (long i = 0 ; i < m_lNumberOfObjects - 1 ; i ++)
{
if ((* pBaseObjectPointer) -> GetOwner () > (* (pBaseObjectPointer+1)) -> GetOwner ())
{
bListSorted = FALSE;
break;
}
pBaseObjectPointer ++;
}
// If the list is already sorted, we do nothing
if (bListSorted) return;
// Else we resort the list
for (i = 1 ; i < m_lNumberOfObjects ; i ++)
{
// We take the object number i
CPA_BaseObject * pBaseObject = m_Array [E_lo_Owner] [i];
BOOL bExist;
// We find the correct index
long lNewIndex = fn_lDichoSearchOwner (m_Array [E_lo_Owner] , i , pBaseObject -> GetOwner () , & bExist , pBaseObject);
if (lNewIndex != i)
{
memmove (& m_Array [E_lo_Owner] [lNewIndex + 1] , & m_Array [E_lo_Owner] [lNewIndex] , (i - lNewIndex) * sizeof (tdp_BaseObjectPointer));
m_Array [E_lo_Owner] [lNewIndex] = pBaseObject;
}
}
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - fn_vReSortList
// Call the three previous functions
//-----------------------------------------------------------------------------
void CPA_BaseObjectList::fn_vReSortList ()
{
fn_vReSortListWithAlphaOrder ();
fn_vReSortListWithDataOrder ();
fn_vReSortListWithOwnerOrder ();
}
//*****************************************************************************
//********** To go through the list **********
//*****************************************************************************
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - GetHeadElement
// Same as CPA_List::GetHeadElement
//-----------------------------------------------------------------------------
CPA_BaseObject * CPA_BaseObjectList::GetHeadElement (Position & _Position)
{
if (m_lNumberOfObjects > 0)
{
_Position = 1;
return m_Array [E_lo_GoThrough] [0];
}
else
{
_Position = 0;
return NULL;
}
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - GetTailElement
// Same as CPA_List::GetTailElement
//-----------------------------------------------------------------------------
CPA_BaseObject * CPA_BaseObjectList::GetTailElement (Position & _Position)
{
if (m_lNumberOfObjects > 0)
{
_Position = m_lNumberOfObjects;
return m_Array [E_lo_GoThrough] [m_lNumberOfObjects - 1];
}
else
{
_Position = 0;
return NULL;
}
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - GetNextElement
// Same as CPA_List::GetNextElement
//-----------------------------------------------------------------------------
CPA_BaseObject * CPA_BaseObjectList::GetNextElement (Position & _Position)
{
if (!_Position) return NULL;
if (_Position >= m_lNumberOfObjects)
{
_Position = 0;
return NULL;
}
return m_Array [E_lo_GoThrough] [_Position++];
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - GetPrevElement
// Same as CList::GetNex
//-----------------------------------------------------------------------------
CPA_BaseObject * CPA_BaseObjectList::GetPrevElement (Position & _Position)
{
if (! _Position) return NULL;
return m_Array [E_lo_GoThrough] [-- _Position];
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - GetNext
// Same as CList::GetNext
//-----------------------------------------------------------------------------
CPA_BaseObject * CPA_BaseObjectList::GetNext (Position & _Position)
{
if (! _Position) return NULL;
Position ActualPosition = _Position;
if (_Position < m_lNumberOfObjects) _Position ++;
else _Position = 0;
return m_Array [E_lo_GoThrough] [ActualPosition - 1];
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - GetPrev
// Same as CList::GetPrev
//-----------------------------------------------------------------------------
CPA_BaseObject * CPA_BaseObjectList::GetPrev (Position & _Position)
{
if (! _Position) return NULL;
return m_Array [E_lo_GoThrough] [-- _Position];
}
//-----------------------------------------------------------------------------
// Class CPA_BaseObjectList - New Name
// Type + number
//-----------------------------------------------------------------------------
CString CPA_BaseObjectList::GetNewName (const CString csDefaultBaseName /*=""*/)
{
CString csName;
if( csDefaultBaseName == "")
{
ASSERT(m_csTypeName != "");
csName.Format("%s%d",m_csTypeName,++m_lCurrentUniqueIndex);
}
else
{
csName.Format("%s%d",csDefaultBaseName,++m_lCurrentUniqueIndex);
}
return csName;
}
#undef stricmp
#endif // ACTIVE_EDITOR