Commit a04da240 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[ADD] - added useful requirement system. Modules can now specify what they need.

parent 87c929ac
......@@ -25,6 +25,8 @@
#ifndef WREQUIREMENT_H
#define WREQUIREMENT_H
#include <string>
#include "WExportCommon.h"
/**
......@@ -53,6 +55,13 @@ public:
*/
virtual bool isComplied() const = 0;
/**
* Return a nice description of the requirement.
*
* \return the description.
*/
virtual std::string getDescription() const = 0;
protected:
private:
......
......@@ -39,7 +39,11 @@ WGERequirement::~WGERequirement()
bool WGERequirement::isComplied() const
{
// TODO(all): implement this properly if you modify the WGE for no-gui versions of OpenWalnut.
return true;
return WGraphicsEngine::isRunning();
}
std::string WGERequirement::getDescription() const
{
return "Module needs an running graphics engine.";
}
......@@ -50,7 +50,14 @@ public:
*
* \return true if the specific requirement is fulfilled.
*/
virtual bool isComplied() const = 0;
virtual bool isComplied() const;
/**
* Return a nice description of the requirement.
*
* \return the description.
*/
virtual std::string getDescription() const;
protected:
......
......@@ -165,13 +165,25 @@ boost::shared_ptr< WGEViewer > WGraphicsEngineAll::getViewer()
return m_viewers[ "main" ];
}
bool WGraphicsEngineAll::isRunning()
{
if ( !m_instance )
{
return false;
}
return m_instance->m_running;
}
void WGraphicsEngineAll::threadMain()
{
WLogger::getLogger()->addLogMessage( "Starting Graphics Engine", "GE", LL_INFO );
m_running = true;
m_viewer->startThreading();
m_viewer->run();
m_viewer->stopThreading();
m_running = false;
}
void WGraphicsEngineAll::notifyStop()
......
......@@ -136,6 +136,13 @@ public:
*/
boost::signals2::connection subscribeSignal( GE_SIGNAL signal, t_GEGenericSignalHandlerType notifier );
/**
* Checks whether the graphics engine is currently running or not.
*
* \return true if running
*/
static bool isRunning();
protected:
/**
......@@ -183,6 +190,11 @@ private:
* Singleton instance of WGraphicsEngine.
*/
static boost::shared_ptr< WGraphicsEngineAll > m_instance;
/**
* True if graphics engine is running.
*/
bool m_running;
};
/**
......
......@@ -163,3 +163,9 @@ boost::signals2::connection WGraphicsEngineMac::subscribeSignal( GE_SIGNAL signa
break;
}
}
bool WGraphicsEngineMac::isRunning()
{
return m_instance.get();
}
......@@ -135,6 +135,13 @@ public:
*/
boost::signals2::connection subscribeSignal( GE_SIGNAL signal, t_GEGenericSignalHandlerType notifier );
/**
* Checks whether the graphics engine is currently running or not.
*
* \return true if running
*/
static bool isRunning();
protected:
/**
......
......@@ -45,6 +45,7 @@
#include "exceptions/WModuleConnectorInitFailed.h"
#include "exceptions/WModuleConnectorNotFound.h"
#include "exceptions/WModuleUninitialized.h"
#include "exceptions/WModuleRequirementNotMet.h"
#include "../common/WException.h"
#include "../common/exceptions/WNameNotUnique.h"
#include "../common/WLogger.h"
......@@ -212,6 +213,10 @@ void WModule::properties()
{
}
void WModule::requirements()
{
}
void WModule::activate()
{
}
......@@ -229,6 +234,7 @@ void WModule::initialize()
m_runtimeName->set( getName() );
// initialize connectors and properties
requirements();
connectors();
properties();
......@@ -492,6 +498,20 @@ void WModule::ready()
signal_ready( shared_from_this() );
}
const WRequirement* WModule::checkRequirements() const
{
// simply iterate all requirements and return the first found that is not fulfilled
for ( Requirements::const_iterator i = m_requirements.begin(); i != m_requirements.end(); ++i )
{
if ( !( *i )->isComplied() )
{
return *i;
}
}
return NULL;
}
void WModule::threadMain()
{
#ifdef __linux__
......@@ -503,6 +523,13 @@ void WModule::threadMain()
{
WLogger::getLogger()->addLogMessage( "Starting module main method.", "Module (" + getName() + ")", LL_INFO );
// check requirements
const WRequirement* failedReq = checkRequirements();
if ( failedReq )
{
throw WModuleRequirementNotMet( failedReq );
}
// call main thread function
m_isRunning( true );
moduleMain();
......
......@@ -51,6 +51,7 @@
#include "../common/WProgressCombiner.h"
#include "../common/WProperties.h"
#include "../common/WPrototyped.h"
#include "../common/WRequirement.h"
#include "../common/WThreadedRunner.h"
#include "WExportKernel.h"
......@@ -364,6 +365,13 @@ protected:
*/
virtual void properties();
/**
* Initialize requirements in this function. This function must not be called multiple times for one module instance.
* The module should always implement this. Using this method, a module can tell the kernel what it needs to run properly. For example, it
* can require a running graphics engine or, in the case of module containers, other modules.
*/
virtual void requirements();
/**
* Manages connector initialization. Gets called by module container.
*
......@@ -575,6 +583,16 @@ protected:
*/
boost::filesystem::path m_localPath;
/**
* The type of the requirement list.
*/
typedef std::vector< WRequirement* > Requirements;
/**
* The list of requirements.
*/
Requirements m_requirements;
private:
/**
......@@ -596,6 +614,13 @@ private:
* Signal fired whenever a module main thread throws an exception/error.
*/
t_ModuleErrorSignalType signal_error;
/**
* This method checks whether all the requirements of the module are complied.
*
* \return the requirement that has failed.
*/
const WRequirement* checkRequirements() const;
};
/**
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include "WModuleFactory.h"
#include "WPrototypeRequirement.h"
WPrototypeRequirement::WPrototypeRequirement( std::string prototype ):
WRequirement(),
m_prototype( prototype )
{
// initialize members
}
WPrototypeRequirement::~WPrototypeRequirement()
{
// cleanup
}
bool WPrototypeRequirement::isComplied() const
{
return WModuleFactory::getModuleFactory()->isPrototypeAvailable( m_prototype );
}
std::string WPrototypeRequirement::getDescription() const
{
return "Module depends upon the module \"" + m_prototype + "\".";
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WPROTOTYPEREQUIREMENT_H
#define WPROTOTYPEREQUIREMENT_H
#include "../common/WRequirement.h"
#include "WExportKernel.h"
/**
* This requirement ensures that the specified prototype exists in the factory. These requirements are especially useful for container modules.
*/
class OWKERNEL_EXPORT WPrototypeRequirement: public WRequirement // NOLINT
{
public:
/**
* Create instance. If your module uses this requirement, it needs the specified module.
*
* \param prototype the module needed.
*/
explicit WPrototypeRequirement( std::string prototype );
/**
* Destructor.
*/
virtual ~WPrototypeRequirement();
/**
* Checks if the requirement is fulfilled on the system. Implement this for your specific case.
*
* \return true if the specific requirement is fulfilled.
*/
virtual bool isComplied() const;
/**
* Return a nice description of the requirement.
*
* \return the description.
*/
virtual std::string getDescription() const;
protected:
private:
/**
* The required prototype.
*/
std::string m_prototype;
};
#endif // WPROTOTYPEREQUIREMENT_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include "../../common/WRequirement.h"
#include "WModuleRequirementNotMet.h"
WModuleRequirementNotMet::WModuleRequirementNotMet( const WRequirement* requirement ):
WModuleException( std::string( "Requirement not met: " ) + requirement->getDescription() )
{
// initialize members
}
WModuleRequirementNotMet::~WModuleRequirementNotMet() throw()
{
// cleanup
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WMODULEREQUIREMENTNOTMET_H
#define WMODULEREQUIREMENTNOTMET_H
#include <string>
#include "WModuleException.h"
#include "../WExportKernel.h"
class WRequirement;
/**
* Thrown whenever a module should be run but its requirements are not completely met.
*/
class OWKERNEL_EXPORT WModuleRequirementNotMet: public WModuleException
{
public:
/**
* Default constructor. Creates an instance and sets the message according to the requirement specified here
*/
explicit WModuleRequirementNotMet( const WRequirement* requirement );
/**
* Destructor.
*/
virtual ~WModuleRequirementNotMet() throw();
protected:
private:
};
#endif // WMODULEREQUIREMENTNOTMET_H
......@@ -32,6 +32,7 @@
#include "../../kernel/WKernel.h"
#include "../../kernel/WModuleFactory.h"
#include "../../kernel/WPrototypeRequirement.h"
#include "../../dataHandler/WSubject.h"
#include "../../dataHandler/WGridRegular3D.h"
......@@ -172,6 +173,12 @@ void WMDistanceMapIsosurface::connectors()
WModule::connectors();
}
void WMDistanceMapIsosurface::requirements()
{
m_requirements.push_back( new WPrototypeRequirement( "Distance Map" ) );
m_requirements.push_back( new WPrototypeRequirement( "Isosurface" ) );
}
void WMDistanceMapIsosurface::activate()
{
m_marchingCubesModule->getProperties()->getProperty( "active" )->toPropBool()->set( m_active->get() );
......
......@@ -80,6 +80,11 @@ protected:
*/
virtual void connectors();
/**
* Initialize requirements for this module.
*/
virtual void requirements();
/**
* Callback for m_active. Overwrite this in your modules to handle m_active changes separately.
*/
......
......@@ -40,6 +40,7 @@
#include "../../graphicsEngine/WGEManagedGroupNode.h"
#include "../../graphicsEngine/WGEUtils.h"
#include "../../graphicsEngine/WShader.h"
#include "../../graphicsEngine/WGERequirement.h"
#include "../../kernel/WKernel.h"
#include "WMIsosurfaceRaytracer.xpm"
#include "WMIsosurfaceRaytracer.h"
......@@ -125,6 +126,11 @@ void WMIsosurfaceRaytracer::properties()
WModule::properties();
}
void WMIsosurfaceRaytracer::requirements()
{
m_requirements.push_back( new WGERequirement() );
}
void WMIsosurfaceRaytracer::moduleMain()
{
m_shader = osg::ref_ptr< WShader > ( new WShader( "WMIsosurfaceRaytracer", m_localPath ) );
......
......@@ -96,6 +96,11 @@ protected:
*/
virtual void properties();
/**
* Initialize requirements for this module.
*/
virtual void requirements();
private:
/**
......
......@@ -63,6 +63,7 @@
#include "../../common/WPathHelper.h"
#include "../../common/WPropertyHelper.h"
#include "../../graphicsEngine/WGEUtils.h"
#include "../../graphicsEngine/WGERequirement.h"
#include "WMTemplate.xpm"
#include "icons/bier.xpm"
......@@ -331,6 +332,16 @@ void WMTemplate::properties()
WModule::properties();
}
void WMTemplate::requirements()
{
// This method allows modules to specify what they need to run properly. This module, for example, needs the WGE. It therefore adds the
// WGERequirement to the list of requirements. Modules only get started if all the requirements of it are met by the current running
// OpenWalnut. This is a very handy tool for NO-GUI versions or script versions of OpenWalnut where there simply is no graphics engine
// running. This way, the kernel can ensure that only modules are allowed to run who do not require the WGE.
// Another useful example are module containers. Usually, they need several other modules to work properly.
m_requirements.push_back( new WGERequirement() );
}
void WMTemplate::moduleMain()
{
// This is the modules working thread. Its the most important part of your module.
......
......@@ -100,6 +100,11 @@ protected:
*/
virtual void properties();
/**
* Initialize requirements for this module.
*/
virtual void requirements();
/**
* The root node used for this modules graphics. For OSG nodes, always use osg::ref_ptr to ensure proper resource management.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment