Architecture & Internals#

This section provides detailed flowcharts showing how PyECS components work internally.

Core Components#

World Operations#

create_entity#

        flowchart TD
    Start([create_entity called]) --> CallEntityManager[Call entity_manager.create_entity]
    
    CallEntityManager --> CheckResult{Result is tuple?}
    
    CheckResult -->|Yes| ExtractEntity[Extract entity from tuple index 1]
    CheckResult -->|No| ReturnFailure[Return result as FAILURE]
    
    ExtractEntity --> CreateEmptyMask[Create empty frozenset mask]
    CreateEmptyMask --> CheckArchetypeExists{Empty mask in archetypes?}
    
    CheckArchetypeExists -->|No| ImportArchetype[Import Archetype class]
    CheckArchetypeExists -->|Yes| SetMapping[Set entity_to_archetype mapping]
    
    ImportArchetype --> CreateArchetype[Create new Archetype instance]
    CreateArchetype --> AddToArchetypes[Add to component_storage.archetypes]
    AddToArchetypes --> SetMapping
    
    SetMapping --> ReturnEntity[Return entity]
    
    ReturnFailure --> End1([End])
    ReturnEntity --> End2([End])
    

create_entity_or_raise#

        flowchart TD
    Start([create_entity_or_raise called]) --> CallSafe[Call create_entity internally]
    
    CallSafe --> CheckResult{Result == StatusCodes.FAILURE?}
    
    CheckResult -->|No| ReturnEntity[Return entity]
    CheckResult -->|Yes| RaiseException[Raise OperationFailedError]
    
    ReturnEntity --> Success([Success: Entity returned])
    RaiseException --> Error([Error: Exception raised])
    

get_component#

        flowchart TD
    Start([get_component called with entity and component_type]) --> CheckAlive{entity_manager.is_alive?}
    
    CheckAlive -->|Yes| CallGetComponent[Call component_storage.get_component]
    CheckAlive -->|No| ReturnFailure[Return FAILURE]
    
    CallGetComponent --> ReturnResult[Return component or FAILURE]
    
    ReturnFailure --> End1([End])
    ReturnResult --> End2([End])
    

get_component_or_raise#

        flowchart TD
    Start([get_component_or_raise called with entity and component_type]) --> CallSafe[Call get_component internally]
    
    CallSafe --> CheckResult{Result == StatusCodes.FAILURE?}
    
    CheckResult -->|No| ReturnComponent[Return component]
    CheckResult -->|Yes| RaiseException[Raise ComponentNotFoundError]
    
    ReturnComponent --> Success([Success: Component returned])
    RaiseException --> Error([Error: Exception raised])
    

get_components#

        flowchart TD
    Start([get_components called with entity and component_types]) --> CheckSingle{len component_types == 1?}
    
    CheckSingle -->|Yes| WarnDeprecated[warn_deprecated: Use get_component for single component]
    CheckSingle -->|No| CheckAlive{entity_manager.is_alive?}
    
    WarnDeprecated --> CallSingle[Call get_component with single type]
    CallSingle --> CheckSingleResult{Result == FAILURE?}
    CheckSingleResult -->|Yes| ReturnFailure1[Return FAILURE]
    CheckSingleResult -->|No| WrapTuple[Wrap in tuple]
    WrapTuple --> End1([End])
    ReturnFailure1 --> End2([End])
    
    CheckAlive -->|No| ReturnFailure2[Return FAILURE]
    CheckAlive -->|Yes| InitResult[Initialize empty result list]
    
    InitResult --> ForEachType{For each component_type}
    
    ForEachType --> GetComponent[Call component_storage.get_component]
    GetComponent --> CheckResult{component == FAILURE?}
    
    CheckResult -->|Yes| ReturnFailure3[Return FAILURE]
    CheckResult -->|No| AppendResult[Append component to result]
    
    AppendResult --> MoreTypes{More types?}
    MoreTypes -->|Yes| ForEachType
    MoreTypes -->|No| ReturnTuple[Return tuple of results]
    
    ReturnFailure2 --> End3([End])
    ReturnFailure3 --> End4([End])
    ReturnTuple --> End5([End])
    

get_components_or_raise#

        flowchart TD
    Start([get_components_or_raise called with entity and component_types]) --> CallSafe[Call get_components internally]
    
    CallSafe --> CheckResult{Result == StatusCodes.FAILURE?}
    
    CheckResult -->|No| ReturnTuple[Return tuple of components]
    CheckResult -->|Yes| RaiseException[Raise ComponentNotFoundError]
    
    ReturnTuple --> Success([Success: Components tuple returned])
    RaiseException --> Error([Error: Exception raised])
    

