vrj::Kernel Class Reference

Main control class for all VR Juggler applications. More...

#include <vrj/Kernel/Kernel.h>

Collaboration diagram for vrj::Kernel:

Collaboration graph
[legend]
List of all members.

Public Types

typedef boost::function< void(const int)> signal_callback_t
 Type definition fo the pre- and post-stop callbacks invoked by the kernel signal handler.

Public Member Functions

void initConfig ()
 Loads initial configuration data for the managers.
void controlLoop (void *nullParam)
 The Kernel loop.
void setApplication (vrj::App *newApp)
 Sets the application object for the Kernel to deal with.
void loadConfigFile (const char *filename)
 Loads configuration data for the kernel.
void loadConfigFile (std::string filename)
 Loads configuration data for the kernel.
void scanForConfigDefinitions (const std::string &path)
 Scans the given directory (or directories) for .jdef files and loads all discovered files into the JCCL Element Factory.
Kernel Control Loop Functions
int start ()
 Starts the VR Juggler microkernel running by spawning the control loop thread.
void stop ()
 Stops the kernel control loop.
bool isRunning () const
 Returns the status of kernel.
void waitForKernelStop ()
 Blocks until the kernel exits.
Signal Handler Callbacks
void addHandlerPreCallback (signal_callback_t callback)
 Adds a "pre-stop" callback to be invoked if a handled signal is received by this kernel instance.
void addHandlerPostCallback (signal_callback_t callback)
 Adds a "post-stop" callback to be invoked if a handled signal is received by this kernel instance.
Global "get" interface
gadget::InputManager * getInputManager ()
 Gets the Input Manager.
vrj::UsergetUser (const std::string &userName)
 Gets the user associated with the given name.
std::vector< vrj::User * > getUsers ()
 Returns a list of the users.
const vpr::Thread * getThread ()

Protected Member Functions

