newspeoplefor developersdocumentationdownloads

app.cc

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 //  application/app.cc
00003 //  (C) 2003 RadonLabs GmbH
00004 //------------------------------------------------------------------------------
00005 #include "application/app.h"
00006 #include "foundation/factory.h"
00007 #include "kernel/nfileserver2.h"
00008 #include "gui/nguiserver.h"
00009 #include "application/statehandler.h"
00010 #include "managers/entitymanager.h"
00011 #include "managers/envquerymanager.h"
00012 #include "managers/factorymanager.h"
00013 #include "managers/focusmanager.h"
00014 #include "managers/savegamemanager.h"
00015 #include "managers/setupmanager.h"
00016 #include "managers/timemanager.h"
00017 #include "loader/entityloader.h"
00018 #include "loader/environmentloader.h"
00019 
00020 nNebulaUsePackage(ui);
00021 
00022 namespace Application
00023 {
00024 App* App::Singleton = 0;
00025 
00026 //------------------------------------------------------------------------------
00029 App::App() :
00030     foundationServer(0),
00031     isOpen(false),
00032     isRunning(false),
00033     isPaused(false),
00034     time(0.0),
00035     stateTime(0.0),
00036     frameTime(0.0),
00037     lastRealTime(0.0),
00038     timeFactor(1.0f),
00039     pauseTime(0.0)
00040 {
00041     n_assert(0 == Singleton);
00042     Singleton = this;
00043 }
00044 
00045 //------------------------------------------------------------------------------
00048 App::~App()
00049 {
00050     n_assert(!this->isOpen);
00051     n_assert(!this->isRunning);
00052     n_assert(Singleton);
00053     Singleton = 0;
00054 }
00055 
00056 //------------------------------------------------------------------------------
00060 nString
00061 App::GetAppName() const
00062 {
00063     return "Mangalore";
00064 }
00065 
00066 //------------------------------------------------------------------------------
00070 nString
00071 App::GetAppVersion() const
00072 {
00073     return "1.0";
00074 }
00075 
00076 //------------------------------------------------------------------------------
00080 nString
00081 App::GetVendorName() const
00082 {
00083     return "Radon Labs GmbH";
00084 }
00085 
00086 //------------------------------------------------------------------------------
00092 bool
00093 App::GetForceFullscreen() const
00094 {
00095     return false;
00096 }
00097 
00098 //------------------------------------------------------------------------------
00105 bool
00106 App::DoStartupCheck()
00107 {
00108     // check if app is already running
00109     // FIXME: LOCALIZE!
00110     nString errorMsgAlreadyRunning;
00111     errorMsgAlreadyRunning.Format("Cannot start '%s' because it is already\n"
00112                                   "running in another desktop session!", this->GetAppName().Get());
00113     if (this->startupChecker.CheckAlreadyRunning(this->GetVendorName(),
00114                                                  this->GetAppName(),
00115                                                  this->displayMode.GetWindowTitle(),
00116                                                  this->GetAppName(),
00117                                                  errorMsgAlreadyRunning))
00118     {
00119         // application is already running
00120         return false;
00121     }
00122 
00123 #ifdef __WIN32__
00124     // check if D3D can be initialized
00125     // FIXME: LOCALIZE!
00126     nString errorMsgD3D("Cannot initialize Direct3D!");
00127     if (!this->startupChecker.CheckDirect3D(this->GetAppName(), errorMsgD3D))
00128     {
00129         // could not initialize Direct3D
00130         return false;
00131     }
00132 
00133     // check if DirectSound can be initialized
00134     nString errorMsgDS("Cannot initialize DirectSound!");
00135     if (!this->startupChecker.CheckDirectSound(this->GetAppName(), errorMsgDS))
00136     {
00137         // could not initialize DirectSound
00138         return false;
00139     }
00140 #endif
00141 
00142     // all ok
00143     return true;
00144 }
00145 
00146 //------------------------------------------------------------------------------
00153 void
00154 App::SetupFromDefaults()
00155 {
00156     // setup display mode
00157     nDisplayMode2 mode;
00158     nString windowTitle = this->GetVendorName() + " - " + this->GetAppName() + " - " + this->GetAppVersion();
00159     mode.SetWindowTitle(windowTitle.Get());
00160     mode.SetXPos(0);
00161     mode.SetYPos(0);
00162     mode.SetWidth(1024);
00163     mode.SetHeight(768);
00164     mode.SetType(nDisplayMode2::Windowed);
00165     mode.SetVerticalSync(false);
00166     mode.SetDialogBoxMode(true);
00167     mode.SetIcon("Icon");
00168     this->SetDisplayMode(mode);
00169 }
00170 
00171 //------------------------------------------------------------------------------
00177 void
00178 App::SetupFromProfile()
00179 {
00180     // FIXME
00181 }
00182 
00183 //------------------------------------------------------------------------------
00195 void
00196 App::SetupFromCmdLineArgs()
00197 {
00198     // setup optional startup savegame or level paths
00199     this->SetStartupSavegame(this->cmdLineArgs.GetStringArg("-loadgame", 0));
00200     this->SetStartupLevel(this->cmdLineArgs.GetStringArg("-level", 0));
00201 
00202     // setup display mode
00203     nDisplayMode2 mode = this->GetDisplayMode();
00204     if (this->cmdLineArgs.HasArg("-fullscreen"))
00205     {
00206         if (this->cmdLineArgs.GetBoolArg("-fullscreen") | this->GetForceFullscreen())
00207         {
00208             mode.SetType(nDisplayMode2::Fullscreen);
00209         }
00210         else
00211         {
00212             mode.SetType(nDisplayMode2::Windowed);
00213         }
00214     }
00215     mode.SetXPos(this->cmdLineArgs.GetIntArg("-x", mode.GetXPos()));
00216     mode.SetYPos(this->cmdLineArgs.GetIntArg("-y", mode.GetYPos()));
00217     mode.SetWidth(this->cmdLineArgs.GetIntArg("-w", mode.GetWidth()));
00218     mode.SetHeight(this->cmdLineArgs.GetIntArg("-h", mode.GetHeight()));
00219     mode.SetAntiAliasSamples(this->cmdLineArgs.GetIntArg("-aa", mode.GetAntiAliasSamples()));
00220     this->SetDisplayMode(mode);
00221 
00222     // set project directory override
00223     nString projDirArg = this->cmdLineArgs.GetStringArg("-projdir", 0);
00224     if (projDirArg.IsValid())
00225     {
00226         this->SetProjectDirectory(projDirArg);
00227     }
00228 
00229     // set feature set override
00230     nString featureSetArg = this->cmdLineArgs.GetStringArg("-featureset", 0);
00231     if (featureSetArg.IsValid())
00232     {
00233         this->SetFeatureSet(featureSetArg);
00234     }
00235 
00236     // set render path override
00237     nString renderPathArg = this->cmdLineArgs.GetStringArg("-renderpath", 0);
00238     if (renderPathArg.IsValid())
00239     {
00240         this->SetRenderPath(renderPathArg);
00241     }
00242 }
00243 
00244 //------------------------------------------------------------------------------
00250 void
00251 App::SetupGameSubsystem()
00252 {
00253     this->gameServer = Game::Server::Create();
00254     this->gameServer->Open();
00255 
00256     Ptr<Managers::EntityManager> entityManager = Managers::EntityManager::Create();
00257     Ptr<Managers::EnvQueryManager> envQueryManager = Managers::EnvQueryManager::Create();
00258     Ptr<Managers::FocusManager> focusManager = Managers::FocusManager::Create();
00259     Ptr<Managers::SaveGameManager> saveGameManager = Managers::SaveGameManager::Create();
00260     Ptr<Managers::SetupManager> setupManager = Managers::SetupManager::Create();
00261     Ptr<Managers::TimeManager> timeManager = Managers::TimeManager::Create();
00262     Ptr<Managers::FactoryManager> factoryManager = Managers::FactoryManager::Create();
00263 
00264     this->gameServer->AttachManager(entityManager);
00265     this->gameServer->AttachManager(envQueryManager);
00266     this->gameServer->AttachManager(focusManager);
00267     this->gameServer->AttachManager(saveGameManager);
00268     this->gameServer->AttachManager(setupManager);
00269     this->gameServer->AttachManager(timeManager);
00270     this->gameServer->AttachManager(factoryManager);
00271 }
00272 
00273 //------------------------------------------------------------------------------
00277 void
00278 App::CleanupGameSubsystem()
00279 {
00280     this->gameServer->Close();
00281     this->gameServer = 0;
00282 }
00283 
00284 //------------------------------------------------------------------------------
00289 void
00290 App::SetupSubsystems()
00291 {
00292     // setup the foundation subsystem
00293     this->foundationServer->SetProjectDir(this->projDir);
00294     this->foundationServer->Open();
00295 
00296     // setup the script subsystem
00297     this->scriptServer = Script::Server::Create();
00298     this->scriptServer->Open();
00299 
00300     // setup the message subsystem
00301     this->messageServer = Message::Server::Create();
00302     this->messageServer->Open();
00303 
00304     // setup the db subsystem
00305     this->dbServer = Db::Server::Create();
00306 
00307     // setup the physics subsystem
00308     this->physicsServer = Physics::Server::Create();
00309     this->physicsServer->Open();
00310 
00311     // setup the graphics subsystem
00312     this->graphicsServer = Graphics::Server::Create();
00313     this->graphicsServer->SetDisplayMode(this->displayMode);
00314     this->graphicsServer->SetRenderPath(this->renderPath);
00315     this->graphicsServer->SetFeatureSet(this->featureSet);
00316     this->graphicsServer->Open();
00317 
00318     // setup the input subsystem
00319     this->inputServer = Input::Server::Create();
00320     this->inputServer->Open();
00321 
00322     // setup the audio subsystem
00323     this->audioServer = Audio::Server::Create();
00324     this->audioServer->Open();
00325     if (nFileServer2::Instance()->FileExists("proj:data/tables/sound.xml"))
00326     {
00327         this->audioServer->OpenWaveBank("proj:data/tables/sound.xml");
00328     }
00329     else
00330     {
00331         n_printf("Warning: proj:data/tables/sound.xml doesn't exist!\n");
00332     }
00333 
00334     // setup the vfx subsystem
00335     this->vfxServer = VFX::Server::Create();
00336     this->vfxServer->Open();
00337     if (nFileServer2::Instance()->FileExists("proj:data/tables/effects.xml"))
00338     {
00339         this->vfxServer->OpenEffectBank("proj:data/tables/effects.xml");
00340     }
00341     else
00342     {
00343         n_printf("Warning: proj:data/tables/effects.xml doesn't exist!\n");
00344     }
00345 
00346     // setup the navigation subsystem
00347     this->navigationServer = Navigation::Server::Create();
00348 
00349     // setup the loader subsystem
00350     this->loaderServer = Loader::Server::Create();
00351     this->loaderServer->Open();
00352 
00353     // attach loader to Loader::Server
00354     Ptr<Loader::EntityLoader> entityloader = Loader::EntityLoader::Create();
00355     this->loaderServer->AttachLoader(entityloader);
00356 
00357     Ptr<Loader::EnvironmentLoader> environmentloader = Loader::EnvironmentLoader::Create();
00358     this->loaderServer->AttachLoader(environmentloader);
00359 
00360     // setup the gui subsystem (FIXME)
00361     nGuiServer* guiServer = nGuiServer::Instance();
00362     guiServer->SetRootPath("/res/gui");
00363     guiServer->SetDisplaySize(vector2(1024.0f, 768.0f));
00364     guiServer->Open();
00365     this->uiServer = UI::Server::Create();
00366     this->uiServer->Open();
00367 #ifdef MANGALORE_USE_CEGUI
00368     this->ceuiServer = CEUI::Server::Create();
00369     this->ceuiServer->Open();
00370 #endif
00371 }
00372 
00373 //------------------------------------------------------------------------------
00377 void
00378 App::CleanupSubsystems()
00379 {
00380     // cleanup gui stuff
00381     nGuiServer::Instance()->Close();
00382     this->uiServer->Close();
00383     this->uiServer = 0;
00384 #ifdef MANGALORE_USE_CEGUI
00385     this->ceuiServer->Close();
00386     this->ceuiServer = 0;
00387 #endif
00388 
00389     // cleanup loader subsystem
00390     this->loaderServer->Close();
00391     this->loaderServer = 0;
00392 
00393     // cleanup navigation subsystem
00394     if (this->navigationServer->IsOpen())
00395     {
00396         this->navigationServer->Close();
00397     }
00398     this->navigationServer = 0;
00399 
00400     // cleanup vfx subsystem
00401     this->vfxServer->Close();
00402     this->vfxServer = 0;
00403 
00404     // cleanup audio subsystem
00405     this->audioServer->Close();
00406     this->audioServer = 0;
00407 
00408     // cleanup graphics subsystem
00409     this->graphicsServer->Close();
00410     this->graphicsServer = 0;
00411 
00412     // cleanup physics subsystem
00413     this->physicsServer->Close();
00414     this->physicsServer = 0;
00415 
00416     // cleanup input subsysyem
00417     this->inputServer->Close();
00418     this->inputServer = 0;
00419 
00420     // cleanup the db subsystem
00421     this->dbServer = 0;
00422 
00423     // cleanup the message subsystem
00424     this->messageServer->Close();
00425     this->messageServer = 0;
00426 
00427     //  cleanup the script subsystem
00428     this->scriptServer->Close();
00429     this->scriptServer = 0;
00430 
00431     // cleanup the foundation subsystem
00432     this->foundationServer->Close();
00433 }
00434 
00435 //------------------------------------------------------------------------------
00442 void
00443 App::SetupStateHandlers()
00444 {
00445     // FIXME
00446 }
00447 
00448 //------------------------------------------------------------------------------
00455 void
00456 App::CleanupStateHandlers()
00457 {
00458     // release game state handlers
00459     this->requestedState.Clear();
00460     this->curState.Clear();
00461     this->nextState.Clear();
00462 
00463     // cleanup state handlers
00464     int i;
00465     int num = this->stateHandlers.Size();
00466     for (i = 0; i < num; i++)
00467     {
00468         this->stateHandlers[i]->OnRemoveFromApplication();
00469     }
00470     this->stateHandlers.Clear();
00471 }
00472 
00473 //------------------------------------------------------------------------------
00479 bool
00480 App::Open()
00481 {
00482     n_assert(!this->isOpen);
00483     nString logName = this->GetAppName() + " - " + this->GetAppVersion();
00484     this->foundationServer = n_new(Foundation::Server(this->GetVendorName(), this->GetAppName(), logName));
00485 
00486     // setup members
00487     this->isRunning = false;
00488     this->isPaused  = false;
00489 
00490     this->time = 0.0;
00491     this->stateTime = 0.0;
00492     this->frameTime = 0.0;
00493     this->pauseTime = 0.0;
00494     this->stateTransitionTimeStamp = 0.0;
00495     this->lastRealTime = 0.0;
00496 
00497     // initialize app settings
00498     this->SetupFromDefaults();
00499     this->SetupFromProfile();
00500     this->SetupFromCmdLineArgs();
00501 
00502     // check if system meets startup preconditions
00503     if (!this->DoStartupCheck())
00504     {
00505         return false;
00506     }
00507 
00508     // setup the Mangalore subsystems
00509     this->SetupSubsystems();
00510     this->SetupGameSubsystem();
00511 
00512     // update time stamps
00513     this->UpdateTimes();
00514 
00515     // setup application state handlers
00516     this->curState.Clear();
00517     this->nextState.Clear();
00518     this->SetupStateHandlers();
00519 
00520     this->isOpen = true;
00521     return true;
00522 }
00523 
00524 //------------------------------------------------------------------------------
00528 void
00529 App::Close()
00530 {
00531     n_assert(this->isOpen);
00532     n_assert(!this->isRunning);
00533 
00534     this->CleanupStateHandlers();
00535     this->CleanupGameSubsystem();
00536     this->CleanupSubsystems();
00537 
00538     n_delete(this->foundationServer);
00539     this->foundationServer = 0;
00540     this->isOpen = false;
00541 }
00542 
00543 //------------------------------------------------------------------------------
00553 void
00554 App::OnFrame()
00555 {
00556     // empty, override in subclass
00557 }
00558 
00559 //------------------------------------------------------------------------------
00564 void
00565 App::Run()
00566 {
00567     while (this->GetCurrentState() != "Exit")
00568     {
00569         // update the times
00570         this->UpdateTimes();
00571 
00572         // call the current state handler
00573         StateHandler* curStateHandler = this->FindStateHandlerByName(this->GetCurrentState());
00574         n_assert(curStateHandler);
00575         nString newState = curStateHandler->OnFrame();
00576 
00577         // call the app's OnFrame() method
00578         this->OnFrame();
00579 
00580         // a requested state always overrides the returned state
00581         if (this->requestedState.IsValid())
00582         {
00583             this->SetState(this->requestedState);
00584         }
00585         else if (newState != curStateHandler->GetName())
00586         {
00587             // a normal state transition
00588             this->SetState(newState);
00589         }
00590 
00591         // give up time slice
00592         n_sleep(0.0);
00593     }
00594 }
00595 
00596 //------------------------------------------------------------------------------
00600 void
00601 App::SetPaused(bool b)
00602 {
00603     if (b)
00604     {
00605         if (!this->isPaused)
00606         {
00607             this->isPaused = true;
00608             this->pauseTime = this->time;
00609         }
00610     }
00611     else
00612     {
00613         if (this->isPaused)
00614         {
00615             this->isPaused = false;
00616             this->time = this->pauseTime;
00617         }
00618     }
00619 }
00620 
00621 //------------------------------------------------------------------------------
00629 void
00630 App::UpdateTimes()
00631 {
00632     if (!this->IsPaused())
00633     {
00634         nTimeServer* timeServer = nTimeServer::Instance();
00635         timeServer->Trigger();
00636         nTime realTime = timeServer->GetTime();
00637         nTime diff = (realTime - this->lastRealTime) * this->timeFactor;
00638         this->lastRealTime = realTime; // update real timestamp
00639 
00640         // handle time exceptions
00641         if (diff <= 0.0)
00642         {
00643             diff = 0.0001;
00644         }
00645         else if (diff > 0.5)
00646         {
00647             diff = 0.5;
00648         }
00649 
00650         this->time = this->time + diff;
00651         this->frameTime = diff;
00652         this->stateTime = this->time - this->stateTransitionTimeStamp;
00653     }
00654 }
00655 
00656 //------------------------------------------------------------------------------
00661 void
00662 App::DoStateTransition()
00663 {
00664     // cleanup previous state
00665     if (this->curState.IsValid())
00666     {
00667         StateHandler* curStateHandler = this->FindStateHandlerByName(this->curState);
00668         n_assert(curStateHandler);
00669         curStateHandler->OnStateLeave(this->nextState);
00670     }
00671 
00672     // initialize new state
00673     nString prevState = this->curState;
00674     this->curState = this->nextState;
00675     if (this->nextState.IsValid())
00676     {
00677         StateHandler* nextStateHandler =  this->FindStateHandlerByName(this->nextState);
00678         if (nextStateHandler)
00679         {
00680             nextStateHandler->OnStateEnter(prevState);
00681         }
00682     }
00683     this->requestedState.Clear();
00684     this->UpdateTimes();
00685     this->stateTransitionTimeStamp = this->time;
00686 }
00687 
00688 //------------------------------------------------------------------------------
00694 void
00695 App::RequestState(const nString& s)
00696 {
00697     this->requestedState = s;
00698 }
00699 
00700 //------------------------------------------------------------------------------
00704 void
00705 App::SetState(const nString& s)
00706 {
00707     this->nextState = s;
00708     this->DoStateTransition();
00709 }
00710 
00711 //------------------------------------------------------------------------------
00717 void
00718 App::AddStateHandler(StateHandler* handler)
00719 {
00720     this->stateHandlers.Append(handler);
00721     handler->OnAttachToApplication();
00722 }
00723 
00724 //------------------------------------------------------------------------------
00731 StateHandler*
00732 App::FindStateHandlerByName(const nString& name) const
00733 {
00734     int i;
00735     int num = this->GetNumStates();
00736     for (i = 0; i < num; i++)
00737     {
00738         if (this->stateHandlers[i]->GetName() == name)
00739         {
00740             return this->stateHandlers[i];
00741         }
00742     }
00743     return 0;
00744 }
00745 
00746 //------------------------------------------------------------------------------
00750 StateHandler*
00751 App::FindStateHandlerByRtti(const Foundation::Rtti& rtti) const
00752 {
00753     int i;
00754     int num = this->GetNumStates();
00755     for (i = 0; i < num; i++)
00756     {
00757         if (this->stateHandlers[i]->IsA(rtti))
00758         {
00759             return this->stateHandlers[i];
00760         }
00761     }
00762     return 0;
00763 }
00764 
00765 //------------------------------------------------------------------------------
00769 StateHandler*
00770 App::GetCurrentStateHandler() const
00771 {
00772     n_assert(this->curState.IsValid());
00773     StateHandler* curStateHandler = this->FindStateHandlerByName(this->curState);
00774     n_assert(0 != curStateHandler);
00775     return curStateHandler;
00776 }
00777 
00778 } // namespace Application

Copyright © 1999-2005 by the contributing authors. Ideas, requests, problems: Send feedback.