#pragma once #include "interest.h" #include "rndorgn.h" #include "resource.h" class DamageZone; class Subsystem; //~~~~~~~~~~~~~~~~~~~~~~~~~ Renderer support types ~~~~~~~~~~~~~~~~~~~~~~~~~ typedef Scalar RendererRate; extern const RendererRate DefaultRendererRate; typedef Scalar RendererComplexity; extern const RendererComplexity MaxRendererComplexity; extern const RendererComplexity MinRendererComplexity; typedef Scalar RendererFrameBudget; extern const RendererFrameBudget DefaultRendererFrameBudget; enum RendererPriority { LowRendererPriority = 0, DefaultRendererPriority, HighRendererPriority }; enum RendererStatus { InactiveRendererStatus, LoadingRendererStatus, RunningRendererStatus }; //########################################################################## //########################### Renderer ############################### //########################################################################## class Renderer__NotifyOfNewInterestingEntityMessage; class Renderer__NotifyOfBecomingUninterestingEntityMessage; class Renderer__StartEntityEffectMessage; class Renderer__StopAllEntityEffectsMessage; class Renderer__StartEntityAlarmMessage; class Renderer__StopEntityAlarmMessage; class Renderer: public Receiver { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Destruction, and Testing // public: ~Renderer(); Logical TestInstance() const; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Control and processing // public: // //----------------------------------------------------------------------- // LoadMission, Shutdown //----------------------------------------------------------------------- // void LoadMission(Mission *mission); void Shutdown(); // //----------------------------------------------------------------------- // LinkToEntity // // This method links the renderer to an entity. Overrides must call // the inherited method. //----------------------------------------------------------------------- // virtual void LinkToEntity(Entity *entity); // //----------------------------------------------------------------------- // UnlinkFromEntity //----------------------------------------------------------------------- // virtual void UnlinkFromEntity(); // //----------------------------------------------------------------------- // SetRendererStatusToRunning //----------------------------------------------------------------------- // void SetRendererStatusToRunning(); // //----------------------------------------------------------------------- // UpdateInterestOrigin //----------------------------------------------------------------------- // void UpdateInterestOrigin(Time target_render_time); // //----------------------------------------------------------------------- // Execute //----------------------------------------------------------------------- // void Execute(Time target_render_time, RendererComplexity complexity_update); virtual void ExecuteIdle(); virtual Logical ExecuteBackground(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Accessors // public: // //----------------------------------------------------------------------- // GetLinkedEntity //----------------------------------------------------------------------- // Entity* GetLinkedEntity(); // //----------------------------------------------------------------------- // GetRendererStatus //----------------------------------------------------------------------- // RendererStatus GetRendererStatus(); // //----------------------------------------------------------------------- // Misc //----------------------------------------------------------------------- // RendererComplexity GetCalibrationComplexity(); Time GetCalibrationFrameDuration(); RendererRate GetCalibrationRate(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Interest Manager support // public: // //----------------------------------------------------------------------- // NotifyOfNewInterestingEntity //----------------------------------------------------------------------- // virtual void NotifyOfNewInterestingEntity(Entity *) {} // //----------------------------------------------------------------------- // NotifyOfBecomingUninterestingEntity //----------------------------------------------------------------------- // virtual void NotifyOfBecomingUninterestingEntity(Entity *) {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Message Support // public: enum { NotifyOfNewInterestingEntityMessageID = Receiver::NextMessageID, NotifyOfBecomingUninterestingEntityMessageID, StartEntityEffectMessageID, StopAllEntityEffectsMessageID, StartEntityAlarmMessageID, StopEntityAlarmMessageID, NextMessageID }; typedef Renderer__NotifyOfNewInterestingEntityMessage NotifyOfNewInterestingEntityMessage; typedef Renderer__NotifyOfBecomingUninterestingEntityMessage NotifyOfBecomingUninterestingEntityMessage; typedef Renderer__StartEntityEffectMessage StartEntityEffectMessage; typedef Renderer__StopAllEntityEffectsMessage StopAllEntityEffectsMessage; typedef Renderer__StartEntityAlarmMessage StartEntityAlarmMessage; typedef Renderer__StopEntityAlarmMessage StopEntityAlarmMessage; static const HandlerEntry MessageHandlerEntries[]; //static MessageHandlerSet MessageHandlers; static MessageHandlerSet& GetMessageHandlers(); void NotifyOfNewInterestingEntityMessageHandler( NotifyOfNewInterestingEntityMessage *message ); void NotifyOfBecomingUninterestingEntityMessageHandler( NotifyOfBecomingUninterestingEntityMessage *message ); void StartEntityEffectMessageHandler( StartEntityEffectMessage *message ); void StopAllEntityEffectsMessageHandler( StopAllEntityEffectsMessage *message ); void StartEntityAlarmMessageHandler( StartEntityAlarmMessage *message ); void StopEntityAlarmMessageHandler( StopEntityAlarmMessage *message ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Shared Data Support // public: static Derivation *GetClassDerivations(); static SharedData DefaultData; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction // protected: // //----------------------------------------------------------------------- // Construction // // Where calibration_rate indicates the update rate, and // calibration_complexity indicates an arbitrary "maximum" complexity // level passed to the renderer. The renderer manager will dynamically // vary the value of complexity based on the actual frame rate that the // renderer is able to maintain (if the total system load exceeds // 100% of the maximum, each renderer's actual frame rate will drop // below the requested rate: the renderer manager will detect this and // lower the complexity value). The renderer manager will then // periodically invoke the renderer's execute function, passing it the // value indicated in complexity. //----------------------------------------------------------------------- // Renderer( RendererRate calibration_rate, RendererComplexity calibration_complexity, RendererPriority calibration_priority, InterestType interest_type, InterestDepth depth_calibration, ClassID class_ID=TrivialReceiverClassID, SharedData &virtual_data=DefaultData ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Protected accessors // protected: // //----------------------------------------------------------------------- // GetInterestOrigin //----------------------------------------------------------------------- // RendererOrigin* GetInterestOrigin(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Protected implementations // protected: Time mTargetRenderTime; // //----------------------------------------------------------------------- // Execute // // This method is called by the rendering manager to execute renderer // updates. Overrides must call the inherited method. //----------------------------------------------------------------------- // virtual void ExecuteImplementation( RendererComplexity complexity_update, RendererOrigin::InterestingEntityIterator *iterator ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private implementations // private: virtual void LoadMissionImplementation(Mission *mission); virtual void ShutdownImplementation(); virtual void StartEntityEffectImplementation( Entity *entity, DamageZone *damage_zone, ResourceDescription::ResourceID resource_ID ) {} virtual void StopAllEntityEffectsImplementation(Entity *entity) {} virtual void StartEntityAlarmImplementation( Entity *entity, Subsystem *subsystem, Enumeration condition, ResourceDescription::ResourceID resource_ID ) {} virtual void StopEntityAlarmImplementation( Entity *entity, Subsystem *subsystem, Enumeration condition ) {} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private data // private: // // Current running state of the renderer // RendererStatus rendererStatus; // // Renderer frame rate related valriables // RendererRate calibrationRate; Time calibrationFrameDuration, nextRenderTime; // // Renderer complexity, depth, and priority // control related variables // RendererComplexity calibrationComplexity; RendererPriority calibrationPriority; InterestType interestType; InterestDepth depthCalibration; RendererFrameBudget framePercentBudget; // // Sockets // SlotOf rendererOriginSocket; SlotOf entitySocket; }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Renderer inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~ inline Entity* Renderer::GetLinkedEntity() { Check(&entitySocket); return entitySocket.GetCurrent(); } inline RendererOrigin* Renderer::GetInterestOrigin() { Check(&rendererOriginSocket); return rendererOriginSocket.GetCurrent(); } inline RendererStatus Renderer::GetRendererStatus() { Check(this); return rendererStatus; } inline RendererComplexity Renderer::GetCalibrationComplexity() { Check(this); return calibrationComplexity; } inline Time Renderer::GetCalibrationFrameDuration() { Check(this); return calibrationFrameDuration; } inline RendererRate Renderer::GetCalibrationRate() { Check(this); return calibrationRate; } inline void Renderer::ExecuteIdle() { Check(this); return; } inline Logical Renderer::ExecuteBackground() { Check(this); return False; } //########################################################################## //######################## RendererManager ########################### //########################################################################## class RendererManager: public Receiver { friend class Renderer; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction, Destruction. Testing // public: RendererManager(); ~RendererManager(); Logical TestInstance() const; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Control, and processing // public: // //----------------------------------------------------------------------- // UpdateInterestOrigins // // Called by the application to update the renderers interest origins // before the interest manager performs its execute method. //----------------------------------------------------------------------- // void UpdateInterestOrigins(Time target_render_time); // //----------------------------------------------------------------------- // Execute // // Perform renderer management functions //----------------------------------------------------------------------- // void Execute( Time target_render_time, Time target_frame_duration, Time actual_frame_duration ); // //----------------------------------------------------------------------- // ExecuteIdle // // Allow renderers to perform functions during idle (WaitingForEgg) //----------------------------------------------------------------------- // void ExecuteIdle(); // //----------------------------------------------------------------------- // AreRenderersRunning //----------------------------------------------------------------------- // Logical AreRenderersRunning(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Effects and Alarms // public: void StartEntityEffect( Entity *entity, DamageZone *damage_zone, ResourceDescription::ResourceID resource_ID ); void StopAllEntityEffects(Entity *entity); void StartEntityAlarm( Entity *entity, Subsystem *subsystem, Enumeration condition, ResourceDescription::ResourceID resource_ID ); void StopEntityAlarm( Entity *entity, Subsystem *subsystem, Enumeration condition ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private methods // private: void StartRenderer(Renderer *renderer); void StopRenderer(Renderer *renderer); void RendererManager::PostRendererEvent( Entity *entity, Receiver::Message *message ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private data // private: SChainOf renderers; }; //~~~~~~~~~~~~~~ Renderer__NotifyOfNewInterestingEntityMessage ~~~~~~~~~~~~~ class Renderer__NotifyOfNewInterestingEntityMessage: public Receiver::Message { public: Renderer__NotifyOfNewInterestingEntityMessage( Entity *interesting_entity ); Entity* GetInterestingEntity(); private: EntityID entityID; }; //~~~~~~~~~~ Renderer__NotifyOfBecomingUninterestingEntityMessage ~~~~~~~~~~ class Renderer__NotifyOfBecomingUninterestingEntityMessage: public Receiver::Message { public: Renderer__NotifyOfBecomingUninterestingEntityMessage( Entity *uninteresting_entity ); Entity* GetUninterestingEntity() {return uninterestingEntity;} private: Entity *uninterestingEntity; }; //~~~~~~~~~~~~~~~~~~~~~~~ Renderer__EntityMessage ~~~~~~~~~~~~~~~~~~~~~~~~~~ class Renderer__EntityMessage: public Receiver::Message { public: Renderer__EntityMessage( Receiver::MessageID message_ID, size_t message_size, Entity *entity ); Entity* GetEntity(); private: EntityID entityID; }; //~~~~~~~~~~~~~~~~~~ Renderer__StartEntityEffectMessage ~~~~~~~~~~~~~~~~~~~~ class Renderer__StartEntityEffectMessage: public Renderer__EntityMessage { public: Renderer__StartEntityEffectMessage( Entity *entity, DamageZone *damage_zone, ResourceDescription::ResourceID resource_ID ); DamageZone* GetDamageZone() {return damageZone;} ResourceDescription::ResourceID GetResourceID() {return resourceID;} private: DamageZone *damageZone; ResourceDescription::ResourceID resourceID; }; //~~~~~~~~~~~~~~~~~~ Renderer__StopAllEntityEffectsMessage ~~~~~~~~~~~~~~~~~ class Renderer__StopAllEntityEffectsMessage: public Renderer__EntityMessage { public: Renderer__StopAllEntityEffectsMessage(Entity *entity); }; //~~~~~~~~~~~~~~~~~~ Renderer__StartEntityAlarmMessage ~~~~~~~~~~~~~~~~~~~~~ class Renderer__StartEntityAlarmMessage: public Renderer__EntityMessage { public: Renderer__StartEntityAlarmMessage( Entity *entity, Subsystem *alarm_subsystem, Enumeration alarm_condition, ResourceDescription::ResourceID resource_ID ); Subsystem* GetSubsystem() {return subsystem;} Enumeration GetCondition() {return condition;} ResourceDescription::ResourceID GetResourceID() {return resourceID;} private: Subsystem *subsystem; Enumeration condition; ResourceDescription::ResourceID resourceID; }; //~~~~~~~~~~~~~~~~~~ Renderer__StopEntityAlarmMessage ~~~~~~~~~~~~~~~~~~~~~~ class Renderer__StopEntityAlarmMessage: public Renderer__EntityMessage { public: Renderer__StopEntityAlarmMessage( Entity *entity, Subsystem *alarm_subsystem, Enumeration alarm_condition ); Subsystem* GetSubsystem() {return subsystem;} Enumeration GetCondition() {return condition;} private: Subsystem *subsystem; Enumeration condition; }; //~~~~~~~~~~~~~~~~~~~~~~ RendererManager inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~ inline void RendererManager::StartEntityEffect( Entity *entity, DamageZone *damage_zone, ResourceDescription::ResourceID resource_ID ) { Renderer::StartEntityEffectMessage message(entity, damage_zone, resource_ID); PostRendererEvent(entity, &message); } inline void RendererManager::StopAllEntityEffects(Entity *entity) { Renderer::StopAllEntityEffectsMessage message(entity); PostRendererEvent(entity, &message); } inline void RendererManager::StartEntityAlarm( Entity *entity, Subsystem *alarm_subsystem, Enumeration alarm_condition, ResourceDescription::ResourceID resource_ID ) { Renderer::StartEntityAlarmMessage message(entity, alarm_subsystem, alarm_condition, resource_ID); PostRendererEvent(entity, &message); } inline void RendererManager::StopEntityAlarm( Entity *entity, Subsystem *alarm_subsystem, Enumeration alarm_condition ) { Renderer::StopEntityAlarmMessage message(entity, alarm_subsystem, alarm_condition); PostRendererEvent(entity, &message); }