void updateFrameData ()
 Updates any data that needs updated once a frame (Trackers, etc.
void checkForReconfig ()
 Checks to see if there is reconfiguration to be done.
void changeApplication (vrj::App *newApp)
 Changes the application in use.
void initSignalButtons ()
 Initializes the signal buttons for the kernel.
void checkSignalButtons ()
 Checks the signal buttons to see if anything has been triggered.
void handleSignal (const int signum)
 Handles a signal delivered by the operating system.
 Kernel ()
 Constructor: Hidden, so no direct instantiation is allowed.
 Kernel (const vrj::Kernel &k)
void operator= (const vrj::Kernel &)
virtual ~Kernel ()
 vprSingletonHeader (Kernel)
Config element handler interface implementation
virtual bool configCanHandle (jccl::ConfigElementPtr element)
 Can the handler handle the given element?
virtual bool configAdd (jccl::ConfigElementPtr element)
 Adds the element to the configuration.
virtual bool configRemove (jccl::ConfigElementPtr element)
 Removes the element from the current configuration.
Local config functions
bool addUser (jccl::ConfigElementPtr element)
 Adds a User to the system.
bool removeUser (jccl::ConfigElementPtr element)
 Removes a User from the system.
Draw Manager routines
void startDrawManager (bool newMgr)
 Starts the Draw Manager running.
void stopDrawManager ()
 Stops the Draw Manager, closes its resources, and deletes it.

Protected Attributes

vrj::AppmApp
 The current active app object.
vrj::AppmNewApp
 New application to set.
bool mNewAppSet
 Flag to notify that a new application should be set.
bool mIsRunning
 Flag for wether the kernel is currently running.
bool mExitFlag
 Set true when the kernel should exit.
vpr::ThreadMemberFunctor<
vrj::Kernel > * 
mControlFunctor
vpr::Thread * mControlThread
 The thread in control of me.
vpr::CondVar mExitWaitCondVar
 Cond var for waiting for exit.
gadget::DigitalInterface mStopKernelSignalButton
 Control "signals" from input interfaces.
Factories and Managers
gadget::InputManager * mInputManager
 The input manager for the system.
DrawManagermDrawManager
 The Draw Manager we are currently using.
SoundManagermSoundManager
 The Audio Manager we are currently using.
DisplayManagermDisplayManager
 The Display Manager we are currently using.
cluster::ClusterManager * mClusterManager
 The Cluster Manager for the system.
PerformanceMediatormPerformanceMediator
Multi-user information
std::vector< vrj::User * > mUsers
 A list of user objects in system.
Signal Handler Callbacks
std::vector< signal_callback_tmPreStopCallbacks
 Callbacks invoked by handleSignal() before stopping the kernel.
std::vector< signal_callback_tmPostStopCallbacks
 Callbacks invoked by handleSignal() after stopping the kernel.

Detailed Description

Main control class for all VR Juggler applications.

The kernel takes care of all initialization and object creation. This class is the only class that MUST be instantiated for all application objects.

Definition at line 80 of file Kernel.h.


Member Typedef Documentation

typedef boost::function<void(const int)> vrj::Kernel::signal_callback_t

Type definition fo the pre- and post-stop callbacks invoked by the kernel signal handler.

These callbacks take a signal integer argument (the signal number) and return nothing.

See also:
addHandlerPreCallback

addHandlerPostCallback

Since:
2.0.2

Definition at line 143 of file Kernel.h.


Constructor & Destructor Documentation

vrj::Kernel::Kernel (  )  [protected]

Constructor: Hidden, so no direct instantiation is allowed.

Definition at line 708 of file Kernel.cpp.

References vrj::getVersionString().

00709    : mApp(NULL)
00710    , mNewApp(NULL)
00711    , mNewAppSet(false)
00712    , mIsRunning(false)
00713    , mExitFlag(false)
00714    , mControlFunctor(NULL)
00715    , mControlThread(NULL)
00716    , mInputManager(NULL)
00717    , mDrawManager(NULL)
00718    , mSoundManager(NULL)
00719    , mDisplayManager(NULL)
00720    , mClusterManager(NULL)
00721    , mPerformanceMediator(NULL)
00722 {
00723    // Print out the Juggler version number when the kernel is created.
00724    vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00725       << std::string(strlen(VJ_VERSION) + 12, '=')
00726       << std::endl << vprDEBUG_FLUSH;
00727    vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00728       << clrOutNORM(clrGREEN, "VR Juggler: ")
00729       << clrOutNORM(clrGREEN, VJ_VERSION) << clrRESET
00730       << std::endl << vprDEBUG_FLUSH;
00731    vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00732       << clrOutNORM(clrGREEN, "VPR: ")
00733       << clrOutNORM(clrGREEN, vpr::getVersionString())
00734       << clrRESET << std::endl << vprDEBUG_FLUSH;
00735    vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00736       << clrOutNORM(clrGREEN, "JCCL: ")
00737       << clrOutNORM(clrGREEN, jccl::getVersionString())
00738       << clrRESET << std::endl << vprDEBUG_FLUSH;
00739    vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00740       << clrOutNORM(clrGREEN, "Gadgeteer: ")
00741       << clrOutNORM(clrGREEN, gadget::getVersionString())
00742       << clrRESET << std::endl << vprDEBUG_FLUSH;
00743    vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL)
00744       << std::string(strlen(VJ_VERSION) + 12, '=')
00745       << std::endl << vprDEBUG_FLUSH;
00746 
00747    // Load in the configuration definitions
00748    std::string def_path;
00749    if ( vpr::System::getenv("VJ_BASE_DIR", def_path).success() )
00750    {
00751       def_path = "${VJ_BASE_DIR}/" VJ_SHARE_DIR "/data/definitions";
00752    }
00753    else
00754    {
00755       def_path = VJ_ROOT_DIR "/" VJ_SHARE_DIR "/data/definitions";
00756       vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00757          << "Loading Definitions: VJ_BASE_DIR is not set.\n"
00758          << vprDEBUG_FLUSH;
00759       vprDEBUG_NEXT(vprDBG_ALL, vprDBG_WARNING_LVL)
00760          << "Defaulting to " << def_path << std::endl << vprDEBUG_FLUSH;
00761    }
00762    jccl::ElementFactory::instance()->loadDefs(def_path);
00763 
00764 
00765    // Set up a default configuration path if the user does not already have
00766    // one defined in the environment variable $JCCL_CFG_PATH.  If that
00767    // environment variable is not defined, check to see if $VJ_CFG_PATH is
00768    // defined.  If it is, use it.  Otherwise, use
00769    // $VJ_BASE_DIR/share/data/configFiles as a last-ditch fallback.
00770    // XXX: Should $VJ_CFG_PATH supercede $JCCL_CFG_PATH instead of doing it
00771    // this way?
00772    std::string cfg_path;
00773    if ( ! vpr::System::getenv("JCCL_CFG_PATH", cfg_path).success() )
00774    {
00775       if ( vpr::System::getenv("VJ_CFG_PATH", cfg_path).success() )
00776       {
00777          vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00778             << "JCCL_CFG_PATH environment variable not set.\n"
00779             << vprDEBUG_FLUSH;
00780          vprDEBUG_NEXT(vprDBG_ALL, vprDBG_WARNING_LVL)
00781             << "Using VJ_CFG_PATH instead.\n" << vprDEBUG_FLUSH;
00782       }
00783       // Neither $JCCL_CFG_PATH nor $VJ_CFG_PATH is set, so use what basically
00784       // amounts to a hard-coded default.
00785       else if ( vpr::System::getenv("VJ_BASE_DIR", cfg_path).success() )
00786       {
00787          cfg_path = "${VJ_BASE_DIR}/" VJ_SHARE_DIR "/data/configFiles";
00788          vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00789             << "Neither JCCL_CFG_PATH nor VJ_CFG_PATH is set.\n"
00790             << vprDEBUG_FLUSH;
00791          vprDEBUG_NEXT(vprDBG_ALL, vprDBG_WARNING_LVL)
00792             << "Defaulting to " << cfg_path << std::endl << vprDEBUG_FLUSH;
00793          cfg_path = vpr::replaceEnvVars(cfg_path);
00794       }
00795       else
00796       {
00797          cfg_path = VJ_ROOT_DIR "/" VJ_SHARE_DIR "/data/configFiles";
00798          vprDEBUG(vprDBG_ALL, vprDBG_WARNING_LVL)
00799             << "JCCL_CFG_PATH, VJ_CFG_PATH, and VJ_BASE_DIR are not set.\n"
00800             << vprDEBUG_FLUSH;
00801          vprDEBUG_NEXT(vprDBG_ALL, vprDBG_WARNING_LVL)
00802             << "Defaulting to " << cfg_path << std::endl << vprDEBUG_FLUSH;
00803          cfg_path = vpr::replaceEnvVars(cfg_path);
00804       }
00805 
00806       jccl::ParseUtil::setCfgSearchPath(cfg_path);
00807    }
00808 }

