using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; namespace Robust.Shared.GameObjects { /// /// Used by to determine whether a component is available. /// This distinction is important because prototypes are shared across client and server, but the two might have different components. /// /// public enum ComponentAvailability : byte { /// /// The component is available and can be instantiated. /// Available, /// /// The component is not available, but should be ignored (prevent warnings for missing components). /// Ignore, /// /// The component is unknown entirely. This may warrant a warning or error. /// Unknown } /// /// Handles the registration and spawning of components. /// /// ///

/// When referring to component names, this is the name the component has been registered as, /// and what's used in prototypes. However, most commonly the type is referred through by an interface. ///

///

/// Before a component can be spawned, it must be registered so things such as name, networking ID, type, etc... /// are known to the factory. /// Components are registered into a registry. /// The relevant methods for writing to this registry are . /// The data is exposed for reading through and its overloads. /// This data is returned in the form of a , which represents one component's registration. ///

///
/// /// public interface IComponentFactory { event Action ComponentAdded; event Action<(IComponentRegistration, Type)> ComponentReferenceAdded; event Action ComponentIgnoreAdded; /// /// All IComponent types that are currently registered to this factory. /// IEnumerable AllRegisteredTypes { get; } /// /// The subset of all registered components that are networked, so that they can be /// referenced between the client and the server. /// /// /// This will be null if the network Ids have not been generated yet. /// /// IReadOnlyList? NetworkedComponents { get; } /// /// Get whether a component is available right now. /// /// The name of the component to check. /// Whether or not to ignore casing on /// The availability of the component. ComponentAvailability GetComponentAvailability(string componentName, bool ignoreCase = false); /// /// Registers a component class with the factory. /// /// If the component already exists, will this replace it? void RegisterClass(bool overwrite = false) where T : IComponent, new(); /// /// Registers a component name as being ignored. /// /// The name to be ignored. /// Whether to overrde existing settings instead of throwing an exception in the case of duplicates. void RegisterIgnore(string name, bool overwrite = false); /// /// Gets a new component instantiated of the specified type. /// /// type of component to make /// A Component /// /// Thrown if no component of type is registered. /// IComponent GetComponent(Type componentType); /// /// Gets a new component instantiated of the specified type. /// /// The type of component to make. /// A Component /// /// Thrown if no component of type is registered. /// T GetComponent() where T : IComponent, new(); /// /// Gets a new component instantiated of the specified . /// /// name of component to make /// Whether or not to ignore casing on /// A Component /// /// Thrown if no component exists with the given name . /// IComponent GetComponent(string componentName, bool ignoreCase = false); /// /// Gets a new component instantiated of the specified network ID. /// /// net id of component to make /// A Component /// /// Thrown if no component exists with the given id . /// IComponent GetComponent(ushort netId); /// /// Gets the name of a component, throwing an exception if it does not exist. /// /// The type of the component /// The registered name of the component /// /// Thrown if no component exists with the given type . /// string GetComponentName(Type componentType); /// /// Gets the registration belonging to a component, throwing an exception if it does not exist. /// /// The name of the component. /// Whether or not to ignore casing on /// /// Thrown if no component exists with the given name . /// IComponentRegistration GetRegistration(string componentName, bool ignoreCase = false); /// /// Gets the registration belonging to a component, throwing an exception if it does not exist. /// /// The type of the component to lookup. /// /// Thrown if no component exists of type . /// IComponentRegistration GetRegistration(Type reference); /// /// Gets the registration belonging to a component, throwing an exception if it does not exist. /// /// A type referencing the component. /// /// Thrown if no component of type exists. /// IComponentRegistration GetRegistration() where T : IComponent, new(); /// /// Gets the registration belonging to a component, throwing an /// exception if it does not exist. /// /// The network ID corresponding to the component. /// /// /// Thrown if no component with id exists. /// IComponentRegistration GetRegistration(ushort netID); /// /// Gets the registration of a component, throwing an exception if /// it does not exist. /// /// An instance of the component. /// /// /// Thrown if no registration exists for component . /// IComponentRegistration GetRegistration(IComponent component); /// /// Tries to get the registration belonging to a component. /// /// The name of the component. /// The registration if found, null otherwise. /// Whether or not to ignore casing on /// true it found, false otherwise. bool TryGetRegistration(string componentName, [NotNullWhen(true)] out IComponentRegistration? registration, bool ignoreCase = false); /// /// Tries to get the registration belonging to a component. /// /// A reference corresponding to the component to look up. /// The registration if found, null otherwise. /// true it found, false otherwise. bool TryGetRegistration(Type reference, [NotNullWhen(true)] out IComponentRegistration? registration); /// /// Tries to get the registration belonging to a component. /// /// A type referencing the component. /// The registration if found, null otherwise. /// true it found, false otherwise. bool TryGetRegistration([NotNullWhen(true)] out IComponentRegistration? registration) where T : IComponent, new(); /// /// Tries to get the registration belonging to a component. /// /// The network ID corresponding to the component. /// The registration if found, null otherwise. /// true it found, false otherwise. bool TryGetRegistration(ushort netID, [NotNullWhen(true)] out IComponentRegistration? registration); /// /// Tries to get the registration of a component. /// /// An instance of the component. /// The registration if found, null otherwise. /// true it found, false otherwise. bool TryGetRegistration(IComponent component, [NotNullWhen(true)] out IComponentRegistration? registration); /// /// Automatically create registrations for all components with a /// void DoAutoRegistrations(); IEnumerable GetAllRefTypes(); void GenerateNetIds(); } /// /// Represents a component registered into a . /// /// /// public interface IComponentRegistration { /// /// The name of the component. /// This is used as the type field in the component declarations if entity prototypes. /// /// string Name { get; } /// /// ID used to reference the component type across the network. /// If null, no network synchronization will be available for this component. /// /// ushort? NetID { get; } /// /// The type that will be instantiated if this component is created. /// Type Type { get; } /// /// A list of type references that can be used to get a reference to an instance of this component, /// for methods like GetComponent. /// These are not unique and can overlap with other components. /// IReadOnlyList References { get; } } }