add_component#

        flowchart TD
    Start([add_component called with entity and component]) --> CheckAlive{entity_manager.is_alive?}
    
    CheckAlive -->|Yes| CallAddComponent[Call component_storage.add_component]
    CheckAlive -->|No| End1([End])
    
    CallAddComponent --> End2([End])
    

remove_component#

        flowchart TD
    Start([remove_component called with entity and component_type]) --> CheckAlive{entity_manager.is_alive?}
    
    CheckAlive -->|Yes| CallRemoveComponent[Call component_storage.remove_component]
    CheckAlive -->|No| End1([End])
    
    CallRemoveComponent --> End2([End])
    

destroy_entity#

        flowchart TD
    Start([destroy_entity called with entity]) --> CallEntityManager[Call entity_manager.destroy_entity]
    
    CallEntityManager --> CheckResult{Result == ENTITY_DESTROYED?}
    
    CheckResult -->|Yes| RemoveComponents[Call component_storage.remove_entity]
    CheckResult -->|No| End1([End])
    
    RemoveComponents --> End2([End])
    

add_system#

        flowchart TD
    Start([add_system called with system]) --> RegisterSystem[Call system_manager.register_system]
    
    RegisterSystem --> CheckResult{Result is tuple?}
    
    CheckResult -->|Yes| InitSystem[Call system.init with self]
    CheckResult -->|No| End1([End])
    
    InitSystem --> End2([End])
    

remove_system#

        flowchart TD
    Start([remove_system called with system]) --> CleanupSystem[Call system.cleanup with self]
    
    CleanupSystem --> RemoveFromManager[Call system_manager.remove_system]
    
    RemoveFromManager --> End([End])
    

update#

        flowchart TD
    Start([update called with dt]) --> UpdateAllSystems[Call system_manager.update_all with self and dt]
    
    UpdateAllSystems --> End([End])
    

Query System#

Query Construction#

with_components#
        flowchart TD
    Start([with_components called with types]) --> UpdateSet[Update _with set with types]
    
    UpdateSet --> ReturnSelf[Return self]
    
    ReturnSelf --> End([End])
    
without_components#
        flowchart TD
    Start([without_components called with types]) --> UpdateSet[Update _without set with types]
    
    UpdateSet --> ReturnSelf[Return self]
    
    ReturnSelf --> End([End])
    

Query Execution#

        flowchart TD
    Start([execute called with storage_or_world]) --> CheckType{Is ComponentStorage?}
    
    CheckType -->|Yes| WarnDeprecated[warn_deprecated: Passing ComponentStorage directly is deprecated]
    CheckType -->|No| GetStorage[Get component_storage from world]
    
    WarnDeprecated --> SetStorage1[storage = storage_or_world]
    GetStorage --> SetStorage2[storage = storage_or_world.component_storage]
    
    SetStorage1 --> InitList[Initialize empty matching list]
    SetStorage2 --> InitList
    
    InitList --> LoopArchetypes[Loop through storage.archetypes items]
    LoopArchetypes --> GetMaskAndArch[Get mask and archetype]
    
    GetMaskAndArch --> CheckWith{_with subset of mask?}
    
    CheckWith -->|No| NextArchetype[Continue to next archetype]
    CheckWith -->|Yes| CheckWithout{_without intersects mask?}
    
    CheckWithout -->|Yes| NextArchetype
    CheckWithout -->|No| ExtendMatching[Extend matching with archetype.entities]
    
    NextArchetype --> MoreArchetypes{More archetypes?}
    ExtendMatching --> MoreArchetypes
    
    MoreArchetypes -->|Yes| LoopArchetypes
    MoreArchetypes -->|No| ReturnMatching[Return matching list]
    
    ReturnMatching --> End([End])
    

Storage Layer#

ComponentStorage Operations#