vrj::Kernel::Kernel ( const vrj::Kernel k  )  [inline, protected]

Definition at line 439 of file Kernel.h.

00439 : jccl::ConfigElementHandler(k) {;}

vrj::Kernel::~Kernel (  )  [protected, virtual]

Definition at line 810 of file Kernel.cpp.

References mControlFunctor, mControlThread, mPerformanceMediator, and mUsers.

00811 {
00812    if ( NULL != mPerformanceMediator )
00813    {
00814       delete mPerformanceMediator;
00815       mPerformanceMediator = NULL;
00816    }
00817 
00818    if ( NULL != mControlThread )
00819    {
00820       delete mControlThread;
00821       mControlThread = NULL;
00822    }
00823 
00824    if ( NULL != mControlFunctor )
00825    {
00826       delete mControlFunctor;
00827       mControlFunctor = NULL;
00828    }
00829 
00830    for ( std::vector<vrj::User*>::iterator i = mUsers.begin(); i != mUsers.end(); ++i )
00831    {
00832       delete *i;
00833    }
00834 
00835    mUsers.clear();
00836 }


Member Function Documentation

int vrj::Kernel::start (  ) 

Starts the VR Juggler microkernel running by spawning the control loop thread.

The methods of the user-supplied application object are invoked from the spawned thread.

Postcondition:
A signal handler is registered with the operating system for SIGINT, SIGTERM, and (on Windows only) SIGBREAK. Upon successful completion, a new thread is running the kernel control loop.
Returns:
0 is returned if the kernel control loop thread is started successfully. 1 is returned if the thread fails to spawn.
See also:
setApplication()

waitForKernelStop()

stop()

addHandlerPreCallback()

addHandlerPostCallback()

handleSignal()

controlLoop()

Definition at line 91 of file Kernel.cpp.

References controlLoop(), gRealHandler, handleSignal(), initSignalButtons(), mControlFunctor, mControlThread, mIsRunning, signalHandler(), and vrjDBG_KERNEL().

Referenced by vrj::VRJProcRunSystem().

00092 {
00093    // Set the real signal handler to be invoked by signalHandler() (see
00094    // above).
00095    gRealHandler = boost::bind(&Kernel::handleSignal, this, _1);
00096 
00097    vpr::SignalAction sig_action(signalHandler);
00098    // Catch SIGINT, SIGTERM, and SIGBREAK so that we can shut down the kernel
00099    // cleanly.
00100    vpr::SigHandler::registerHandler(SIGINT, sig_action, false);
00101    vpr::SigHandler::registerHandler(SIGTERM, sig_action, false);
00102 #if defined(VPR_OS_Windows)
00103    vpr::SigHandler::registerHandler(SIGBREAK, sig_action, false);
00104 #endif
00105 
00106    if(mControlThread != NULL) // Have already started
00107    {
00108       vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
00109          << clrOutNORM(clrRED,"ERROR:")
00110          << " vrj::Kernel::start() called when kernel already running!\n"
00111          << vprDEBUG_FLUSH;
00112       vprASSERT(false);
00113       exit(0);
00114    }
00115 
00116    mIsRunning = true;
00117    initSignalButtons();    // Initialize the signal buttons that may be pressed
00118 
00119    // Create a new thread to handle the control
00120    mControlFunctor = new vpr::ThreadMemberFunctor<Kernel>(this,
00121                                                           &Kernel::controlLoop,
00122                                                           NULL);
00123 
00124    // mControlThread is set in controlLoop().
00125    new vpr::Thread(mControlFunctor);
00126 
00127    vprDEBUG(vrjDBG_KERNEL,vprDBG_STATE_LVL)
00128       << "vrj::Kernel::start(): Just started control loop." << std::endl
00129       << vprDEBUG_FLUSH;
00130 
00131    return 1;
00132 }

void vrj::Kernel::stop (  ) 

Stops the kernel control loop.

If there is an application set, then it will be closed first.

Postcondition:
The kernel exits, and the VR Juggler system shuts down.

Definition at line 137 of file Kernel.cpp.

References mExitFlag, mExitWaitCondVar, and setApplication().

Referenced by checkSignalButtons(), and handleSignal().

00138 {
00139    mExitWaitCondVar.acquire();
00140    {
00141       mExitFlag = true;
00142       mExitWaitCondVar.signal();
00143    }
00144    mExitWaitCondVar.release();
00145 
00146    setApplication(NULL);    // Set NULL application so that the app gets closed
00147 }

bool vrj::Kernel::isRunning (  )  const [inline]

Returns the status of kernel.

Definition at line 117 of file Kernel.h.

Referenced by handleSignal().

00118    {
00119       return mIsRunning;
00120    }

void vrj::Kernel::waitForKernelStop (  ) 

Blocks until the kernel exits.

See also:
stop()

Definition at line 157 of file Kernel.cpp.

References mExitFlag, mExitWaitCondVar, and mIsRunning.

Referenced by vrj::VRJProcRunSystem().

