reman3/Rayman_X/cpa/tempgrp/ldt/Src/refs.c

161 lines
3.1 KiB
C

#include <stdinc.h>
#include <stdarg.h>
#include "LDT.h"
#include "refs.h"
#include "DynArray.h"
#include "Error.h"
extern LDT_tdst_Link *g_pGetFrom;
extern int g_nInitialized;
LDT_tdst_DSArray g_ArSolvers;
int SortRefs( const void **A, const void **B )
{
tdst_Ref *pA, *pB;
pA=(tdst_Ref *)*A;
pB=(tdst_Ref *)*B;
if( pA->iType<pB->iType)
return 1;
else if( pA->iType>pB->iType)
return -1;
return 0;
}
int SortSolvers( const void **A, const void **B )
{
tdst_Solver *pA, *pB;
pA=(tdst_Solver *)*A;
pB=(tdst_Solver *)*B;
if( pA->iPriority<pB->iPriority)
return -1;
else if( pA->iPriority>pB->iPriority)
return 1;
return 0;
}
HREF LDT_CreateRefsTable( )
{
LDT_tdst_DSArray* pRef=LDT_DSAr_new();
LDT_DSAr_SetGranularity( pRef, 50 );
LDT_DSAr_SetSortMethod( pRef, SortRefs );
return (HREF)pRef;
}
void LDT_AddToRefsTable( HREF hRef, LDT_tdst_Link* pObj, int iType, short xCount, ... )
{
LDT_tdst_DSArray* pRef=(LDT_tdst_DSArray *)hRef;
tdst_Ref *pSt=(tdst_Ref *)malloc( sizeof(tdst_Ref) );
pSt->pObject=pObj;
pSt->pGetFrom=g_pGetFrom;
pSt->iType=iType;
pSt->xCount=xCount;
if( xCount )
{
int i;
va_list vaList;
pSt->pVal=(long *)malloc( xCount*sizeof( long ) );
va_start( vaList, xCount );
for( i=0; i<xCount; i++ )
pSt->pVal[i]=va_arg( vaList, long );
va_end( vaList );
}
else pSt->pVal=NULL;
pObj->wUnsolvedRefs++;
LDT_DSAr_SAdd( pRef, (void *)pSt, 1, NULL );
}
long pValues[128];
int LDT_GetRefFromTable( HREF hRef, LDT_tdst_Link **pObj, LDT_tdst_Link **pGetFrom, int *iType, short *xCount, long **pVal )
{
LDT_tdst_DSArray* pRef=(LDT_tdst_DSArray *)hRef;
int i=LDT_DSAr_GetUpperBound( pRef ), ii;
tdst_Ref *pSt;
if( i==-1 )
return -1;
for( ii=i; (ii>=0) && (pSt=(tdst_Ref *)LDT_DSAr_GetAt( pRef, ii ))->pGetFrom && pSt->pGetFrom->wUnsolvedRefs; ii--);
if( ii<0 ) /* circular refs - problem ! */
return -2;
if( ii!=i ) /* swap */
{
void *pTemp=LDT_DSAr_GetAt( pRef, i );
LDT_DSAr_SetAt( pRef, ii, pTemp );
}
LDT_DSAr_SetSize( pRef, i );
*pObj=pSt->pObject;
if( pSt->pGetFrom )
*pGetFrom=pSt->pGetFrom;
else *pGetFrom=NULL;
*iType=pSt->iType;
*xCount=pSt->xCount;
if(pSt->xCount)
{
memcpy(pValues, pSt->pVal, pSt->xCount*sizeof(long));
*pVal=pValues;
free(pSt->pVal);
}
else
*pVal = NULL;
pSt->pObject->wUnsolvedRefs--;
free( pSt );
return 0;
}
#pragma warning( disable:4100 )
void LDT_FreeRefValues( long *p )
{
// free( p ); the function is here only for backwards compatibility
}
#pragma warning( default:4100 )
HREF LDT_RegisterSolver( void(* Solve)(HREF), int iPri )
{
tdst_Solver *pSolver;
if(!g_nInitialized )
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, NULL, 0, "Call LDT_Initialize prior to solver registration !");
#endif
return NULL;
}
pSolver=(tdst_Solver *)malloc( sizeof(tdst_Solver) );
pSolver->Solve=Solve;
pSolver->iPriority=iPri;
if( LDT_DSAr_SAdd( &g_ArSolvers, (void *)pSolver, 0, NULL ) <0 )
{
#if defined(LDT_ERROR_TREATMENT)
ERRoR(0, NULL, 0, "Solver registration failed. The priority slot is in use. Please choose a different priority number.");
#endif
free (pSolver);
return NULL;
}
pSolver->hRef=LDT_CreateRefsTable();
return pSolver->hRef;
}