Interface Component<T>

Type Parameters:
T - The type of argument that can be passed when enabling this component
All Known Implementing Classes:
NWindowManagerComponent, PlayerManagerComponent, StallingComponent

public interface Component<T>
A component is a reusable piece of functionality that can be attached to a ComponentManager. Components are composed of various fragments that define their behavior and capabilities.

Components can be attached and detached from a ComponentManager and can be enabled or disabled with specific arguments. They can also define a slot for mutually exclusive components.

Component Lifecycle

  1. Attached: onAttached(ComponentManager, Runner, DataStoreProvider) is called when the component is first added to the manager
  2. Enabled: onEnable(ComponentManager, Runner, DataStoreProvider, boolean, Object) is called when the component and all its dependencies are ready
  3. Nudged: onNudge(ComponentManager, Runner, DataStoreProvider, boolean, Object) is called when the component is scheduled to be enabled but has pending dependencies
  4. Disabled: onDisable(ComponentManager, Runner, DataStoreProvider) is called when the component is explicitly disabled or when one of its dependencies is disabled
  5. Detached: onDetached(ComponentManager, Runner, DataStoreProvider) is called when the component is removed from the manager

Dependency System

Components can depend on other components and will only be enabled when all their dependencies are enabled. Dependencies are specified when adding a component to the manager:

 manager.addComponent(myComponent, dependency1, dependency2, ...);
 

If any dependency is disabled, components that depend on it will automatically be disabled as well. When dependencies become available again, dependent components will not automatically re-enable; they must be explicitly enabled again.

Best Practices

For a detailed explaination of the component lifecycle and methods execution order, see the Fragment class.

It is usually a good approach to ignore the onAttached(org.ngengine.components.ComponentManager, org.ngengine.runner.Runner, org.ngengine.store.DataStoreProvider) and onDetached(org.ngengine.components.ComponentManager, org.ngengine.runner.Runner, org.ngengine.store.DataStoreProvider) methods and implement all the logic in onEnable(org.ngengine.components.ComponentManager, org.ngengine.runner.Runner, org.ngengine.store.DataStoreProvider, boolean, T) and onDisable(org.ngengine.components.ComponentManager, org.ngengine.runner.Runner, org.ngengine.store.DataStoreProvider), so that when the component is disabled, everything that was set up in onEnable(org.ngengine.components.ComponentManager, org.ngengine.runner.Runner, org.ngengine.store.DataStoreProvider, boolean, T) is cleaned up in onDisable(org.ngengine.components.ComponentManager, org.ngengine.runner.Runner, org.ngengine.store.DataStoreProvider). Unless you are dealing with heavy initialization logic, this will help keeping the code clean and concise.

  • Method Details

    • onAttached

      default void onAttached(ComponentManager mng, Runner runner, DataStoreProvider dataStore)
      Called immediately when the component is attached to a ComponentManager and a Runner.

      This method can be overridden to perform initialization tasks when the component is attached.

      Parameters:
      mng - the ComponentManager to which this component is attached
      runner - the Runner associated with this component
      dataStore - the DataStoreProvider for accessing shared data
    • onDetached

      default void onDetached(ComponentManager mng, Runner runner, DataStoreProvider dataStore)
      Called when the component is detached from the ComponentManager.

      This method can be overridden to perform cleanup tasks when the component is detached.

      Parameters:
      mng -
      runner -
      dataStore -
    • getId

      default String getId()
      Returns an identifier for this component, multiple component can have the same identifier.

      The default implementation returns the simple name of the class. This can be overridden to provide a custom identifier if needed.

      Returns:
      an identifier for this component, default is the simple class name
    • getSlot

      default Object getSlot()
      Returns the slot associated with this component.

      A slot represents a mutually exclusive container for components. Only one component can be active in a given slot at any time. When a component with a defined slot is enabled, any other active component occupying the same slot will be automatically disabled.

      If getSlot() returns null, the component is excluded from slot-based management and can coexist with other components.
      Returns:
      the name of the slot this component belongs to, or null if it does not use a slot
    • onEnable

      void onEnable(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime, T arg)
      Called when the component is enabled. This is the most important method of the component lifecycle, where the component's main logic is implemented.

      This method is called when the component is enabled, all its dependencies are satisfied, the fragments are initialized, and the resources are loaded.

      Parameters:
      mng - - the ComponentManager to which this component is attached
      runner - - the Runner that executes the logic
      dataStore - - the DataStoreProvider for storing and retrieving data and caches
      firstTime - - whether this is the first time the component is being enabled
      arg - - an argument that can be passed when enabling this component, can be null
    • onDisable

      void onDisable(ComponentManager mng, Runner runner, DataStoreProvider dataStore)
      Called when the component is disabled.

      This should undo anything that was done in onEnable(org.ngengine.components.ComponentManager, org.ngengine.runner.Runner, org.ngengine.store.DataStoreProvider, boolean, T) and reset the component state to allow future re-enabling.

      This method is called when the component is explicitly disabled or when one of its dependencies is disabled.

      If $

      invalid reference
      #onDetach
      is not implemented, this method should take care of cleaning up all resources to prevent leaks.

      It is always called before an enabled component is detached from the ComponentManager.

      Parameters:
      mng -
      runner -
      dataStore -
    • onNudge

      default void onNudge(ComponentManager mng, Runner runner, DataStoreProvider dataStore, boolean firstTime, T arg)
      Called when the component is scheduled to be enabled but cannot be due to unsatisfied dependencies.

      This method provides an opportunity for the component to take action when it's waiting on dependencies. Unlike onEnable(org.ngengine.components.ComponentManager, org.ngengine.runner.Runner, org.ngengine.store.DataStoreProvider, boolean, T), which is only called when all dependencies are satisfied, onNudge is called when the component manager attempts to enable the component but one or more dependencies are not yet enabled.

      This can be used to implement "smart" components that can enable their own dependencies or adapt to missing dependencies. For example, a GameMapComponent might depend on a GameTerrainComponent. When a user tries to enable the GameMapComponent, it could use this method to detect and enable its terrain dependency automatically.

      The method receives the same parameters as onEnable(org.ngengine.components.ComponentManager, org.ngengine.runner.Runner, org.ngengine.store.DataStoreProvider, boolean, T), allowing components to perform partial initialization or setup temporary alternatives while waiting for dependencies.

      Parameters:
      mng - the ComponentManager that manages this component
      runner - the Runner that provides execution context
      dataStore - the DataStoreProvider for accessing persistent data
      firstTime - whether this is the first attempt to enable this component
      arg - an optional argument passed when enabling this component