add_component#
        flowchart TD
    Start([add_component called with entity and component]) --> CheckEntity{Entity in entity_to_archetype?}
    
    CheckEntity -->|No| ReturnFailure[Return FAILURE]
    CheckEntity -->|Yes| GetMask[Get current archetype mask]
    
    GetMask --> GetArchetype[Get current archetype from mask]
    GetArchetype --> CheckComponentType{Component type in mask?}
    
    CheckComponentType -->|No| CreateNewMask[Create new mask with component type]
    CheckComponentType -->|Yes| GetEntityIndex[Get entity_index from archetype.entity_indices - O1 lookup]
    
    CreateNewMask --> GetComponents[Get all entity components]
    GetComponents --> AppendComponent[Append new component to list]
    AppendComponent --> MoveEntity[Call move_entity_to_archetype with new mask]
    MoveEntity --> ReturnAdded[Return COMPONENT_ADDED]
    
    GetEntityIndex --> UpdateComponent[Update component at entity_index in component array]
    UpdateComponent --> ReturnUpdated[Return COMPONENT_UPDATED]
    
    ReturnFailure --> End1([End])
    ReturnAdded --> End2([End])
    ReturnUpdated --> End3([End])
    
remove_component#
        flowchart TD
    Start([remove_component called with entity and component_type]) --> CheckEntity{Entity in entity_to_archetype?}
    
    CheckEntity -->|No| ReturnFailure1[Return FAILURE]
    CheckEntity -->|Yes| GetMask[Get current archetype mask]
    
    GetMask --> GetArchetype[Get current archetype]
    GetArchetype --> CheckHasComponent{Component type in mask?}
    
    CheckHasComponent -->|No| ReturnFailure2[Return FAILURE]
    CheckHasComponent -->|Yes| CreateNewMask[Create new mask without component type]
    
    CreateNewMask --> CheckMaskEmpty{New mask empty?}
    
    CheckMaskEmpty -->|No| GetRemainingComponents[Get all components except removed type]
    CheckMaskEmpty -->|Yes| RemoveEntity[Call self.remove_entity]
    
    GetRemainingComponents --> LoopComponents[Loop through mask types]
    LoopComponents --> CheckNotRemoved{Type != removed type?}
    
    CheckNotRemoved -->|Yes| GetComponent[Get component from archetype]
    CheckNotRemoved -->|No| SkipComponent[Skip this component]
    
    GetComponent --> AppendToList[Append to components list]
    AppendToList --> LoopComponents
    SkipComponent --> LoopComponents
    
    LoopComponents --> MoveEntity[Call move_entity_to_archetype with new mask]
    MoveEntity --> ReturnRemoved1[Return COMPONENT_REMOVED]
    
    RemoveEntity --> ReturnRemoved2[Return COMPONENT_REMOVED]
    
    ReturnFailure1 --> End1([End])
    ReturnFailure2 --> End2([End])
    ReturnRemoved1 --> End3([End])
    ReturnRemoved2 --> End4([End])
    
get_component#
        flowchart TD
    Start([get_component called with entity and component_type]) --> CheckEntity{Entity in entity_to_archetype?}
    
    CheckEntity -->|No| ReturnFailure1[Return FAILURE]
    CheckEntity -->|Yes| GetMask[Get entity archetype mask]
    
    GetMask --> GetArchetype[Get archetype from mask]
    GetArchetype --> CheckHasComponent{Component type in mask?}
    
    CheckHasComponent -->|No| ReturnFailure2[Return FAILURE]
    CheckHasComponent -->|Yes| CallArchetypeGet[Call archetype.get_component]
    
    CallArchetypeGet --> ReturnComponent[Return component instance]
    
    ReturnFailure1 --> End1([End])
    ReturnFailure2 --> End2([End])
    ReturnComponent --> End3([End])
    
get_entity_components#
        flowchart TD
    Start([get_entity_components called with entity]) --> GetMask[Get entity mask from entity_to_archetype]
    
    GetMask --> GetArchetype[Get archetype from mask]
    GetArchetype --> InitList[Initialize empty components list]
    
    InitList --> LoopTypes[Loop through component types in mask]
    LoopTypes --> GetComponent[Call archetype.get_component for type]
    
    GetComponent --> AppendComponent[Append component to list]
    AppendComponent --> LoopTypes
    
    LoopTypes --> ReturnList[Return components list]
    ReturnList --> End([End])
    
has_component#
        flowchart TD
    Start([has_component called with entity and component_type]) --> CheckEntity{Entity in entity_to_archetype?}
    
    CheckEntity -->|No| ReturnFalse[Return False]
    CheckEntity -->|Yes| GetMask[Get entity archetype mask]
    
    GetMask --> CheckInMask{Component type in mask?}
    
    CheckInMask -->|No| ReturnFalse2[Return False]
    CheckInMask -->|Yes| ReturnTrue[Return True]
    
    ReturnFalse --> End1([End])
    ReturnFalse2 --> End2([End])
    ReturnTrue --> End3([End])
    
