161 lines
3.1 KiB
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;
|
|
}
|
|
|