00158 {
00159    mExitWaitCondVar.acquire();
00160    {
00161       while (! (!mIsRunning && mExitFlag) )   // Wait until !mIsRunning && mExitFlag
00162       {
00163          mExitWaitCondVar.wait();
00164       }
00165    }
00166    mExitWaitCondVar.release();
00167 }

void vrj::Kernel::addHandlerPreCallback ( signal_callback_t  callback  ) 

Adds a "pre-stop" callback to be invoked if a handled signal is received by this kernel instance.

The job of the kernel signal handler is to try to shut down the kernel cleanly upon receiving one of the handled signals. Prior to stopping the kernel, all registered pre-stop callbacks are invoked regardless of whether the control loop for this kernel is currently running.

Postcondition:
The given callback is appended to mPreStopCallbacks.
Parameters:
callback The callback to be invoked by this kernel's signal handler prior to stopping the kernel control loop.
Note:
To avoid a race condition wherein the signal handler gets registered with the operating system and a signal is delivered prior to this method being invoked, it is recommended that pre-stop callbacks be registered prior to invoking start().
See also:
start()

handleSignal()

Since:
2.0.2

Definition at line 169 of file Kernel.cpp.

References mPreStopCallbacks.

00170 {
00171    mPreStopCallbacks.push_back(callback);
00172 }

void vrj::Kernel::addHandlerPostCallback ( signal_callback_t  callback  ) 

Adds a "post-stop" callback to be invoked if a handled signal is received by this kernel instance.

The job of the kernel signal handler is to try to shut down the kernel cleanly upon receiving one of the handled signals. After stopping the kernel, all registered post-stop callbacks are invoked regardless of whether the control loop for this kernel is currently running.

Postcondition:
The given callback is appended to mPostStopCallbacks.
Parameters:
callback The callback to be invoked by this kernel's signal handler after stopping the kernel control loop.
Note:
To avoid a race condition wherein the signal handler gets registered with the operating system and a signal is delivered prior to this method being invoked, it is recommended that post-stop callbacks be registered prior to invoking start().
See also:
start()

handleSignal()

Since:
2.0.2

Definition at line 174 of file Kernel.cpp.

References mPostStopCallbacks.

00175 {
00176    mPostStopCallbacks.push_back(callback);
00177 }

void vrj::Kernel::initConfig (  ) 

Loads initial configuration data for the managers.

Postcondition:
Input Manager, Display Manager, and kernel configuration files are loaded and handed to configAdd().

Definition at line 454 of file Kernel.cpp.

References mClusterManager, mDisplayManager, mInputManager, mPerformanceMediator, and vrjDBG_KERNEL().

Referenced by controlLoop().

00455 {
00456    vprDEBUG_BEGIN(vrjDBG_KERNEL, vprDBG_CONFIG_LVL)
00457       << "vrj::Kernel::initConfig(): Setting initial config.\n"
00458       << vprDEBUG_FLUSH;
00459 
00460    // ---- ALLOCATE MANAGERS --- //
00461    //initialSetupInputManager();
00462    mInputManager = gadget::InputManager::instance();
00463 
00464    //initialSetupDisplayManager();
00465    mDisplayManager = DisplayManager::instance();  // Get display manager
00466    vprASSERT(mDisplayManager != NULL);            // Did we get an object
00467 
00468    mClusterManager = cluster::ClusterManager::instance();
00469 
00470 
00471    mPerformanceMediator = new PerformanceMediator();
00472 
00473    //??// processPending() // Should I do this here
00474 
00475    // hook dynamically-reconfigurable managers up to config manager
00476    // XXX: Should replace with dynamic support in future
00477    jccl::ConfigManager::instance()->addConfigElementHandler(this);
00478    jccl::ConfigManager::instance()->addConfigElementHandler(mInputManager);
00479    jccl::ConfigManager::instance()->addConfigElementHandler(mClusterManager);
00480    jccl::ConfigManager::instance()->addConfigElementHandler(mDisplayManager);
00481    vprDEBUG_END(vrjDBG_KERNEL, vprDBG_CONFIG_LVL)
00482       << "vrj::Kernel::initConfig(): Done.\n" << vprDEBUG_FLUSH;
00483 }

void vrj::Kernel::controlLoop ( void *  nullParam  ) 

The Kernel loop.

Definition at line 180 of file Kernel.cpp.

References checkForReconfig(), checkSignalButtons(), vrj::DrawManager::draw(), getInputManager(), initConfig(), vrj::App::intraFrame(), vrj::App::latePreFrame(), mApp, mClusterManager, mControlThread, mDrawManager, mExitFlag, mExitWaitCondVar, mIsRunning, mSoundManager, vrj::App::postFrame(), vrj::App::preFrame(), vrj::DrawManager::sync(), vrj::SoundManager::sync(), vrj::SoundManager::update(), updateFrameData(), and vrjDBG_KERNEL().

Referenced by start().

