#include #include #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->iTypeiType) 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->iPriorityiPriority) 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; ipVal[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; }