/** Gets a track duration using its config ID * @param[in] _zTrackID Config ID of the concerned track * @return Duration if found, -orxFLOAT_1 otherwise */ orxFLOAT orxFASTCALL orxTimeLine_GetTrackDuration(const orxSTRING _zTrackID) { orxTIMELINE_TRACK *pstTrack; orxU32 u32TrackID; orxFLOAT fResult; /* Checks */ orxASSERT(sstTimeLine.u32Flags & orxTIMELINE_KU32_STATIC_FLAG_READY); orxASSERT((_zTrackID != orxNULL) && (_zTrackID != orxSTRING_EMPTY)); /* Gets track CRC */ u32TrackID = orxString_ToCRC(_zTrackID); /* Gets it */ if((pstTrack = (orxTIMELINE_TRACK *)orxHashTable_Get(sstTimeLine.pstTrackTable, u32TrackID)) != orxNULL) { /* Updates result */ fResult = pstTrack->astEventList[pstTrack->u32EventCounter - 1].fTimeStamp; } else { /* Updates result */ fResult = -orxFLOAT_1; } /* Done! */ return fResult; }
/** Gets camera given its name * @param[in] _zName Camera name * @return orxCAMERA / orxNULL */ orxCAMERA *orxFASTCALL orxCamera_Get(const orxSTRING _zName) { orxCAMERA *pstResult; /* Checks */ orxASSERT(sstCamera.u32Flags & orxCAMERA_KU32_STATIC_FLAG_READY); orxASSERT(_zName != orxNULL); /* Updates result */ pstResult = (orxCAMERA *)orxHashTable_Get(sstCamera.pstReferenceTable, orxString_ToCRC(_zName)); /* Done! */ return pstResult; }
/** Gets clock given its name * @param[in] _zName Clock name * @return orxCLOCK / orxNULL */ orxCLOCK *orxFASTCALL orxClock_Get(const orxSTRING _zName) { orxCLOCK *pstResult; /* Checks */ orxASSERT(sstClock.u32Flags & orxCLOCK_KU32_STATIC_FLAG_READY); orxASSERT(_zName != orxNULL); /* Valid name? */ if(_zName != orxSTRING_EMPTY) { /* Updates result */ pstResult = (orxCLOCK *)orxHashTable_Get(sstClock.pstReferenceTable, orxString_ToCRC(_zName)); } else { /* Clears result */ pstResult = orxNULL; } /* Done! */ return pstResult; }
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; }
/** Adds a track to a TimeLine from config * @param[in] _pstTimeLine Concerned TimeLine * @param[in] _zTrackID Config ID * return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxTimeLine_AddTrackFromConfig(orxTIMELINE *_pstTimeLine, const orxSTRING _zTrackID) { orxU32 u32Index; orxSTATUS eResult = orxSTATUS_FAILURE; /* Checks */ orxSTRUCTURE_ASSERT(_pstTimeLine); orxASSERT((_zTrackID != orxNULL) && (_zTrackID != orxSTRING_EMPTY)); /* Checks */ orxSTRUCTURE_ASSERT(_pstTimeLine); /* Finds an empty track */ for(u32Index = 0; (u32Index < orxTIMELINE_KU32_TRACK_NUMBER) && (_pstTimeLine->astTrackList[u32Index].pstTrack != orxNULL); u32Index++); /* Found? */ if(u32Index < orxTIMELINE_KU32_TRACK_NUMBER) { orxTIMELINE_TRACK *pstTrack; orxU32 u32ID; /* Gets track ID */ u32ID = orxString_ToCRC(_zTrackID); /* Search for reference */ pstTrack = (orxTIMELINE_TRACK *)orxHashTable_Get(sstTimeLine.pstTrackTable, u32ID); /* Found? */ if(pstTrack != orxNULL) { /* Increases counter */ pstTrack->u32RefCounter++; } else { /* Creates track */ pstTrack = orxTimeLine_CreateTrack(_zTrackID); } /* Valid? */ if(pstTrack != orxNULL) { orxTIMELINE_EVENT_PAYLOAD stPayload; orxSTRUCTURE *pstOwner; /* Gets owner */ pstOwner = orxStructure_GetOwner(_pstTimeLine); /* Updates track holder */ _pstTimeLine->astTrackList[u32Index].pstTrack = pstTrack; _pstTimeLine->astTrackList[u32Index].fStartTime = _pstTimeLine->fTime; _pstTimeLine->astTrackList[u32Index].u32NextEventIndex = 0; _pstTimeLine->astTrackList[u32Index].u32Flags = orxTIMELINE_HOLDER_KU32_FLAG_NONE; /* Inits event payload */ orxMemory_Zero(&stPayload, sizeof(orxTIMELINE_EVENT_PAYLOAD)); stPayload.pstTimeLine = _pstTimeLine; stPayload.zTrackName = pstTrack->zReference; /* Sends event */ orxEVENT_SEND(orxEVENT_TYPE_TIMELINE, orxTIMELINE_EVENT_TRACK_ADD, pstOwner, pstOwner, &stPayload); /* Updates timeline flags */ orxStructure_SetFlags(_pstTimeLine, orxTIMELINE_KU32_FLAG_DIRTY, orxTIMELINE_KU32_FLAG_NONE); /* Is immediate? */ if(orxFLAG_TEST(pstTrack->u32Flags, orxTIMELINE_TRACK_KU32_FLAG_IMMEDIATE)) { /* Updates it */ orxTimeLine_Update(orxSTRUCTURE(_pstTimeLine), pstOwner, orxNULL); } /* Updates result */ eResult = orxSTATUS_SUCCESS; } } else { /* Logs message */ orxDEBUG_PRINT(orxDEBUG_LEVEL_OBJECT, "No room for a new track in TimeLine, can't add track <%s>.", _zTrackID); } /* 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; }
/** Adds an event handler with user-defined context * @param[in] _eEventType Concerned type of event * @param[in] _pfnHandler Event handler to add * @param[in] _pContext Context that will be stored in events sent to this handler * return orxSTATUS_SUCCESS / orxSTATUS_FAILURE */ orxSTATUS orxFASTCALL orxEvent_AddHandlerWithContext(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); /* No storage yet? */ if(pstStorage == orxNULL) { /* Allocates it */ pstStorage = (orxEVENT_HANDLER_STORAGE *)orxBank_Allocate(sstEvent.pstHandlerStorageBank); /* Success? */ if(pstStorage != orxNULL) { /* Creates its bank */ pstStorage->pstBank = orxBank_Create(orxEVENT_KU32_HANDLER_BANK_SIZE, sizeof(orxEVENT_HANDLER_INFO), orxBANK_KU32_FLAG_NONE, orxMEMORY_TYPE_MAIN); /* Success? */ if(pstStorage->pstBank != orxNULL) { /* Clears its list */ orxMemory_Zero(&(pstStorage->stList), sizeof(orxLINKLIST)); /* Is a core event handler? */ if(_eEventType < orxEVENT_TYPE_CORE_NUMBER) { /* Stores it */ sstEvent.astCoreHandlerStorageList[_eEventType] = pstStorage; } else { /* Tries to add it to the table */ if(orxHashTable_Add(sstEvent.pstHandlerStorageTable, _eEventType, pstStorage) == orxSTATUS_FAILURE) { /* Deletes its bank */ orxBank_Delete(pstStorage->pstBank); /* Frees storage */ orxBank_Free(sstEvent.pstHandlerStorageBank, pstStorage); pstStorage = orxNULL; } } } else { /* Frees storage */ orxBank_Free(sstEvent.pstHandlerStorageBank, pstStorage); pstStorage = orxNULL; } } } /* Valid? */ if(pstStorage != orxNULL) { orxEVENT_HANDLER_INFO *pstInfo; /* Allocates a new handler info */ pstInfo = (orxEVENT_HANDLER_INFO *)orxBank_Allocate(pstStorage->pstBank); /* Valid? */ if(pstInfo != orxNULL) { /* Clears its node */ orxMemory_Zero(&(pstInfo->stNode), sizeof(orxLINKLIST_NODE)); /* Stores its handler */ pstInfo->pfnHandler = _pfnEventHandler; /* Stores context */ pstInfo->pContext = _pContext; /* Adds it to the list */ eResult = orxLinkList_AddEnd(&(pstStorage->stList), &(pstInfo->stNode)); } } /* Done! */ return eResult; }