00181 {
00182    boost::ignore_unused_variable_warning(nullParam);
00183    vprDEBUG(vrjDBG_KERNEL, vprDBG_CONFIG_LVL)
00184       << "vrj::Kernel::controlLoop: Started.\n" << vprDEBUG_FLUSH;
00185    vprASSERT (NULL != vpr::Thread::self());
00186 
00187    mControlThread = vpr::Thread::self();
00188 
00189    // Do any initial configuration
00190    initConfig();
00191 
00192    vpr::prof::start("Kernel: controlLoop",10);
00193 
00194    // --- MAIN CONTROL LOOP -- //
00195    while(! (mExitFlag && (mApp == NULL)))     // While not exit flag set and don't have app. (can't exit until app is closed)
00196    {
00197       // Might not want the Kernel to know about the ClusterNetwork
00198       // It is currently being registered as a jccl::ConfigElementHandler in
00199       // the ClusterManager constructor
00200          vpr::prof::start("Cluster: updateNewConnections.",10);
00201        cluster::ClusterManager::instance()->getNetwork()->updateNewConnections();
00202          vpr::prof::next("Cluster: sendRequests.",10);
00203        cluster::ClusterManager::instance()->sendRequests();
00204          vpr::prof::stop();
00205 
00206       bool cluster = !( cluster::ClusterManager::instance()->isClusterActive() &&
00207                         !cluster::ClusterManager::instance()->isClusterReady());
00208 
00209       // Iff we have an app and a draw manager
00210       if((mApp != NULL) && (mDrawManager != NULL) && cluster)
00211       {
00212             vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00213                << "vrj::Kernel::controlLoop: mApp->preFrame()\n"
00214                << vprDEBUG_FLUSH;
00215          vpr::prof::start("App: PreFrame",10);
00216          mApp->preFrame();         // PREFRAME: Do Any application pre-draw stuff
00217          vpr::prof::stop();
00218             vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00219                << "vrj::Kernel::controlLoop: Update ClusterManager preDraw()\n"
00220                << vprDEBUG_FLUSH;
00221       }
00222       else
00223       {
00224          // ??? Should we do this, or just grind up the CPU as fast as possible
00225          vprASSERT(NULL != mControlThread);      // If control thread is not set correctly, it will seg fault here
00226          vpr::Thread::yield();   // Give up CPU
00227       }
00228 
00229       vpr::prof::start("Cluster: preDraw",10);
00230       mClusterManager->preDraw();
00231       vpr::prof::stop();
00232 
00233       if((mApp != NULL) && (mDrawManager != NULL) && cluster)
00234       {
00235             vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00236                << "vrj::Kernel::controlLoop: mApp->latePreFrame()\n"
00237                << vprDEBUG_FLUSH;
00238             vpr::prof::start("App: latePreFrame",10);
00239          mApp->latePreFrame();
00240             vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00241                << "vrj::Kernel::controlLoop: drawManager->draw()\n"
00242                << vprDEBUG_FLUSH;
00243             vpr::prof::next("trigger draw",10);
00244          mDrawManager->draw();    // DRAW: Trigger the beginning of frame drawing
00245             vpr::prof::next("sound mgr update",10);
00246          mSoundManager->update();
00247             vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00248                << "vrj::Kernel::controlLoop: mApp->intraFrame()\n"
00249                << vprDEBUG_FLUSH;
00250             vpr::prof::next("App: intraFrame",10);
00251          mApp->intraFrame();        // INTRA FRAME: Do computations that can be done while drawing.  This should be for next frame.
00252             vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00253                << "vrj::Kernel::controlLoop: drawManager->sync()\n"
00254                << vprDEBUG_FLUSH;
00255             vpr::prof::next("sound sync",10);
00256          mSoundManager->sync();
00257             vpr::prof::next("draw sync",10);
00258          mDrawManager->sync();    // SYNC: Block until drawing is done
00259             vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00260                << "vrj::Kernel::controlLoop: mApp->postFrame()\n"
00261                << vprDEBUG_FLUSH;
00262             vpr::prof::next("App: postFrame",10);
00263          mApp->postFrame();        // POST FRAME: Do processing after drawing is complete
00264             vpr::prof::stop();
00265       }
00266       else
00267       {
00268          // ??? Should we do this, or just grind up the CPU as fast as possible
00269          vprASSERT(NULL != mControlThread);      // If control thread is not set correctly, it will seg fault here
00270          vpr::Thread::yield();   // Give up CPU
00271       }
00272 
00273       // --- Stop for reconfiguration -- //
00274          vpr::prof::start("checkForReconfig",10);
00275       checkForReconfig();        // Check for any reconfiguration that needs done (system or application)
00276          vpr::prof::next("check kern signals",10);
00277       checkSignalButtons();      // Check for any pending control requests
00278          vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00279             << "vrj::Kernel::controlLoop: Update Trackers\n" << vprDEBUG_FLUSH;
00280          vpr::prof::next("resetAllDevicesAndProxies", 10);
00281       getInputManager()->resetAllDevicesAndProxies();
00282          vpr::prof::next("updateAllDevices",10);
00283       getInputManager()->updateAllDevices();
00284          vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00285             << "vrj::Kernel::controlLoop: Update ClusterManager\n"
00286             << vprDEBUG_FLUSH;
00287          vpr::prof::next("Cluster: postPostFrame.",10);
00288       mClusterManager->postPostFrame();
00289            vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00290             << "vrj::Kernel::controlLoop: Update Proxies\n"
00291             << vprDEBUG_FLUSH;
00292          vpr::prof::next("updateAllProxies",10);
00293       getInputManager()->updateAllProxies();
00294          vprDEBUG(vrjDBG_KERNEL, vprDBG_HVERB_LVL)
00295             << "vrj::Kernel::controlLoop: Update Projections\n"
00296             << vprDEBUG_FLUSH;
00297          vpr::prof::next("Update frame data",10);
00298       updateFrameData();         // Any frame-based manager data
00299          vpr::prof::stop();
00300    }
00301 
00302    vpr::prof::stop();
00303 
00304    vprDEBUG(vrjDBG_KERNEL, vprDBG_WARNING_LVL)
00305       << "vrj::Kernel::controlLoop: Exiting. \n" << vprDEBUG_FLUSH;
00306 
00307    // Set the running status to false
00308    mExitWaitCondVar.acquire();
00309    {
00310       mIsRunning = false;
00311       mExitWaitCondVar.signal();
00312    }
00313    mExitWaitCondVar.release();
00314 }

