Sample: Cabin_Comfort.cpp
Cabin_Comfort.cpp |
| //Copyright (c) Microsoft Corporation. All rights reserved. // // Cabin_Comfort.cpp // #define _CRT_RAND_S #include "../inc/gauges.h" #pragma once GAUGE_CALLBACK gauge_callback; // Note: The items in the property table correspond to the indices that // will be returned in the Get/Set Property functions struct PROPERTY_TABLE { PCSTRINGZ szPropertyName; PCSTRINGZ szUnitsName; ENUM units; }; // // PanelCallback is an abstract base class that can be overrided. Implementors // should override the functions CreateAircraftCallback(UINT32 ContainerId) as // well as GetPropertyTable. class PanelCallback : public IPanelCCallback { DECLARE_PANEL_CALLBACK_REFCOUNT(PanelCallback); public: PanelCallback(); // ******* IPanelCCallback Methods ***************** IPanelCCallback* QueryInterface(PCSTRINGZ pszInterface); UINT32 GetVersion(); bool ConvertStringToProperty (PCSTRINGZ keyword, SINT32* pID); bool ConvertPropertyToString (SINT32 id, PPCSTRINGZ pKeyword); bool GetPropertyUnits (SINT32 id, ENUM* pEnum); protected: // ******** PanelCallback Methods ****************** virtual const PROPERTY_TABLE *GetPropertyTable(UINT &uLength;) = 0; }; // // AircraftCallback is an abstract base class that can be overrided. Implementors // should override the function CreateGaugeCCallback(UINT32 ContainerId) class AircraftCallback : public IAircraftCCallback { DECLARE_PANEL_CALLBACK_REFCOUNT(AircraftCallback); public: AircraftCallback(UINT32 containerId); // ******* IAircraftCCallback Methods ************* IAircraftCCallback* QueryInterface(PCSTRINGZ pszInterface); void Update(); protected: UINT32 GetContainerId() const; private: UINT32 m_containerId; }; // End of paneldefs.h DEFINE_PANEL_CALLBACK_REFCOUNT(PanelCallback); PanelCallback::PanelCallback() : m_RefCount(1) { } IPanelCCallback* PanelCallback::QueryInterface(PCSTRINGZ pszInterface) { return NULL; } UINT32 PanelCallback::GetVersion() { return 1; } bool PanelCallback::ConvertStringToProperty (PCSTRINGZ keyword, SINT32* pID) { if(!keyword) { return false; } if(!pID) { return false; } UINT uNumProperties; const PROPERTY_TABLE *parPropertyTable = GetPropertyTable(uNumProperties); for(UINT i = 0; i < uNumProperties; i++) { if(_stricmp(parPropertyTable[i].szPropertyName, keyword) == 0) { *pID = i; return true; } } return false; } bool PanelCallback::ConvertPropertyToString (SINT32 id, PPCSTRINGZ pKeyword) { if(!pKeyword) { return false; } UINT uNumProperties; const PROPERTY_TABLE *parPropertyTable = GetPropertyTable(uNumProperties); if(id < 0 || id >= (SINT32)uNumProperties) { return false; } *pKeyword = parPropertyTable[id].szPropertyName; return true; } bool PanelCallback::GetPropertyUnits (SINT32 id, ENUM* pEnum) { if(!pEnum) { return false; } UINT uNumProperties; const PROPERTY_TABLE *parPropertyTable = GetPropertyTable(uNumProperties); if(id < 0 || id >= (SINT32)uNumProperties) { return false; } *pEnum = parPropertyTable[id].units; return true; } DEFINE_PANEL_CALLBACK_REFCOUNT(AircraftCallback); AircraftCallback::AircraftCallback(UINT32 containerId) : m_containerId(containerId), m_RefCount(1) { } IAircraftCCallback* AircraftCallback::QueryInterface(PCSTRINGZ pszInterface) { return NULL; } void AircraftCallback::Update() { } UINT32 AircraftCallback::GetContainerId() const { return m_containerId; } //---------------------------------------------------------------------------- // Static Variables //---------------------------------------------------------------------------- static const char CABIN_CALLBACK_NAME[] = "CABIN"; #define ROOM_TEMPERATURE 25 // degrees celcius static PROPERTY_TABLE CABIN_PROPERTY_TABLE[] = { { "CabinTemperature", "Celcius", UNITS_UNKNOWN}, { "BankAngle", "Degrees", UNITS_UNKNOWN}, { "FlightAttendants", "String", UNITS_STRING}, { "Restroom", "String", UNITS_STRING}, { "PassengerComfort", "Number", UNITS_UNKNOWN}, }; // Enum that contains the properties enum CABIN_VAR { CABIN_VAR_CABIN_TEMPERATURE, CABIN_VAR_BANK_ANGLE, CABIN_VAR_FLIGHT_ATTENDANTS, CABIN_VAR_RESTROOM, CABIN_VAR_PASSENGER_COMFORT, }; enum FLIGHT_ATTENDANTS { PASSIVE = 0, ACTIVE, SERVING, }; struct stringValuePair { char* string; int value; }; const struct stringValuePair attendantStrings[3] = { {"Passive", -10}, {"Active", 10}, {"Serving", 15} }; enum RESTROOM { VACANT = 0, ENGAGED }; const struct stringValuePair restroomStrings[2] = { {"Vacant", 5}, {"Engaged", -5} }; // // Class that implements IGaugeCCallback // class CABINGaugeCallback : public IGaugeCCallback { DECLARE_PANEL_CALLBACK_REFCOUNT(CABINGaugeCallback); // Declare member variables representing cabin state float cabin_temperature; FLIGHT_ATTENDANTS flight_attendant_state; RESTROOM restroom_state; public: CABINGaugeCallback(UINT32 containerId); // ************* IGaugeCCallback Methods *************** IGaugeCCallback* QueryInterface(PCSTRINGZ pszInterface); void Update(); bool GetPropertyValue (SINT32 id, FLOAT64* pValue); bool GetPropertyValue (SINT32 id, PCSTRINGZ* pszValue); bool SetPropertyValue (SINT32 id, FLOAT64 value); bool SetPropertyValue (SINT32 id, PCSTRINGZ szValue); IGaugeCDrawable* CreateGaugeCDrawable(SINT32 id, const IGaugeCDrawableCreateParameters* pParameters); float getCabinTemperature() { return cabin_temperature; } FLIGHT_ATTENDANTS getFlightAttendantState() { return flight_attendant_state; } RESTROOM getRestroomState() { return restroom_state; } void setCabinTemperature(float temp) { cabin_temperature = temp; } void setFlightAttendantState(FLIGHT_ATTENDANTS state) { flight_attendant_state = state; } void setRestroomState(RESTROOM state) { restroom_state = state; } private: UINT32 m_containerId; }; DEFINE_PANEL_CALLBACK_REFCOUNT(CABINGaugeCallback) CABINGaugeCallback::CABINGaugeCallback(UINT32 containerId) : m_RefCount(1), m_containerId(containerId) { // Initialize aircraft variables cabin_temperature = ROOM_TEMPERATURE; flight_attendant_state = PASSIVE; restroom_state = VACANT; } IGaugeCCallback* CABINGaugeCallback::QueryInterface(PCSTRINGZ pszInterface) { return NULL; } // // The Update functions is called on a 18Hz cycle // void CABINGaugeCallback::Update() { unsigned int random; // Inane logic to update the attendants and restroom settings if (rand_s(&random;) == 0) { if (random < UINT_MAX/20) { if (rand_s(&random;) == 0) { if (random < UINT_MAX/6) flight_attendant_state = SERVING; else if (random < UINT_MAX/3) flight_attendant_state = ACTIVE; else if (random < UINT_MAX/2) flight_attendant_state = PASSIVE; } if (rand_s(&random;) == 0) { if (random < UINT_MAX/4) restroom_state = VACANT; else if (random < UINT_MAX/2) restroom_state = ENGAGED; } } } } // // Getting float/numeric values // bool CABINGaugeCallback::GetPropertyValue (SINT32 id, FLOAT64* pValue) { if(!pValue) { return false; } *pValue = 1.0; // Start with a reasonable default CABIN_VAR eCABINVar = (CABIN_VAR)id; switch(eCABINVar) { case CABIN_VAR_CABIN_TEMPERATURE: *pValue = getCabinTemperature(); break; case CABIN_VAR_BANK_ANGLE: // Get the variable name from Simulation Variables, not Token Variables, for aircraft_varget *pValue = abs( aircraft_varget( get_aircraft_var_enum("PLANE BANK DEGREES"), get_units_enum("degrees"), 0) ); break; case CABIN_VAR_PASSENGER_COMFORT: // Lame equation to calculate passenger comfort, in range 0 to 100 *pValue = - abs( aircraft_varget( get_aircraft_var_enum("PLANE BANK DEGREES"), get_units_enum("degrees"), 0) ); *pValue += 75 - abs(ROOM_TEMPERATURE - getCabinTemperature()) + attendantStrings[ (int) getFlightAttendantState() ].value + restroomStrings[ (int) getRestroomState() ].value; if (*pValue > 100) *pValue = 100; if (*pValue < 0) *pValue = 0; break; default: return false; } return true; } // // Getting string property values // bool CABINGaugeCallback::GetPropertyValue (SINT32 id, PCSTRINGZ* pszValue) { if(!pszValue) { return false; } *pszValue = "null"; // Return a reasonable default CABIN_VAR eCABINVar = (CABIN_VAR)id; switch(eCABINVar) { case CABIN_VAR_FLIGHT_ATTENDANTS: *pszValue = attendantStrings[ (int) getFlightAttendantState() ].string; break; case CABIN_VAR_RESTROOM: *pszValue = restroomStrings[ (int) getRestroomState() ].string; break; default: return false; } return true; } // // Setting float/numeric values // bool CABINGaugeCallback::SetPropertyValue (SINT32 id, FLOAT64 value) { CABIN_VAR eCABINVar = (CABIN_VAR)id; switch(eCABINVar) { case CABIN_VAR_CABIN_TEMPERATURE: setCabinTemperature(value); break; default: return false; } return true; } // // Setting string values // bool CABINGaugeCallback::SetPropertyValue (SINT32 id, PCSTRINGZ szValue) { return false; // String properties not permitted to be set } IGaugeCDrawable* CABINGaugeCallback::CreateGaugeCDrawable(SINT32 id, const IGaugeCDrawableCreateParameters* pParameters) { return NULL; // No implementation of this necessary } // // AircraftCallback Override // class CABINAircraftCallback : public AircraftCallback { private: public: CABINAircraftCallback(UINT32 ContainerID): AircraftCallback(ContainerID) {} IGaugeCCallback* CreateGaugeCCallback () { return new CABINGaugeCallback(GetContainerId()); } }; // // PanelCallback Override // class CABINPanelCallback : public PanelCallback { public: CABINPanelCallback::CABINPanelCallback() { // init property table for (int n = 0; n < 5; n++) { if (ImportTable.PANELSentry.fnptr != NULL && CABIN_PROPERTY_TABLE[n].units == UNITS_UNKNOWN) { CABIN_PROPERTY_TABLE[n].units = get_units_enum ( CABIN_PROPERTY_TABLE[n].szUnitsName ); } } } IAircraftCCallback* CreateAircraftCCallback (UINT32 ContainerID) { return new CABINAircraftCallback(ContainerID); } protected: const PROPERTY_TABLE *GetPropertyTable(UINT &uLength;) { uLength = LENGTHOF(CABIN_PROPERTY_TABLE); return CABIN_PROPERTY_TABLE; } }; void CABINPanelCallbackInit() { CABINPanelCallback *pPanelCallback = new CABINPanelCallback(); if(pPanelCallback) { bool b = panel_register_c_callback(CABIN_CALLBACK_NAME, pPanelCallback); pPanelCallback->Release(); } } void CABINPanelCallbackDeInit() { panel_register_c_callback(CABIN_CALLBACK_NAME, NULL); } // The Panels pointer will get filled in during the loading process // if this DLL is listed in DLL.XML PPANELS Panels = NULL; GAUGESIMPORT ImportTable = { { 0x0000000F, (PPANELS)NULL }, { 0x00000000, NULL } }; void FSAPI module_init(void) { if (NULL != Panels) { ImportTable.PANELSentry.fnptr = (PPANELS)Panels; CABINPanelCallbackInit(); } } void FSAPI module_deinit(void){ CABINPanelCallbackDeInit(); } BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) { return TRUE; } // This is the module's export table. GAUGESLINKAGE Linkage = { 0x00000013, module_init, module_deinit, 0, 0, FS9LINK_VERSION, { 0 } }; // // end of cabin_comfort.cpp // |
Show: