app.cc
Go to the documentation of this file.00001
00002
00003
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
00109
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
00120 return false;
00121 }
00122
00123 #ifdef __WIN32__
00124
00125
00126 nString errorMsgD3D("Cannot initialize Direct3D!");
00127 if (!this->startupChecker.CheckDirect3D(this->GetAppName(), errorMsgD3D))
00128 {
00129
00130 return false;
00131 }
00132
00133
00134 nString errorMsgDS("Cannot initialize DirectSound!");
00135 if (!this->startupChecker.CheckDirectSound(this->GetAppName(), errorMsgDS))
00136 {
00137
00138 return false;
00139 }
00140 #endif
00141
00142
00143 return true;
00144 }
00145
00146
00153 void
00154 App::SetupFromDefaults()
00155 {
00156
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
00181 }
00182
00183
00195 void
00196 App::SetupFromCmdLineArgs()
00197 {
00198
00199 this->SetStartupSavegame(this->cmdLineArgs.GetStringArg("-loadgame", 0));
00200 this->SetStartupLevel(this->cmdLineArgs.GetStringArg("-level", 0));
00201
00202
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
00223 nString projDirArg = this->cmdLineArgs.GetStringArg("-projdir", 0);
00224 if (projDirArg.IsValid())
00225 {
00226 this->SetProjectDirectory(projDirArg);
00227 }
00228
00229
00230 nString featureSetArg = this->cmdLineArgs.GetStringArg("-featureset", 0);
00231 if (featureSetArg.IsValid())
00232 {
00233 this->SetFeatureSet(featureSetArg);
00234 }
00235
00236
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
00293 this->foundationServer->SetProjectDir(this->projDir);
00294 this->foundationServer->Open();
00295
00296
00297 this->scriptServer = Script::Server::Create();
00298 this->scriptServer->Open();
00299
00300
00301 this->messageServer = Message::Server::Create();
00302 this->messageServer->Open();
00303
00304
00305 this->dbServer = Db::Server::Create();
00306
00307
00308 this->physicsServer = Physics::Server::Create();
00309 this->physicsServer->Open();
00310
00311
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
00319 this->inputServer = Input::Server::Create();
00320 this->inputServer->Open();
00321
00322
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
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
00347 this->navigationServer = Navigation::Server::Create();
00348
00349
00350 this->loaderServer = Loader::Server::Create();
00351 this->loaderServer->Open();
00352
00353
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
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
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
00390 this->loaderServer->Close();
00391 this->loaderServer = 0;
00392
00393
00394 if (this->navigationServer->IsOpen())
00395 {
00396 this->navigationServer->Close();
00397 }
00398 this->navigationServer = 0;
00399
00400
00401 this->vfxServer->Close();
00402 this->vfxServer = 0;
00403
00404
00405 this->audioServer->Close();
00406 this->audioServer = 0;
00407
00408
00409 this->graphicsServer->Close();
00410 this->graphicsServer = 0;
00411
00412
00413 this->physicsServer->Close();
00414 this->physicsServer = 0;
00415
00416
00417 this->inputServer->Close();
00418 this->inputServer = 0;
00419
00420
00421 this->dbServer = 0;
00422
00423
00424 this->messageServer->Close();
00425 this->messageServer = 0;
00426
00427
00428 this->scriptServer->Close();
00429 this->scriptServer = 0;
00430
00431
00432 this->foundationServer->Close();
00433 }
00434
00435
00442 void
00443 App::SetupStateHandlers()
00444 {
00445
00446 }
00447
00448
00455 void
00456 App::CleanupStateHandlers()
00457 {
00458
00459 this->requestedState.Clear();
00460 this->curState.Clear();
00461 this->nextState.Clear();
00462
00463
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
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
00498 this->SetupFromDefaults();
00499 this->SetupFromProfile();
00500 this->SetupFromCmdLineArgs();
00501
00502
00503 if (!this->DoStartupCheck())
00504 {
00505 return false;
00506 }
00507
00508
00509 this->SetupSubsystems();
00510 this->SetupGameSubsystem();
00511
00512
00513 this->UpdateTimes();
00514
00515
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
00557 }
00558
00559
00564 void
00565 App::Run()
00566 {
00567 while (this->GetCurrentState() != "Exit")
00568 {
00569
00570 this->UpdateTimes();
00571
00572
00573 StateHandler* curStateHandler = this->FindStateHandlerByName(this->GetCurrentState());
00574 n_assert(curStateHandler);
00575 nString newState = curStateHandler->OnFrame();
00576
00577
00578 this->OnFrame();
00579
00580
00581 if (this->requestedState.IsValid())
00582 {
00583 this->SetState(this->requestedState);
00584 }
00585 else if (newState != curStateHandler->GetName())
00586 {
00587
00588 this->SetState(newState);
00589 }
00590
00591
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;
00639
00640
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
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
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 }