void vrj::Kernel::setApplication ( vrj::App newApp  ) 

Sets the application object for the Kernel to deal with.

If there is another application active, the kernel has to stop that application first and then restart all the graphics API-specific Managers.

Parameters:
newApp If NULL, stops current application.

Definition at line 318 of file Kernel.cpp.

References mNewApp, mNewAppSet, and vrjDBG_KERNEL().

Referenced by stop(), and vrj::VRJProcRunSystem().

00319 {
00320    vprDEBUG(vrjDBG_KERNEL,vprDBG_CONFIG_LVL)
00321       << "[vrj::Kernel::setApplication()] New application set\n"
00322       << vprDEBUG_FLUSH;
00323    mNewApp = newApp;
00324    mNewAppSet = true;
00325 }

void vrj::Kernel::loadConfigFile ( const char *  filename  )  [inline]

Loads configuration data for the kernel.

Postcondition:
Config data has been read into initial the buffer.
Parameters:
filename The name of the configuration file to load.

Definition at line 226 of file Kernel.h.

Referenced by vrj::VRJConfigure().

00227    {
00228       std::string filename_str = std::string(filename);
00229       loadConfigFile(filename_str);
00230    }

void vrj::Kernel::loadConfigFile ( std::string  filename  ) 

Loads configuration data for the kernel.

Postcondition:
Config data has been read into initial the buffer.
Parameters:
filename The name of the configuration file to load.

Definition at line 575 of file Kernel.cpp.

References vrjDBG_KERNEL().

00576 {
00577    vprDEBUG(vrjDBG_KERNEL,vprDBG_CONFIG_LVL)
00578       << "Loading config file: " << filename << std::endl << vprDEBUG_FLUSH;
00579 
00580    // We can allocate this on thte stack because the config elements get
00581    // copied into a new PendingConfigElement from the configuration.
00582    jccl::Configuration cfg;
00583 
00584    // ------- OPEN Program specified Config file ------ //
00585    if(filename.empty())   // We have a filename
00586    {
00587       return;
00588    }
00589 
00590    bool cfg_load_success = cfg.load(filename);
00591    if (!cfg_load_success)
00592    {
00593       vprDEBUG(vprDBG_ERROR,vprDBG_CRITICAL_LVL) << clrOutNORM(clrRED,"ERROR:")
00594          << "vrj::Kernel::loadConfigFile: Failed to load file: "
00595          << filename << std::endl << vprDEBUG_FLUSH;
00596       exit(1);
00597    }
00598 
00599    // Put all the newly loaded config elments into the Config Manager's
00600    // incoming element list.
00601    jccl::ConfigManager::instance()->addConfigurationAdditions(&cfg);
00602 }

void vrj::Kernel::scanForConfigDefinitions ( const std::string &  path  ) 

Scans the given directory (or directories) for .jdef files and loads all discovered files into the JCCL Element Factory.

Postcondition:
The config element factory can now manage elements with the discovered types.
Parameters:
path One or more directories, delineated by a platform-specific path separator, that will be searched for .jdef files.

Definition at line 606 of file Kernel.cpp.

00607 {
00608    jccl::ElementFactory::instance()->loadDefs(path);
00609 }

bool vrj::Kernel::configCanHandle ( jccl::ConfigElementPtr  element  )  [protected, virtual]

Can the handler handle the given element?

Returns:
true if we can handle the element; false otherwise.

Definition at line 492 of file Kernel.cpp.

Referenced by configAdd(), and configRemove().

00493 {
00494    return std::string("user") == element->getID();
00495 }

bool vrj::Kernel::configAdd ( jccl::ConfigElementPtr  element  )  [protected, virtual]

Adds the element to the configuration.

Precondition:
configCanHandle(element) == true.
Returns:
Success.

Definition at line 497 of file Kernel.cpp.

References addUser(), and configCanHandle().

00498 {
00499    const std::string element_type(element->getID());
00500 
00501    vprASSERT(configCanHandle(element));
00502 
00503    bool result(false);
00504 
00505    if(std::string("user") == element_type)
00506    {
00507       result = addUser(element);
00508    }
00509 
00510    return result;
00511 }

bool vrj::Kernel::configRemove ( jccl::ConfigElementPtr  element  )  [protected, virtual]

Removes the element from the current configuration.

Precondition:
configCanHandle(element) == true.
Returns:
success.

Definition at line 513 of file Kernel.cpp.

References configCanHandle(), and removeUser().

00514 {
00515    const std::string element_type(element->getID());
00516 
00517    vprASSERT(configCanHandle(element));
00518 
00519    bool result(false);
00520 
00521    if(std::string("user") == element_type)
00522    {
00523       result = removeUser(element);
00524    }
00525 
00526    return result;
00527 }

