#include #pragma hdrstop #if !defined(APPMGR_HPP) # include #endif ApplicationManager::ApplicationManager(Scalar frame_rate): Node(ApplicationManagerClassID), runningApplications(this) { frameRate = frame_rate; frameDuration = 1.0f/frameRate; Check_Fpu(); } ApplicationManager::~ApplicationManager() { } void ApplicationManager::StartApplication(Application *new_app) { Check(this); Check(new_app); runningApplications.Add(new_app); application = new_app; new_app->Initialize(); } // //############################################################################# // RunMissions //############################################################################# // void ApplicationManager::RunMissions() { Check(this); SChainIteratorOf current_application(runningApplications); Start_Of_Frame: current_application.First(); Time end_of_frame = Now(); end_of_frame += frameDuration; #if defined(LAB_ONLY) int bad_count = 0; #endif if (frameDuration > 0.1f) { Fail("frameDuration has grown!\n"); } // //---------------------------------- // Run all relevant foreground loops //---------------------------------- // while ((application = current_application.ReadAndNext()) != NULL) { Check(application); if (!application->ExecuteForeground(end_of_frame, frameDuration)) { if (!application->Shutdown()) { application->Terminate(); Unregister_Object(application); delete application; } } } // //----------------------------------------------------------------------- // Run all relevant background loops until it is time for the next frame. // If no applications remain, exit the whole loop //----------------------------------------------------------------------- // current_application.First(); application = current_application.GetCurrent(); if (!application) { return; } // //------------------------------------------------------------------ // Give each application a chance to do at least one background task //------------------------------------------------------------------ // Background_Loop: do { Check(application); application->ExecuteBackgroundTask(); // // Move to the next application // current_application.Next(); application = current_application.GetCurrent(); } while (application); // //--------------------------------------------------------------------- // If time remains before the next frame is due, do another pass on the // background tasks //--------------------------------------------------------------------- // Time t2 = Now(); if (t2 < end_of_frame) { current_application.First(); application = current_application.GetCurrent(); #if defined(LAB_ONLY) if (end_of_frame - t2 > 0.1f) { DEBUG_STREAM << t2 << ',' << end_of_frame << endl; if (++bad_count == 1000) { Fail("End-of-frame cannot be correctly calculated!"); } } #endif goto Background_Loop; } goto Start_Of_Frame; }