00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <vrj/vrjConfig.h>
00034 #include <string.h>
00035 #include <vrj/vrjParam.h>
00036 #include <vrj/Kernel/Kernel.h>
00037 #include <vrj/Util/Debug.h>
00038 #include <vrj/Draw/DrawManager.h>
00039 #include <vrj/Display/DisplayManager.h>
00040 #include <vrj/Kernel/App.h>
00041 #include <vrj/Kernel/User.h>
00042
00043 #include <vpr/vpr.h>
00044 #include <vpr/Thread/Thread.h>
00045 #include <vpr/System.h>
00046 #include <vpr/Util/Version.h>
00047 #include <vpr/Util/FileUtils.h>
00048 #include <gadget/Util/Version.h>
00049
00050 #include <gadget/InputManager.h>
00051
00052 #include <cluster/ClusterManager.h>
00053 #include <cluster/ClusterNetwork/ClusterNetwork.h>
00054
00055 #include <jccl/Config/ParseUtil.h>
00056 #include <jccl/Config/ConfigElement.h>
00057 #include <jccl/Config/ElementFactory.h>
00058 #include <jccl/RTRC/ConfigManager.h>
00059
00060 #include <boost/concept_check.hpp>
00061
00062
00063 namespace vrj
00064 {
00065
00066 vprSingletonImp(Kernel);
00067
00068
00069 int Kernel::start()
00070 {
00071 if(mControlThread != NULL)
00072 {
00073 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
00074 << clrOutNORM(clrRED,"ERROR:")
00075 << " vrj::Kernel::start() called when kernel already running!\n"
00076 << vprDEBUG_FLUSH;
00077 vprASSERT(false);
00078 exit(0);
00079 }
00080
00081 mIsRunning = true;
00082 initSignalButtons();
00083
00084
00085 vpr::ThreadMemberFunctor<Kernel>* memberFunctor =
00086 new vpr::ThreadMemberFunctor<Kernel>(this, &Kernel::controlLoop, NULL);
00087
00088
00089 new vpr::Thread(memberFunctor);
00090
00091 vprDEBUG(vrjDBG_KERNEL,vprDBG_STATE_LVL)
00092 << "vrj::Kernel::start(): Just started control loop." << std::endl
00093 << vprDEBUG_FLUSH;
00094
00095 return 1;
00096 }
00097
00098
00099
00100
00101 void Kernel::stop()
00102 {
00103 mExitWaitCondVar.acquire();
00104 {
00105 mExitFlag = true;
00106 mExitWaitCondVar.signal();
00107 }
00108 mExitWaitCondVar.release();
00109
00110 setApplication(NULL);
00111 }
00112
00121 void Kernel::waitForKernelStop()
00122 {
00123 mExitWaitCondVar.acquire();
00124 {
00125 while (! (!mIsRunning && mExitFlag) )
00126 {
00127 mExitWaitCondVar.wait();
00128 }
00129 }
00130 mExitWaitCondVar.release();
00131 }
00132
00133
00134
00135 void Kernel::controlLoop(void* nullParam)
00136 {
00137 boost::ignore_unused_variable_warning(nullParam);
00138 vprDEBUG(vrjDBG_KERNEL, vprDBG_CONFIG_LVL)
00139 << "vrj::Kernel::controlLoop: Started.\n" << vprDEBUG_FLUSH;
00140 vprASSERT (NULL != vpr::Thread::self());
00141
00142 mControlThread = vpr::Thread::self();
00143
00144
00145 initConfig();
00146
00147
00148 while(! (mExitFlag && (mApp == NULL)))
00149 {
00150
00151
00152
00153 cluster::ClusterNetwork::instance()->updateNewConnections();
00154 cluster::ClusterManager::instance()->sendRequests();
00155
00156 bool cluster = !(cluster::ClusterManager::instance()->isClusterActive() &&
00157 !cluster::ClusterManager::instance()->isClusterReady());
00158
00159
00160 if((mApp != NULL) && (mDrawManager != NULL) && cluster)
00161 {
00162 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00163 << "vrj::Kernel::controlLoop: mApp->preFrame()\n"
00164 << vprDEBUG_FLUSH;
00165 mApp->preFrame();
00166 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00167 << "vrj::Kernel::controlLoop: Update ClusterManager preDraw()\n"
00168 << vprDEBUG_FLUSH;
00169 }
00170 else
00171 {
00172
00173 vprASSERT(NULL != mControlThread);
00174 vpr::Thread::yield();
00175 }
00176
00177 mClusterManager->preDraw();
00178
00179 if((mApp != NULL) && (mDrawManager != NULL) && cluster)
00180 {
00181 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00182 << "vrj::Kernel::controlLoop: mApp->latePreFrame()\n"
00183 << vprDEBUG_FLUSH;
00184 mApp->latePreFrame();
00185 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00186 << "vrj::Kernel::controlLoop: drawManager->draw()\n"
00187 << vprDEBUG_FLUSH;
00188 mDrawManager->draw();
00189 mSoundManager->update();
00190 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00191 << "vrj::Kernel::controlLoop: mApp->intraFrame()\n"
00192 << vprDEBUG_FLUSH;
00193 mApp->intraFrame();
00194 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00195 << "vrj::Kernel::controlLoop: drawManager->sync()\n"
00196 << vprDEBUG_FLUSH;
00197 mSoundManager->sync();
00198 mDrawManager->sync();
00199 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00200 << "vrj::Kernel::controlLoop: mApp->postFrame()\n"
00201 << vprDEBUG_FLUSH;
00202 mApp->postFrame();
00203 }
00204 else
00205 {
00206
00207 vprASSERT(NULL != mControlThread);
00208 vpr::Thread::yield();
00209 }
00210
00211
00212 checkForReconfig();
00213 checkSignalButtons();
00214 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00215 << "vrj::Kernel::controlLoop: Update Trackers\n" << vprDEBUG_FLUSH;
00216 getInputManager()->updateAllData();
00217 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00218 << "vrj::Kernel::controlLoop: Update ClusterManager\n"
00219 << vprDEBUG_FLUSH;
00220 mClusterManager->postPostFrame();
00221 vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00222 << "vrj::Kernel::controlLoop: Update Projections\n"
00223 << vprDEBUG_FLUSH;
00224 updateFrameData();
00225 }
00226
00227 vprDEBUG(vrjDBG_KERNEL, vprDBG_WARNING_LVL)
00228 << "vrj::Kernel::controlLoop: Exiting. \n" << vprDEBUG_FLUSH;
00229
00230
00231 mExitWaitCondVar.acquire();
00232 {
00233 mIsRunning = false;
00234 mExitWaitCondVar.signal();
00235 }
00236 mExitWaitCondVar.release();
00237 }
00238
00239
00240
00241 void Kernel::setApplication(App* newApp)
00242 {
00243 vprDEBUG(vrjDBG_KERNEL,vprDBG_CONFIG_LVL)
00244 << "vrj::Kernel::setApplication: New application set\n" << vprDEBUG_FLUSH;
00245 mNewApp = newApp;
00246 mNewAppSet = true;
00247 }
00248
00249
00250 void Kernel::checkForReconfig()
00251 {
00252 vprASSERT(vpr::Thread::self() == mControlThread);
00253
00254 jccl::ConfigManager* cfg_mgr = jccl::ConfigManager::instance();
00255 unsigned num_processed(0);
00256
00257 do
00258 {
00259 num_processed = cfg_mgr->attemptReconfiguration();
00260 }
00261 while (num_processed > 0);
00262
00263
00264 if(mNewAppSet)
00265 {
00266 if((mNewApp == NULL) || (mNewApp->depSatisfied()) )
00267 {
00268 vprDEBUG(vrjDBG_KERNEL,vprDBG_CONFIG_STATUS_LVL)
00269 << "vrj::Kernel: New application set, dependencies: Satisfied.\n"
00270 << vprDEBUG_FLUSH;
00271 mNewAppSet = false;
00272 changeApplication(mNewApp);
00273 }
00274 else
00275 {
00276 vprDEBUG(vrjDBG_KERNEL,vprDBG_WARNING_LVL)
00277 << "vrj::Kernel: New application set, dependencies: Not satisfied yet.\n"
00278 << vprDEBUG_FLUSH;
00279 }
00280 }
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 void Kernel::changeApplication(App* newApp)
00290 {
00291 vprDEBUG(vrjDBG_KERNEL, vprDBG_CONFIG_LVL)
00292 << "vrj::Kernel::changeApplication: Changing to:" << newApp << std::endl
00293 << vprDEBUG_FLUSH;
00294
00295 vprASSERT(vpr::Thread::self() == mControlThread);
00296 jccl::ConfigManager* cfg_mgr = jccl::ConfigManager::instance();
00297
00298 if(mApp != NULL)
00299 {
00300 cfg_mgr->removeConfigElementHandler(mApp);
00301 mApp->exit();
00302 mApp = NULL;
00303 }
00304
00305
00306 if(newApp != NULL)
00307 {
00308 mApp = newApp;
00309 DrawManager* new_draw_mgr = mApp->getDrawManager();
00310 vprASSERT(NULL != new_draw_mgr);
00311
00312 if (new_draw_mgr != mDrawManager)
00313 {
00314 stopDrawManager();
00315 cfg_mgr->removeConfigElementHandler(mDrawManager);
00316
00317 mDrawManager = mApp->getDrawManager();
00318 mSoundManager = mApp->getSoundManager();
00319 cfg_mgr->addConfigElementHandler(mDrawManager);
00320 cfg_mgr->addConfigElementHandler(mSoundManager);
00321 startDrawManager(true);
00322 }
00323 else
00324 {
00325 startDrawManager(false);
00326 }
00327
00328 cfg_mgr->addConfigElementHandler(mApp);
00329 cfg_mgr->refreshPendingList();
00330 }
00331 else
00332 {
00333 stopDrawManager();
00334 mApp = NULL;
00335 }
00336 }
00337
00338
00339 void Kernel::initSignalButtons()
00340 {
00341 mStopKernelSignalButton.init("VJSystemStopKernel");
00342 }
00343
00344
00345 void Kernel::checkSignalButtons()
00346 {
00347 if(mStopKernelSignalButton->getData() == gadget::Digital::ON)
00348 {
00349 vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
00350 << "Stop kernel signal button pressed: Kernel will exit.\n"
00351 << vprDEBUG_FLUSH;
00352 this->stop();
00353 }
00354 }
00355
00356
00357
00358
00359
00360 void Kernel::initConfig()
00361 {
00362 vprDEBUG_BEGIN(vrjDBG_KERNEL, vprDBG_CONFIG_LVL)
00363 << "vrj::Kernel::initConfig(): Setting initial config.\n"
00364 << vprDEBUG_FLUSH;
00365
00366
00367
00368 mInputManager = gadget::InputManager::instance();
00369
00370
00371 mDisplayManager = DisplayManager::instance();
00372 vprASSERT(mDisplayManager != NULL);
00373
00374 mClusterManager = cluster::ClusterManager::instance();
00375
00376
00377
00378
00379
00380 jccl::ConfigManager::instance()->addConfigElementHandler(this);
00381 jccl::ConfigManager::instance()->addConfigElementHandler(mInputManager);
00382 jccl::ConfigManager::instance()->addConfigElementHandler(mClusterManager);
00383 jccl::ConfigManager::instance()->addConfigElementHandler(mDisplayManager);
00384 vprDEBUG_END(vrjDBG_KERNEL, vprDBG_CONFIG_LVL)
00385 << "vrj::Kernel::initConfig(): Done.\n" << vprDEBUG_FLUSH;
00386 }
00387
00388 void Kernel::updateFrameData()
00389 {
00390
00391
00392
00393 }
00394
00395 bool Kernel::configCanHandle(jccl::ConfigElementPtr element)
00396 {
00397 return std::string("user") == element->getID();
00398 }
00399
00400 bool Kernel::configAdd(jccl::ConfigElementPtr element)
00401 {
00402 const std::string element_type(element->getID());
00403
00404 vprASSERT(configCanHandle(element));
00405
00406 if(std::string("user") == element_type)
00407 {
00408 return addUser(element);
00409 }
00410 else
00411 {
00412 return false;
00413 }
00414 }
00415
00416 bool Kernel::configRemove(jccl::ConfigElementPtr element)
00417 {
00418 const std::string element_type(element->getID());
00419
00420 vprASSERT(configCanHandle(element));
00421
00422 if(std::string("user") == element_type)
00423 {
00424 return removeUser(element);
00425 }
00426 else
00427 {
00428 return false;
00429 }
00430 }
00431
00432
00433 bool Kernel::addUser(jccl::ConfigElementPtr element)
00434 {
00435 vprASSERT(element->getID() == "user");
00436
00437 User* new_user = new User;
00438 bool success = new_user->config(element);
00439
00440 if(!success)
00441 {
00442 vprDEBUG(vrjDBG_KERNEL, vprDBG_CRITICAL_LVL)
00443 << clrOutNORM(clrRED,"ERROR:") << " Failed to add new User: "
00444 << element->getName() << std::endl << vprDEBUG_FLUSH;
00445 delete new_user;
00446 }
00447 else
00448 {
00449 vprDEBUG(vrjDBG_KERNEL, vprDBG_STATE_LVL)
00450 << "vrj::Kernel: Added new User: " << new_user->getName() << std::endl
00451 << vprDEBUG_FLUSH;
00452 mUsers.push_back(new_user);
00453 }
00454
00455 return success;
00456 }
00457
00458
00459 bool Kernel::removeUser(jccl::ConfigElementPtr element)
00460 {
00461 boost::ignore_unused_variable_warning(element);
00462 return false;
00463 }
00464
00465
00466 void Kernel::loadConfigFile(std::string filename)
00467 {
00468 vprDEBUG(vrjDBG_KERNEL,vprDBG_CONFIG_LVL)
00469 << "Loading config file: " << filename << std::endl << vprDEBUG_FLUSH;
00470
00471
00472
00473 jccl::Configuration cfg;
00474
00475
00476 if(filename.empty())
00477 {
00478 return;
00479 }
00480
00481 bool cfg_load_success = cfg.load(filename);
00482 if (!cfg_load_success)
00483 {
00484 vprDEBUG(vprDBG_ERROR,vprDBG_CRITICAL_LVL) << clrOutNORM(clrRED,"ERROR:")
00485 << "vrj::Kernel::loadConfigFile: Failed to load file: "
00486 << filename << std::endl << vprDEBUG_FLUSH;
00487 exit(1);
00488 }
00489
00490
00491
00492 jccl::ConfigManager::instance()->addConfigurationAdditions(&cfg);
00493 }
00494
00495
00496
00497 void Kernel::scanForConfigDefinitions(const std::string& path)
00498 {
00499 jccl::ElementFactory::instance()->loadDefs(path);
00500 }
00501
00502
00503 void Kernel::startDrawManager(bool newMgr)
00504 {
00505 vprASSERT((mApp != NULL) && (mDrawManager != NULL) && (mDisplayManager != NULL));
00506
00507 if(newMgr)
00508 {
00509 mDrawManager->setDisplayManager(mDisplayManager);
00510 jccl::ConfigManager::instance()->lockPending();
00511 {
00512 mDrawManager->configProcessPending();
00513 }
00514 jccl::ConfigManager::instance()->unlockPending();
00515 }
00516 mDrawManager->setApp(mApp);
00517
00518 mApp->init();
00519 if(newMgr)
00520 mDrawManager->initAPI();
00521 mApp->apiInit();
00522 if(newMgr)
00523 {
00524 mDisplayManager->setDrawManager(mDrawManager);
00525 }
00526 }
00527
00528
00529
00530
00531 void Kernel::stopDrawManager()
00532 {
00533 if(mDrawManager != NULL)
00534 {
00535 mDrawManager->closeAPI();
00536 delete mDrawManager;
00537 mDrawManager = NULL;
00538 mDisplayManager->setDrawManager(NULL);
00539 }
00540 }
00541
00542
00543 gadget::InputManager* Kernel::getInputManager()
00544 {
00545 return mInputManager;
00546 }
00547
00548 User* Kernel::getUser(const std::string& userName)
00549 {
00550 for(unsigned int i = 0; i < mUsers.size(); ++i)
00551 {
00552 if(userName == mUsers[i]->getName())
00553 {
00554 return mUsers[i];
00555 }
00556 }
00557
00558 return NULL;
00559 }
00560
00561 Kernel::Kernel()
00562 : mApp(NULL)
00563 , mNewApp(NULL)
00564 , mNewAppSet(false)
00565 , mIsRunning(false)
00566 , mExitFlag(false)
00567 , mControlThread(NULL)
00568 , mInputManager(NULL)
00569 , mDrawManager(NULL)
00570 , mSoundManager(NULL)
00571 , mDisplayManager(NULL)
00572 , mClusterManager(NULL)
00573 {
00574
00575 vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00576 << std::string(strlen(VJ_VERSION) + 12, '=')
00577 << std::endl << vprDEBUG_FLUSH;
00578 vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00579 << clrOutNORM(clrGREEN, "VR Juggler: ")
00580 << clrOutNORM(clrGREEN, VJ_VERSION) << clrRESET
00581 << std::endl << vprDEBUG_FLUSH;
00582 vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00583 << clrOutNORM(clrGREEN, "VPR: ")
00584 << clrOutNORM(clrGREEN, vpr::getVersionString())
00585 << clrRESET << std::endl << vprDEBUG_FLUSH;
00586 vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00587 << clrOutNORM(clrGREEN, "Gadgeteer: ")
00588 << clrOutNORM(clrGREEN, gadget::getVersionString())
00589 << clrRESET << std::endl << vprDEBUG_FLUSH;
00590 vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00591 << std::string(strlen(VJ_VERSION) + 12, '=')
00592 << std::endl << vprDEBUG_FLUSH;
00593
00594
00595 std::string def_path;
00596 if ( ! vpr::System::getenv("JCCL_DEFINITION_PATH", def_path).success() )
00597 {
00598 def_path = "${VJ_BASE_DIR}/" VJ_SHARE_DIR "/data/definitions";
00599 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00600 << "JCCL_DEFINITION_PATH environment variable not set.\n"
00601 << vprDEBUG_FLUSH;
00602 vprDEBUG_NEXT(vprDBG_ALL, vprDBG_WARNING_LVL)
00603 << "Defaulting to " << def_path << std::endl << vprDEBUG_FLUSH;
00604 }
00605 jccl::ElementFactory::instance()->loadDefs(def_path);
00606
00607
00608
00609
00610
00611
00612
00613
00614 std::string cfg_path;
00615 if ( ! vpr::System::getenv("JCCL_CFG_PATH", cfg_path).success() )
00616 {
00617 if ( vpr::System::getenv("VJ_CFG_PATH", cfg_path).success() )
00618 {
00619 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00620 << "JCCL_CFG_PATH environment variable not set.\n"
00621 << vprDEBUG_FLUSH;
00622 vprDEBUG_NEXT(vprDBG_ALL, vprDBG_WARNING_LVL)
00623 << "Using VJ_CFG_PATH instead.\n" << vprDEBUG_FLUSH;
00624 }
00625
00626
00627 else
00628 {
00629 cfg_path = "${VJ_BASE_DIR}/" VJ_SHARE_DIR "/data/configFiles";
00630 vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00631 << "Neither JCCL_CFG_PATH nor VJ_CFG_PATH is set.\n"
00632 << vprDEBUG_FLUSH;
00633 vprDEBUG_NEXT(vprDBG_ALL, vprDBG_WARNING_LVL)
00634 << "Defaulting to " << cfg_path << std::endl << vprDEBUG_FLUSH;
00635 cfg_path = vpr::replaceEnvVars(cfg_path);
00636 }
00637
00638 jccl::ParseUtil::setCfgSearchPath(cfg_path);
00639 }
00640 }
00641
00642 }