bool vrj::Kernel::addUser ( jccl::ConfigElementPtr  element  )  [protected]

Adds a User to the system.

Definition at line 530 of file Kernel.cpp.

References mUsers, and vrjDBG_KERNEL().

Referenced by configAdd().

00531 {
00532    vprASSERT(element->getID() == "user");
00533 
00534    User* new_user = new User;
00535    bool success = new_user->config(element);
00536 
00537    if(!success)
00538    {
00539       vprDEBUG(vrjDBG_KERNEL, vprDBG_CRITICAL_LVL)
00540          << clrOutNORM(clrRED,"ERROR:") << " Failed to add new User: "
00541          << element->getName() << std::endl << vprDEBUG_FLUSH;
00542       delete new_user;
00543    }
00544    else
00545    {
00546       vprDEBUG(vrjDBG_KERNEL, vprDBG_STATE_LVL)
00547          << "vrj::Kernel: Added new User: " << new_user->getName() << std::endl
00548          << vprDEBUG_FLUSH;
00549       mUsers.push_back(new_user);
00550    }
00551 
00552    return success;
00553 }

bool vrj::Kernel::removeUser ( jccl::ConfigElementPtr  element  )  [protected]

Removes a User from the system.

Definition at line 555 of file Kernel.cpp.

References vrj::User::getName(), getUser(), mUsers, and vrjDBG_KERNEL().

Referenced by configRemove().

00556 {
00557    vprASSERT(element->getID() == "user");
00558    
00559    std::string user_name = element->getName();
00560    vrj::User* user = getUser(user_name);
00561 
00562    if (NULL != user)
00563    {
00564       vprDEBUG(vrjDBG_KERNEL, vprDBG_STATE_LVL)
00565          << "vrj::Kernel: Removing User: " << user->getName() << std::endl
00566          << vprDEBUG_FLUSH;
00567          
00568       mUsers.erase(std::find(mUsers.begin(), mUsers.end(), user));
00569       return true;
00570    }
00571    return false;
00572 }

void vrj::Kernel::updateFrameData (  )  [protected]

Updates any data that needs updated once a frame (Trackers, etc.

).

Postcondition:
All tracker data is ready for next frame.

Definition at line 485 of file Kernel.cpp.

Referenced by controlLoop().

00486 {
00487    // When we have a draw manager, tell it to update its projections
00488    // XXX: Moved to be updated on demand
00489    // mDisplayManager->updateProjections();
00490 }

void vrj::Kernel::checkForReconfig (  )  [protected]

Checks to see if there is reconfiguration to be done.

Postcondition:
Any reconfiguration needed has been completed.
Note:
Can only be called by the kernel thread.

Definition at line 328 of file Kernel.cpp.

References changeApplication(), vrj::App::depSatisfied(), mControlThread, mNewApp, mNewAppSet, and vrjDBG_KERNEL().

Referenced by controlLoop().

00329 {
00330    vprASSERT(vpr::Thread::self() == mControlThread);      // ASSERT: We are being called from kernel thread
00331    // ---- RECONFIGURATION --- //
00332    jccl::ConfigManager* cfg_mgr = jccl::ConfigManager::instance();
00333    unsigned num_processed(0);
00334 
00335    do
00336    {
00337       num_processed = cfg_mgr->attemptReconfiguration();
00338    }
00339    while (num_processed > 0);
00340    // ---- APP SWITCH ---- //
00341    // check for a new applications
00342    if(mNewAppSet)
00343    {
00344       if((mNewApp == NULL) || (mNewApp->depSatisfied()) )   // If app is NULL or dependencies satisfied
00345       {
00346          vprDEBUG(vrjDBG_KERNEL,vprDBG_CONFIG_STATUS_LVL)
00347             << "New application set; dependencies satisfied.\n"
00348             << vprDEBUG_FLUSH;
00349          mNewAppSet = false;
00350          changeApplication(mNewApp);
00351       }
00352       else
00353       {
00354          vprDEBUG(vrjDBG_KERNEL,vprDBG_WARNING_LVL)
00355             << "New application set; dependencies not satisfied yet.\n"
00356             << vprDEBUG_FLUSH;
00357       }
00358    }
00359 }

void vrj::Kernel::changeApplication ( vrj::App newApp  )  [protected]

Changes the application in use.

If there is another application object active, it has to stop that application first then restart all API-specific Managers.

Parameters:
newApp If NULL, stops current application.
Note:
This can only be called from the kernel thread.

Definition at line 367 of file Kernel.cpp.

References vrj::App::getDrawManager(), vrj::App::getSoundManager(), mApp, mControlThread, mDrawManager, mSoundManager, startDrawManager(), stopDrawManager(), and vrjDBG_KERNEL().

Referenced by checkForReconfig().