move_entity_to_archetype#
        flowchart TD
    Start([move_entity_to_archetype called]) --> CheckEntityExists{Entity in entity_to_archetype?}
    
    CheckEntityExists -->|Yes| GetCurrentMask[Get current mask]
    CheckEntityExists -->|No| CheckComponentsParam{Components parameter provided?}
    
    GetCurrentMask --> GetCurrentArchetype[Get current archetype]
    GetCurrentArchetype --> CheckComponentsProvided{Components parameter provided?}
    
    CheckComponentsProvided -->|No| GetEntityComponents[Call get_entity_components]
    CheckComponentsProvided -->|Yes| UseProvidedComponents[Use provided components]
    
    GetEntityComponents --> RemoveFromCurrent[Remove entity from current archetype]
    UseProvidedComponents --> RemoveFromCurrent
    
    CheckComponentsParam -->|No| SetEmptyComponents[Set components = empty list]
    CheckComponentsParam -->|Yes| UseProvided[Use provided components]
    
    SetEmptyComponents --> CheckArchetypeExists{New mask in archetypes?}
    UseProvided --> CheckArchetypeExists
    RemoveFromCurrent --> CheckArchetypeExists
    
    CheckArchetypeExists -->|No| CreateArchetype[Create new Archetype]
    CheckArchetypeExists -->|Yes| GetTargetArchetype[Get target archetype]
    
    CreateArchetype --> AddToArchetypes[Add to archetypes dict]
    AddToArchetypes --> GetTargetArchetype
    
    GetTargetArchetype --> AddEntity[Call target_archetype.add_entity]
    AddEntity --> UpdateMapping[Update entity_to_archetype mapping]
    UpdateMapping --> ReturnSuccess[Return SUCCESS]
    
    ReturnSuccess --> End([End])
    
remove_entity#
        flowchart TD
    Start([remove_entity called with entity]) --> CheckEntity{Entity in entity_to_archetype?}
    
    CheckEntity -->|No| ReturnFailure[Return FAILURE]
    CheckEntity -->|Yes| GetMask[Get entity archetype mask]
    
    GetMask --> GetArchetype[Get archetype from mask]
    GetArchetype --> RemoveFromArchetype[Call archetype.remove_entity]
    
    RemoveFromArchetype --> DeleteMapping[Delete from entity_to_archetype]
    DeleteMapping --> ReturnSuccess[Return SUCCESS]
    
    ReturnFailure --> End1([End])
    ReturnSuccess --> End2([End])
    

Archetype Operations#

add_entity#
        flowchart TD
    Start([add_entity called with entity and components list]) --> CheckExists{Entity in entity_indices dict?}
    
    CheckExists -->|Yes| ReturnFailure[Return FAILURE]
    CheckExists -->|No| CalcIndex["Calculate entity_index as len(entities)"]
    
    CalcIndex --> AppendEntity[Append entity to entities list]
    AppendEntity --> AddToDict["Add entity->entity_index to entity_indices dict"]
    AddToDict --> LoopComponents[Loop through components]
    
    LoopComponents --> GetCompType[Get component.__class__]
    GetCompType --> CheckTypeExists{Component type in self.components?}
    
    CheckTypeExists -->|No| CreateList[Create list with None * entity_index]
    CheckTypeExists -->|Yes| AppendToList[Append component to type list]
    
    CreateList --> AddToDict[Add list to components dict]
    AddToDict --> AppendToList
    
    AppendToList --> MoreComponents{More components?}
    
    MoreComponents -->|Yes| LoopComponents
    MoreComponents -->|No| ReturnSuccess[Return SUCCESS]
    
    ReturnFailure --> End1([End])
    ReturnSuccess --> End2([End])
    
