/** Finds a clock function storage * @param[in] _pstClock Concerned clock * @param[in] _pfnCallback Concerned callback * @return orxCLOCK_FUNCTION_STORAGE / orxNULL */ static orxINLINE orxCLOCK_FUNCTION_STORAGE *orxClock_FindFunctionStorage(const orxCLOCK *_pstClock, const orxCLOCK_FUNCTION _pfnCallback) { orxCLOCK_FUNCTION_STORAGE *pstFunctionStorage; /* Checks */ orxASSERT(sstClock.u32Flags & orxCLOCK_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstClock); orxASSERT(_pfnCallback != orxNULL); /* Finds matching function storage */ for(pstFunctionStorage = (orxCLOCK_FUNCTION_STORAGE *)orxLinkList_GetFirst(&(_pstClock->stFunctionList)); pstFunctionStorage != orxNULL; pstFunctionStorage = (orxCLOCK_FUNCTION_STORAGE *)orxLinkList_GetNext(&(pstFunctionStorage->stNode))) { /* Match? */ if(pstFunctionStorage->pfnCallback == _pfnCallback) { /* Found */ break; } } /* Done! */ return pstFunctionStorage; }
/** Removes a timer function from a clock * @param[in] _pstClock Concerned clock * @param[in] _pfnCallback Concerned timer callback to remove * @param[in] _fDelay Delay between 2 calls of the timer to remove, -1.0f for removing all occurrences regardless of their respective delay * @param[in] _pContext Context of the timer to remove, orxNULL for removing all occurrences regardless of their context * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxClock_RemoveTimer(orxCLOCK *_pstClock, const orxCLOCK_FUNCTION _pfnCallback, orxFLOAT _fDelay, void *_pContext) { orxCLOCK_TIMER_STORAGE *pstTimerStorage; orxSTATUS eResult = orxSTATUS_SUCCESS; /* Checks */ orxASSERT(sstClock.u32Flags & orxCLOCK_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstClock); orxASSERT(_pfnCallback != orxNULL); /* For all stored timers */ for(pstTimerStorage = (orxCLOCK_TIMER_STORAGE *)orxLinkList_GetFirst(&(_pstClock->stTimerList)); pstTimerStorage != orxNULL; pstTimerStorage = (orxCLOCK_TIMER_STORAGE *)orxLinkList_GetNext(&(pstTimerStorage->stNode))) { /* Matches criteria? */ if((pstTimerStorage->pfnCallback == _pfnCallback) && ((_fDelay < orxFLOAT_0) || (pstTimerStorage->fDelay == _fDelay)) && ((_pContext == orxNULL) || (pstTimerStorage->pContext == _pContext))) { /* Marks it for deletion */ pstTimerStorage->s32Repetition = 0; } } /* Done! */ return eResult; }
/** Sends an event * @param[in] _pstEvent Event to send */ orxSTATUS orxFASTCALL orxEvent_Send(orxEVENT *_pstEvent) { orxEVENT_HANDLER_STORAGE *pstStorage; orxSTATUS eResult = orxSTATUS_SUCCESS; /* Checks */ orxASSERT(orxFLAG_TEST(sstEvent.u32Flags, orxEVENT_KU32_STATIC_FLAG_READY)); orxASSERT(_pstEvent != orxNULL); /* Gets corresponding storage */ pstStorage = (_pstEvent->eType < orxEVENT_TYPE_CORE_NUMBER) ? sstEvent.astCoreHandlerStorageList[_pstEvent->eType] : (orxEVENT_HANDLER_STORAGE *)orxHashTable_Get(sstEvent.pstHandlerStorageTable, _pstEvent->eType); /* Valid? */ if(pstStorage != orxNULL) { orxEVENT_HANDLER_INFO *pstInfo; /* Main thread? */ if(orxThread_GetCurrent() == orxTHREAD_KU32_MAIN_THREAD_ID) { /* Updates event send counter */ sstEvent.s32EventSendCounter++; } /* For all handlers */ for(pstInfo = (orxEVENT_HANDLER_INFO *)orxLinkList_GetFirst(&(pstStorage->stList)); pstInfo != orxNULL; pstInfo = (orxEVENT_HANDLER_INFO *)orxLinkList_GetNext(&(pstInfo->stNode))) { /* Stores context */ _pstEvent->pContext = pstInfo->pContext; /* Calls it */ if((pstInfo->pfnHandler)(_pstEvent) == orxSTATUS_FAILURE) { /* Updates result */ eResult = orxSTATUS_FAILURE; break; } } /* Clears context */ _pstEvent->pContext = orxNULL; /* Main thread? */ if(orxThread_GetCurrent() == orxTHREAD_KU32_MAIN_THREAD_ID) { /* Updates event send counter */ sstEvent.s32EventSendCounter--; } } /* Done! */ return eResult; }
/** Removes an event handler which matches given context * @param[in] _eEventType Concerned type of event * @param[in] _pfnEventHandler Event handler to remove * @param[in] _pContext Context of the handler to remove, orxNULL for removing all occurrences regardless of their context * return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxEvent_RemoveHandlerWithContext(orxEVENT_TYPE _eEventType, orxEVENT_HANDLER _pfnEventHandler, void *_pContext) { orxEVENT_HANDLER_STORAGE *pstStorage; orxSTATUS eResult = orxSTATUS_FAILURE; /* Checks */ orxASSERT(orxFLAG_TEST(sstEvent.u32Flags, orxEVENT_KU32_STATIC_FLAG_READY)); orxASSERT(_pfnEventHandler != orxNULL); /* Gets corresponding storage */ pstStorage = (_eEventType < orxEVENT_TYPE_CORE_NUMBER) ? sstEvent.astCoreHandlerStorageList[_eEventType] : (orxEVENT_HANDLER_STORAGE *)orxHashTable_Get(sstEvent.pstHandlerStorageTable, _eEventType); /* Valid? */ if(pstStorage != orxNULL) { orxEVENT_HANDLER_INFO *pstInfo; /* For all handlers */ for(pstInfo = (orxEVENT_HANDLER_INFO *)orxLinkList_GetFirst(&(pstStorage->stList)); pstInfo != orxNULL; pstInfo = (orxEVENT_HANDLER_INFO *)orxLinkList_GetNext(&(pstInfo->stNode))) { /* Found? */ if((pstInfo->pfnHandler == _pfnEventHandler) && ((_pContext == orxNULL) || (_pContext == _pfnEventHandler) || (_pContext == pstInfo->pContext))) { /* Removes it from list */ orxLinkList_Remove(&(pstInfo->stNode)); /* Frees it */ orxBank_Free(pstStorage->pstBank, pstInfo); /* Updates result */ eResult = orxSTATUS_SUCCESS; /* Should only remove one? */ if(_pContext == _pfnEventHandler) { /* Stops */ break; } } } } else { /* Defaults to success */ eResult = orxSTATUS_SUCCESS; } /* Done! */ return eResult; }
static void Run() { // Ready? if(orxFLAG_TEST_ALL(sstFontGen.u32Flags, orxFONTGEN_KU32_STATIC_MASK_READY)) { orxU32 u32Counter; // Gets glyph list's counter u32Counter = orxLinkList_GetCounter(&sstFontGen.stGlyphList); // Valid? if(u32Counter) { orxS32 s32Width, s32Height, s32BaseLine, s32MaxAscend, s32MaxDescend; orxSTRING *azWidthList = orxNULL; orxFLOAT fWidth, fHeight; orxU8 *pu8ImageBuffer; // Not monospaced? if(!orxFLAG_TEST(sstFontGen.u32Flags, orxFONTGEN_KU32_STATIC_FLAG_MONOSPACE)) { orxU32 i; // Allocates width list azWidthList = (orxSTRING *)orxMemory_Allocate(u32Counter * sizeof(orxSTRING), orxMEMORY_TYPE_MAIN); // Checks orxASSERT(azWidthList); // For all strings for(i = 0; i < u32Counter; i++) { azWidthList[i] = (orxSTRING)orxMemory_Allocate(8 * sizeof(orxCHAR), orxMEMORY_TYPE_MAIN); } } // No font name? if(!sstFontGen.zFontName) { // Uses default one sstFontGen.zFontName = orxString_Duplicate(orxFONTGEN_KZ_DEFAULT_NAME); // Logs message orxFONTGEN_LOG(OUTPUT, "No output name specified, defaulting to '%s'.", orxFONTGEN_KZ_DEFAULT_NAME); } // Is not monospaced? if(!orxFLAG_TEST(sstFontGen.u32Flags, orxFONTGEN_KU32_STATIC_FLAG_MONOSPACE)) { orxFONTGEN_GLYPH *pstGlyph; orxS32 s32LargestWidth = 0; // For all defined glyphs for(pstGlyph = (orxFONTGEN_GLYPH *)orxLinkList_GetFirst(&sstFontGen.stGlyphList); pstGlyph; pstGlyph = (orxFONTGEN_GLYPH *)orxLinkList_GetNext(&pstGlyph->stNode)) { orxS32 s32CharacterWidth; FT_Error eError; // Loads rendered glyph eError = FT_Load_Glyph(sstFontGen.pstFontFace, (FT_UInt)pstGlyph->u32Index, FT_LOAD_RENDER); orxASSERT(!eError); // Use original advance value? if(orxFLAG_TEST(sstFontGen.u32Flags, orxFONTGEN_KU32_STATIC_FLAG_ADVANCE)) { // Gets character width s32CharacterWidth = sstFontGen.pstFontFace->glyph->advance.x >> 6; } else { // Gets character width s32CharacterWidth = orxMAX((orxS32)sstFontGen.pstFontFace->glyph->bitmap_left, 0) + (orxS32)sstFontGen.pstFontFace->glyph->bitmap.width; } // Updates largest character width s32LargestWidth = orxMAX(s32LargestWidth, s32CharacterWidth); }
static orxSTATUS orxFASTCALL ParseTextFile(const orxSTRING _zFileName) { orxFILE *pstFile; orxSTATUS eResult; // Opens file pstFile = orxFile_Open(_zFileName, orxFILE_KU32_FLAG_OPEN_READ | orxFILE_KU32_FLAG_OPEN_BINARY); // Success? if(pstFile) { orxCHAR acBuffer[orxFONTGEN_KU32_BUFFER_SIZE]; orxU32 u32Size, u32Offset, u32Counter; orxBOOL bFirst; // While file isn't empty for(u32Size = (orxU32)orxFile_Read(acBuffer, sizeof(orxCHAR), orxFONTGEN_KU32_BUFFER_SIZE, pstFile), u32Offset = 0, u32Counter = 0, bFirst = orxTRUE; u32Size > 0; u32Size = (orxU32)orxFile_Read(acBuffer + u32Offset, sizeof(orxCHAR), orxFONTGEN_KU32_BUFFER_SIZE - u32Offset, pstFile) + u32Offset, bFirst = orxFALSE) { orxCHAR *pc, *pcNext; // Has UTF-8 BOM? if((bFirst != orxFALSE) && (orxString_NCompare(acBuffer, orxFONTGEN_KZ_UTF8_BOM, orxFONTGEN_KU32_UTF8_BOM_LENGTH) == 0)) { // Skips it pc = acBuffer + orxFONTGEN_KU32_UTF8_BOM_LENGTH; } else { // Starts at the beginning of the buffer pc = acBuffer; } // For all characters for(pcNext = orxNULL; pc < acBuffer + u32Size; pc = pcNext) { orxU32 u32CharacterCodePoint; // Reads it u32CharacterCodePoint = orxString_GetFirstCharacterCodePoint(pc, (const orxSTRING *)&pcNext); // Non EOL? if((u32CharacterCodePoint != orxCHAR_CR) && (u32CharacterCodePoint != orxCHAR_LF)) { // Valid? if(u32CharacterCodePoint != orxU32_UNDEFINED) { // Not already in table? if(orxHashTable_Get(sstFontGen.pstCharacterTable, u32CharacterCodePoint) == orxNULL) { orxU32 u32GlyphIndex; // Gets character's glyph index u32GlyphIndex = (orxU32)FT_Get_Char_Index(sstFontGen.pstFontFace, (FT_ULong)u32CharacterCodePoint); // Valid? if(u32GlyphIndex) { orxFONTGEN_GLYPH *pstGlyph; // Allocates glyph pstGlyph = (orxFONTGEN_GLYPH *)orxBank_Allocate(sstFontGen.pstGlyphBank); // Checks orxASSERT(pstGlyph); // Inits it pstGlyph->u32Index = u32GlyphIndex; pstGlyph->u32CodePoint = u32CharacterCodePoint; // Adds it if(orxHashTable_Add(sstFontGen.pstCharacterTable, u32CharacterCodePoint, (void *)pstGlyph) != orxSTATUS_FAILURE) { orxFONTGEN_GLYPH *pstSearchGlyph; // Finds position for(pstSearchGlyph = (orxFONTGEN_GLYPH *)orxLinkList_GetFirst(&sstFontGen.stGlyphList); pstSearchGlyph && (u32CharacterCodePoint > pstSearchGlyph->u32CodePoint); pstSearchGlyph = (orxFONTGEN_GLYPH *)orxLinkList_GetNext(&pstSearchGlyph->stNode)); // Valid? if(pstSearchGlyph) { // Adds it before orxLinkList_AddBefore(&pstSearchGlyph->stNode, &pstGlyph->stNode); } else { // Adds it at the end orxLinkList_AddEnd(&sstFontGen.stGlyphList, &pstGlyph->stNode); } // Updates counter u32Counter++; } else { // Logs message orxFONTGEN_LOG(LOAD, "Character '0x%X': couldn't add to table, skipping.", u32CharacterCodePoint); } } else { // Adds it orxHashTable_Add(sstFontGen.pstCharacterTable, u32CharacterCodePoint, (void *)sstFontGen.pstCharacterTable); // Logs message orxFONTGEN_LOG(LOAD, "Character '0x%X': glyph not found in font, skipping.", u32CharacterCodePoint); } } } else { // End of buffer? if(pcNext >= acBuffer + u32Size) { // Stops break; } else { // Logs message orxFONTGEN_LOG(LOAD, "Invalid character code point '0x%X', skipping.", u32CharacterCodePoint); } } } } // Has remaining buffer? if((pc != acBuffer) && (pcNext > pc)) { // Updates offset u32Offset = (orxU32)(orxMIN(pcNext, acBuffer + u32Size) - pc); // Copies it at the beginning of the buffer orxMemory_Copy(acBuffer, pc, u32Offset); } else { // Clears offset u32Offset = 0; } } // Logs message orxFONTGEN_LOG(LOAD, "'%s': added %d characters.", _zFileName, u32Counter); // Updates result eResult = orxSTATUS_SUCCESS; } else { // Updates result eResult = orxSTATUS_FAILURE; } // Done! return eResult; }
/** Deletes a clock * @param[in] _pstClock Concerned clock * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxClock_Delete(orxCLOCK *_pstClock) { orxSTATUS eResult = orxSTATUS_SUCCESS; /* Checks */ orxASSERT(sstClock.u32Flags & orxCLOCK_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstClock); /* Decreases counter */ orxStructure_DecreaseCounter(_pstClock); /* Not referenced? */ if(orxStructure_GetRefCounter(_pstClock) == 0) { /* Not locked? */ if(!orxStructure_TestFlags(_pstClock, orxCLOCK_KU32_FLAG_UPDATE_LOCK)) { orxCLOCK_TIMER_STORAGE *pstTimerStorage; /* For all stored timers */ for(pstTimerStorage = (orxCLOCK_TIMER_STORAGE *)orxLinkList_GetFirst(&(_pstClock->stTimerList)); pstTimerStorage != orxNULL; pstTimerStorage = (orxCLOCK_TIMER_STORAGE *)orxLinkList_GetFirst(&(_pstClock->stTimerList))) { /* Removes it */ orxLinkList_Remove(&(pstTimerStorage->stNode)); /* Deletes it */ orxBank_Free(sstClock.pstTimerBank, pstTimerStorage); } /* Deletes function bank */ orxBank_Delete(_pstClock->pstFunctionBank); /* Is referenced? */ if(orxStructure_TestFlags(_pstClock, orxCLOCK_KU32_FLAG_REFERENCED)) { /* Removes it from reference table */ orxHashTable_Remove(sstClock.pstReferenceTable, orxString_ToCRC(_pstClock->zReference)); } /* Has reference? */ if(_pstClock->zReference != orxNULL) { /* Unprotects it */ orxConfig_ProtectSection(_pstClock->zReference, orxFALSE); } /* Deletes clock */ orxStructure_Delete(_pstClock); } else { /* Increases counter */ orxStructure_IncreaseCounter(_pstClock); /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_CLOCK, "Can't delete clock <%s> as it's currently locked for processing!", orxStructure_TestFlags(_pstClock, orxCLOCK_KU32_FLAG_REFERENCED) ? _pstClock->zReference : orxSTRING_EMPTY); /* Updates result */ eResult = orxSTATUS_FAILURE; } } else { /* Referenced by others */ eResult = orxSTATUS_FAILURE; } /* Done! */ return eResult; }
/** Updates the clock system * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxClock_Update() { orxDOUBLE dNewTime; orxFLOAT fDT, fDelay; orxCLOCK *pstClock; orxSTATUS eResult = orxSTATUS_SUCCESS; /* Checks */ orxASSERT(sstClock.u32Flags & orxCLOCK_KU32_STATIC_FLAG_READY); /* Not already locked? */ if(!(sstClock.u32Flags & orxCLOCK_KU32_STATIC_FLAG_UPDATE_LOCK)) { /* Lock clocks */ sstClock.u32Flags |= orxCLOCK_KU32_STATIC_FLAG_UPDATE_LOCK; /* Gets new time */ dNewTime = orxSystem_GetTime(); /* Computes natural DT */ fDT = (orxFLOAT)(dNewTime - sstClock.dTime); /* Gets modified DT */ fDT = orxClock_ComputeDT(fDT, orxNULL); /* Updates time */ sstClock.dTime = dNewTime; /* Inits delay */ fDelay = sstClock.fMainClockTickSize; /* For all clocks */ for(pstClock = orxCLOCK(orxStructure_GetFirst(orxSTRUCTURE_ID_CLOCK)); pstClock != orxNULL; pstClock = orxCLOCK(orxStructure_GetNext(pstClock))) { /* Locks it */ orxStructure_SetFlags(pstClock, orxCLOCK_KU32_FLAG_UPDATE_LOCK, orxCLOCK_KU32_FLAG_NONE); /* Is clock not paused? */ if(orxClock_IsPaused(pstClock) == orxFALSE) { orxFLOAT fClockDelay; /* Updates clock real time & partial DT */ pstClock->fPartialDT += fDT; /* New tick happens? */ if(pstClock->fPartialDT >= pstClock->stClockInfo.fTickSize) { orxFLOAT fClockDT; orxCLOCK_TIMER_STORAGE *pstTimerStorage; orxCLOCK_FUNCTION_STORAGE *pstFunctionStorage; /* Gets clock modified DT */ fClockDT = orxClock_ComputeDT(pstClock->fPartialDT, &(pstClock->stClockInfo)); /* Updates clock DT */ pstClock->stClockInfo.fDT = fClockDT; /* Updates clock time */ pstClock->stClockInfo.fTime += fClockDT; /* For all timers */ for(pstTimerStorage = (orxCLOCK_TIMER_STORAGE *)orxLinkList_GetFirst(&(pstClock->stTimerList)); pstTimerStorage != orxNULL;) { /* Should call it? */ if((pstTimerStorage->fTimeStamp <= pstClock->stClockInfo.fTime) && (pstTimerStorage->s32Repetition != 0)) { /* Calls it */ pstTimerStorage->pfnCallback(&(pstClock->stClockInfo), pstTimerStorage->pContext); /* Updates its time stamp */ pstTimerStorage->fTimeStamp = pstClock->stClockInfo.fTime + pstTimerStorage->fDelay; /* Should update counter */ if(pstTimerStorage->s32Repetition > 0) { /* Updates it */ pstTimerStorage->s32Repetition--; } } /* Should delete it */ if(pstTimerStorage->s32Repetition == 0) { orxCLOCK_TIMER_STORAGE *pstDelete; /* Gets timer to delete */ pstDelete = pstTimerStorage; /* Gets the next timer */ pstTimerStorage = (orxCLOCK_TIMER_STORAGE *)orxLinkList_GetNext(&(pstTimerStorage->stNode)); /* Removes current timer */ orxLinkList_Remove(&(pstDelete->stNode)); /* Deletes it */ orxBank_Free(sstClock.pstTimerBank, pstDelete); } else { /* Gets the next timer */ pstTimerStorage = (orxCLOCK_TIMER_STORAGE *)orxLinkList_GetNext(&(pstTimerStorage->stNode)); } } /* For all registered callbacks */ for(pstFunctionStorage = (orxCLOCK_FUNCTION_STORAGE *)orxLinkList_GetFirst(&(pstClock->stFunctionList)); pstFunctionStorage != orxNULL; pstFunctionStorage = (orxCLOCK_FUNCTION_STORAGE *)orxLinkList_GetNext(&(pstFunctionStorage->stNode))) { /* Calls it */ pstFunctionStorage->pfnCallback(&(pstClock->stClockInfo), pstFunctionStorage->pContext); } /* Updates partial DT */ pstClock->fPartialDT = orxFLOAT_0; } /* Gets clock's delay */ fClockDelay = pstClock->stClockInfo.fTickSize - pstClock->fPartialDT; /* Smaller than previous clocks' delay? */ if(fClockDelay < fDelay) { /* Stores it */ fDelay = fClockDelay; } } /* Unlocks it */ orxStructure_SetFlags(pstClock, orxCLOCK_KU32_FLAG_NONE, orxCLOCK_KU32_FLAG_UPDATE_LOCK); } /* Unlocks clocks */ sstClock.u32Flags &= ~orxCLOCK_KU32_STATIC_FLAG_UPDATE_LOCK; /* Gets real remaining delay */ fDelay = fDelay + orxCLOCK_KF_DELAY_ADJUSTMENT - orx2F(orxSystem_GetTime() - sstClock.dTime); /* Should delay? */ if(fDelay > orxFLOAT_0) { /* Waits for next time slice */ orxSystem_Delay(fDelay); } } /* Done! */ return eResult; }
/** Registers a callback function to a clock * @param[in] _pstClock Concerned clock * @param[in] _pfnCallback Callback to register * @param[in] _pContext Context that will be transmitted to the callback when called * @param[in] _eModuleID ID of the module related to this callback * @param[in] _ePriority Priority for the function * @return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxClock_Register(orxCLOCK *_pstClock, const orxCLOCK_FUNCTION _pfnCallback, void *_pContext, orxMODULE_ID _eModuleID, orxCLOCK_PRIORITY _ePriority) { orxCLOCK_FUNCTION_STORAGE *pstFunctionStorage; orxSTATUS eResult = orxSTATUS_SUCCESS; /* Checks */ orxASSERT(sstClock.u32Flags & orxCLOCK_KU32_STATIC_FLAG_READY); orxSTRUCTURE_ASSERT(_pstClock); orxASSERT(_pfnCallback != orxNULL); /* Gets function slot */ pstFunctionStorage = (orxCLOCK_FUNCTION_STORAGE *)orxBank_Allocate(_pstClock->pstFunctionBank); /* Valid? */ if(pstFunctionStorage != orxNULL) { orxCLOCK_FUNCTION_STORAGE *pstRefFunctionStorage; /* Finds correct index */ for(pstRefFunctionStorage = (orxCLOCK_FUNCTION_STORAGE *)orxLinkList_GetFirst(&(_pstClock->stFunctionList)); pstRefFunctionStorage != orxNULL; pstRefFunctionStorage = (orxCLOCK_FUNCTION_STORAGE *)orxLinkList_GetNext(&(pstRefFunctionStorage->stNode))) { /* Higher priority */ if(_ePriority > pstRefFunctionStorage->ePriority) { /* Stores it */ orxLinkList_AddBefore(&(pstRefFunctionStorage->stNode), &(pstFunctionStorage->stNode)); pstFunctionStorage->ePriority = _ePriority; break; } } /* No index found? */ if(pstRefFunctionStorage == orxNULL) { /* Stores it at the end */ orxLinkList_AddEnd(&(_pstClock->stFunctionList), &(pstFunctionStorage->stNode)); pstFunctionStorage->ePriority = _ePriority; } /* Stores callback */ pstFunctionStorage->pfnCallback = _pfnCallback; /* Stores context */ pstFunctionStorage->pContext = _pContext; /* Stores module id */ pstFunctionStorage->eModuleID = _eModuleID; } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_CLOCK, "Couldn't allocate bank for function storage."); /* Not successful */ eResult = orxSTATUS_FAILURE; } /* Done! */ return eResult; }