00368 {
00369    vprDEBUG(vrjDBG_KERNEL, vprDBG_CONFIG_LVL)
00370       << "vrj::Kernel::changeApplication() Changing to: "
00371       << std::hex << std::showbase << (void*) newApp << std::dec << std::endl
00372       << vprDEBUG_FLUSH;
00373 
00374    vprASSERT(vpr::Thread::self() == mControlThread);      // ASSERT: We are being called from kernel thread
00375    jccl::ConfigManager* cfg_mgr = jccl::ConfigManager::instance();
00376 
00377    // Quick out if for some reason the user calls setApplication with
00378    // the same application that is running.
00379    if (newApp == mApp)
00380    {
00381       return;
00382    }
00383 
00384    // XXX: TODO: Free resources (ie closeContext())
00385 
00386    // If the new application is NULL OR
00387    // we have an old draw manager and it is different from the new one, stop it.
00388    if (NULL == newApp || NULL != mDrawManager && newApp->getDrawManager() != mDrawManager)
00389    {
00390       stopDrawManager();
00391       cfg_mgr->removeConfigElementHandler(mDrawManager);
00392       cfg_mgr->removeConfigElementHandler(mSoundManager);
00393    }
00394 
00395    // If we have an old application, exit it.
00396    if (NULL != mApp)
00397    {
00398       cfg_mgr->removeConfigElementHandler(mApp);
00399       mApp->exit();
00400    }
00401 
00402    // Start using the new application.
00403    // NOTE: The kernel no longer has a reference to the old application
00404    //       so it can be safely deleted.
00405    mApp = newApp;
00406 
00407    // If we have a new application
00408    if (NULL != mApp)
00409    {
00410       // If the new application uses a different draw manager.
00411       if(mApp->getDrawManager() != mDrawManager)
00412       {
00413          mDrawManager = mApp->getDrawManager();
00414          vprASSERT(NULL != mDrawManager);
00415 
00416          mDrawManager = mApp->getDrawManager();             // Get the new draw manager
00417          mSoundManager = mApp->getSoundManager();           // Get the new sound manager
00418          cfg_mgr->addConfigElementHandler(mDrawManager);    // Tell config manager about them
00419          cfg_mgr->addConfigElementHandler(mSoundManager);   // Tell config manager about them
00420          startDrawManager(true);                      // Start the new one
00421       }
00422       else
00423       {
00424          startDrawManager(false);                     // Start new app
00425       }
00426       // Now handle configuration
00427       cfg_mgr->addConfigElementHandler(mApp);
00428       cfg_mgr->refreshPendingList();                  // New managers, so we may be able to handle config requests now
00429    }
00430 }

void vrj::Kernel::initSignalButtons (  )  [protected]

Initializes the signal buttons for the kernel.

Definition at line 433 of file Kernel.cpp.

References mStopKernelSignalButton.

Referenced by start().

00434 {
00435    mStopKernelSignalButton.init("VJSystemStopKernel");
00436 }

void vrj::Kernel::checkSignalButtons (  )  [protected]

Checks the signal buttons to see if anything has been triggered.

Definition at line 439 of file Kernel.cpp.

References mStopKernelSignalButton, and stop().

Referenced by controlLoop().

00440 {
00441    if(mStopKernelSignalButton->getData() == gadget::Digital::TOGGLE_ON)
00442    {
00443       vprDEBUG(vprDBG_ALL, vprDBG_STATE_LVL)
00444          << "Stop kernel signal button pressed: Kernel will exit.\n"
00445          << vprDEBUG_FLUSH;
00446       this->stop();  // Signal kernel to stop
00447    }
00448 }

void vrj::Kernel::startDrawManager ( bool  newMgr  )  [protected]

Starts the Draw Manager running.

Calls the app callbacks for the Draw Manager.

Precondition:
The application object, current Draw Manager, and current Display Manager have all been set.
Postcondition:
All processes and data should have been created by Draw Manager.
Parameters:
newMgr Is this a new manager or the same one.

Definition at line 612 of file Kernel.cpp.

References vrj::App::apiInit(), vrj::App::init(), vrj::DrawManager::initAPI(), mApp, mDisplayManager, mDrawManager, vrj::DrawManager::setApp(), vrj::DrawManager::setDisplayManager(), vrj::DisplayManager::setDrawManager(), vrjDBG_KERNEL(), and vrj::ManagerException::what().

Referenced by changeApplication().

00613 {
00614    vprASSERT((mApp != NULL) && (mDrawManager != NULL) && (mDisplayManager != NULL));
00615 
00616    if(newMgr)
00617    {
00618       mDrawManager->setDisplayManager(mDisplayManager);
00619       jccl::ConfigManager::instance()->lockPending();
00620       {
00621          mDrawManager->configProcessPending();                 // Handle any pending configuration requests BEFORE we init and start it going
00622       }
00623       jccl::ConfigManager::instance()->unlockPending();
00624    }
00625 
00626    try
00627    {
00628       mDrawManager->setApp(mApp);
00629 
00630       mApp->init();                // Init the app
00631 
00632       if(newMgr)
00633       {
00634          // Just sets up API type stuff, possibly starts new processes.
00635          mDrawManager->initAPI();
00636       }
00637 
00638       mApp->apiInit();             // Have app do any app-init stuff
00639 
00640       if(newMgr)
00641       {
00642          // This can trigger the update of windows to the Draw Manager.
00643          mDisplayManager->setDrawManager(mDrawManager);
00644       }
00645    }
00646    catch(vrj::DrawMgrException& ex)
00647    {
00648       vprDEBUG(vrjDBG_KERNEL, vprDBG_WARNING_LVL)
00649          << clrOutBOLD(clrYELLOW, "WARNING:")
00650          << " Draw Manager rejected application object:" << std::endl
00651          << vprDEBUG_FLUSH;
00652       vprDEBUG_NEXT(vrjDBG_KERNEL, vprDBG_WAR