remove_entity#
        flowchart TD
    Start([remove_entity called with entity]) --> CheckExists{Entity in entity_indices dict?}
    
    CheckExists -->|No| ReturnFailure[Return FAILURE]
    CheckExists -->|Yes| GetIndex[Get entity_index from dict - O1 lookup]
    
    GetIndex --> CheckLast{Is entity_index == last_index?}
    
    CheckLast -->|No| SwapWithLast[Swap entity with last entity in lists]
    SwapWithLast --> UpdateLastEntityIndex[Update last entity's index in dict]
    UpdateLastEntityIndex --> SwapComponents[Swap components in all component lists]
    SwapComponents --> RemoveLast
    
    CheckLast -->|Yes| RemoveLast[Pop last entity from entities list]
    RemoveLast --> RemoveFromDict[Delete entity from entity_indices dict]
    RemoveFromDict --> PopComponents[Pop last element from all component lists]
    
    PopComponents --> ReturnSuccess[Return SUCCESS]
    
    ReturnFailure --> End1([End])
    ReturnSuccess --> End2([End])
    
get_component#
        flowchart TD
    Start([get_component called with entity and component_type]) --> CheckEntity{Entity in entity_indices dict?}
    
    CheckEntity -->|No| ReturnFailure1[Return FAILURE]
    CheckEntity -->|Yes| GetIndex[Get entity_index from entity_indices dict - O1 lookup]
    
    GetIndex --> CheckTypeExists{Component type in components dict?}
    
    CheckTypeExists -->|No| ReturnFailure2[Return FAILURE]
    CheckTypeExists -->|Yes| GetFromList[Get component from type list at entity_index]
    
    GetFromList --> ReturnComponent[Return component instance]
    
    ReturnFailure1 --> End1([End])
    ReturnFailure2 --> End2([End])
    ReturnComponent --> End3([End])
    
iter_components#
        flowchart TD
    Start([iter_components called with component_type]) --> CheckTypeExists{Component type in components dict?}
    
    CheckTypeExists -->|Yes| YieldComponents[Yield from components list for type]
    CheckTypeExists -->|No| YieldNothing[Yield nothing]
    
    YieldComponents --> End1([End])
    YieldNothing --> End2([End])
    
iter_entities#
        flowchart TD
    Start([iter_entities called]) --> CreateIterator[Create iterator from entities list]
    
    CreateIterator --> ReturnIterator[Return iterator]
    
    ReturnIterator --> End([End])
    

Entity Management#

EntityManager Operations#

create_entity#
        flowchart TD
    Start([create_entity called]) --> Lock[Acquire thread lock]
    
    Lock --> GenerateUUID[Generate unique UUID4]
    GenerateUUID --> AddToSet[Add UUID to alive_entities set]
    
    AddToSet --> CreateTuple[Create tuple with ENTITY_CREATED status and UUID]
    CreateTuple --> ReleaseLock[Release thread lock]
    
    ReleaseLock --> ReturnSuccess[Return tuple]
    
    ReturnSuccess --> End([End])
    
destroy_entity#
        flowchart TD
    Start([destroy_entity called with entity UUID]) --> Lock[Acquire thread lock]
    
    Lock --> CheckExists{Entity in alive_entities?}
    
    CheckExists -->|No| ReturnFailure[Return FAILURE status]
    CheckExists -->|Yes| RemoveEntity[Remove entity from alive_entities set]
    
    RemoveEntity --> ReturnDestroyed[Return ENTITY_DESTROYED status]
    
    ReturnFailure --> ReleaseLock1[Release thread lock]
    ReturnDestroyed --> ReleaseLock2[Release thread lock]
    
    ReleaseLock1 --> End1([End])
    ReleaseLock2 --> End2([End])
    
is_alive#
        flowchart TD
    Start([is_alive called with entity]) --> Lock[Acquire thread lock]
    
    Lock --> CheckInSet{Entity in alive_entities?}
    
    CheckInSet -->|Yes| ReturnTrue[Return True]
    CheckInSet -->|No| ReturnFalse[Return False]
    
    ReturnTrue --> ReleaseLock1[Release thread lock]
    ReturnFalse --> ReleaseLock2[Release thread lock]
    
    ReleaseLock1 --> End1([End])
    ReleaseLock2 --> End2([End])
    

System Management#

SystemManager Operations#

register_system#
        flowchart TD
    Start([register_system called with system]) --> CheckExists{System in system_to_id?}
    
    CheckExists -->|Yes| ReturnFailure[Return FAILURE]
    CheckExists -->|No| GenerateUUID[Call _unique_id to generate UUID]
    
    GenerateUUID --> AppendSystem[Append system to systems list]
    AppendSystem --> MapSystemToId[Add to system_to_id mapping]
    MapSystemToId --> MapIdToSystem[Add to id_to_system mapping]
    
    MapIdToSystem --> CreateTuple[Create tuple with SYSTEM_REGISTERED and system]
    CreateTuple --> ReturnTuple[Return tuple]
    
    ReturnFailure --> End1([End])
    ReturnTuple --> End2([End])
    
remove_system#
        flowchart TD
    Start([remove_system called with system]) --> CheckExists{System in system_to_id?}
    
    CheckExists -->|No| ReturnFailure[Return FAILURE]
    CheckExists -->|Yes| GetSystemId[Get system_id from system_to_id]
    
    GetSystemId --> CallUnregister[Call unregister_system with system_id]
    CallUnregister --> ReturnResult[Return unregister result]
    
    ReturnFailure --> End1([End])
    ReturnResult --> End2([End])
    
unregister_system#
        flowchart TD
    Start([unregister_system called with id]) --> CheckIdExists{ID in id_to_system?}
    
    CheckIdExists -->|No| ReturnFailure[Return FAILURE]
    CheckIdExists -->|Yes| GetSystem[Get system from id_to_system]
    
    GetSystem --> RemoveFromList[Remove system from systems list]
    RemoveFromList --> DeleteSystemToId[Delete from system_to_id mapping]
    DeleteSystemToId --> DeleteIdToSystem[Delete from id_to_system mapping]
    
    DeleteIdToSystem --> ReturnUnregistered[Return SYSTEM_UNREGISTERED]
    
    ReturnFailure --> End1([End])
    ReturnUnregistered --> End2([End])
    
update_all#
        flowchart TD
    Start([update_all called with world and dt]) --> LoopSystems[Loop through systems list]
    
    LoopSystems --> CallUpdate[Call system.update with world and dt]
    CallUpdate --> MoreSystems{More systems?}
    
    MoreSystems -->|Yes| LoopSystems
    MoreSystems -->|No| End([End])
    

Exception Handling#

PyECS provides both safe (status code) and unsafe (exception-based) APIs for error handling.

Exception Hierarchy#

        classDiagram
    class PyECSError {
        <<abstract>>
        Base exception for all PyECS errors
    }
    
    class ComponentNotFoundError {
        Raised when a component is not found on an entity
    }
    
    class EntityNotFoundError {
        Raised when an entity does not exist or is not alive
    }
    
    class OperationFailedError {
        Raised when a general operation fails
    }
    
    PyECSError <|-- ComponentNotFoundError
    PyECSError <|-- EntityNotFoundError
    PyECSError <|-- OperationFailedError
    

Unsafe Decorator Flow#

        flowchart TD
    Start([Class decorated with @auto_unsafe]) --> ScanMethods{Scan all class methods}
    
    ScanMethods --> ForEachMethod{For each method}
    
    ForEachMethod --> CheckAnnotations{Has return annotation with StatusCodes.FAILURE?}
    
    CheckAnnotations -->|No| NextMethod[Skip to next method]
    CheckAnnotations -->|Yes| DetermineException{Check method name}
    
    DetermineException -->|Contains 'component'| SetComponentError[Exception = ComponentNotFoundError]
    DetermineException -->|Contains 'entity'| SetEntityError[Exception = EntityNotFoundError]
    DetermineException -->|Otherwise| SetOperationError[Exception = OperationFailedError]
    
    SetComponentError --> GenerateUnsafe[Call generate_unsafe decorator]
    SetEntityError --> GenerateUnsafe
    SetOperationError --> GenerateUnsafe
    
    GenerateUnsafe --> CreateWrapper[Create unsafe_wrapper function]
    CreateWrapper --> SetAttribute[Set _unsafe_version attribute on method]
    
    SetAttribute --> NextMethod
    NextMethod --> MoreMethods{More methods?}
    
    MoreMethods -->|Yes| ForEachMethod
    MoreMethods -->|No| ProcessUnsafe[Call process_unsafe_methods]
    
    ProcessUnsafe --> AddToClass[Add all _or_raise methods to class]
    
    AddToClass --> End([Return decorated class])
    

Unsafe Method Execution#

        flowchart TD
    Start([User calls method_or_raise]) --> CallOriginal[Call original method]

    CallOriginal --> CheckResult{Result == StatusCodes.FAILURE?}

    CheckResult -->|No| ReturnValue[Return result value]
    CheckResult -->|Yes| RaiseException[Raise configured exception]

    RaiseException --> ExceptionType{Exception Type}

    ExceptionType -->|ComponentNotFoundError| CompError([Component not found on entity])
    ExceptionType -->|EntityNotFoundError| EntError([Entity does not exist])
    ExceptionType -->|OperationFailedError| OpError([Operation failed])

    ReturnValue --> Success([Success: Value returned])