Commit 900fda26 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[ADD] - added an extensive template/example module

parent b62e2cce
......@@ -61,6 +61,15 @@ public:
*/
virtual ~WFlag();
/**
* Operator returns value of the flag.
*
* \param resetChangeState when true, the changed() flag gets reset to false.
*
* \return the value.
*/
virtual const T get( bool resetChangeState = false );
/**
* Operator returns value of the flag.
*
......@@ -81,7 +90,7 @@ public:
virtual void wait() const;
/**
* Sets the new value for this flag. Also notifies waiting threads.
* Sets the new value for this flag. Also notifies waiting threads. After setting a value, changed() will be true.
*
* \param value the new value
* \param suppressNotification true to avoid a firing condition. This is useful for resetting values.
......@@ -116,6 +125,13 @@ public:
*/
virtual bool accept( T newValue );
/**
* True whenever the value inside this flag has changed since the last reset. It stays true until get( true ) is called.
*
* \return true when the value has changed and not yet been reseted.
*/
virtual bool changed();
protected:
/**
......@@ -128,6 +144,11 @@ protected:
*/
T m_flag;
/**
* Denotes whether the value has changed since the last reset.
*/
bool m_changed;
private:
};
......@@ -137,17 +158,19 @@ private:
typedef WFlag< bool > WBoolFlag;
template < typename T >
WFlag< T >::WFlag( WCondition* condition, T initial )
WFlag< T >::WFlag( WCondition* condition, T initial ):
m_condition( boost::shared_ptr< WCondition >( condition ) ),
m_flag( initial ),
m_changed( true )
{
m_condition = boost::shared_ptr< WCondition >( condition );
m_flag = initial;
}
template < typename T >
WFlag< T >::WFlag( boost::shared_ptr< WCondition > condition, T initial )
WFlag< T >::WFlag( boost::shared_ptr< WCondition > condition, T initial ):
m_condition( condition ),
m_flag( initial ),
m_changed( true )
{
m_condition = condition;
m_flag = initial;
}
template < typename T >
......@@ -161,6 +184,16 @@ const T WFlag< T >::operator()() const
return get();
}
template < typename T >
const T WFlag< T >::get( bool resetChangeState )
{
if ( resetChangeState )
{
m_changed = false;
}
return m_flag;
}
template < typename T >
const T WFlag< T >::get() const
{
......@@ -195,6 +228,7 @@ bool WFlag< T >::set( T value, bool suppressNotification )
}
m_flag = value;
m_changed = true;
// is the notification suppressed ?
if ( !suppressNotification )
......@@ -218,5 +252,11 @@ bool WFlag< T >::accept( T /* newValue */ )
return true;
}
template < typename T >
bool WFlag< T >::changed()
{
return m_changed;
}
#endif // WFLAG_H
......@@ -188,6 +188,15 @@ public:
*/
void addConstraint( boost::shared_ptr< PropertyConstraint > constraint );
/**
* Add a new constraint. It creates one for your with the specified type.
*
* \param constraint the type of constraint.
*
* \return the constraint created and added.
*/
boost::shared_ptr< PropertyConstraint > addConstraint( PROPERTYCONSTRAINT_TYPE constraint );
/**
* Creates a new WPropertyConstraintMin for this WPropertyVariable.
*
......@@ -380,6 +389,15 @@ void WPropertyVariable< T >::addConstraint( boost::shared_ptr< PropertyConstrain
lock.unlock();
}
template < typename T >
boost::shared_ptr< typename WPropertyVariable< T >::PropertyConstraint >
WPropertyVariable< T >::addConstraint( PROPERTYCONSTRAINT_TYPE constraint )
{
boost::shared_ptr< typename WPropertyVariable< T >::PropertyConstraint > c = PropertyConstraint::create( constraint );
addConstraint( c );
return c;
}
template < typename T >
void WPropertyVariable< T >::updateType()
{
......
......@@ -28,6 +28,7 @@
#include <typeinfo>
#include "../common/WLogger.h"
#include "../modules/template/WMTemplate.h"
#include "../modules/data/WMData.h" // this is the ONLY module with a special meaning.
#include "../modules/coordinateSystem/WMCoordinateSystem.h"
#include "../modules/boundingBox/WMBoundingBox.h"
......@@ -72,6 +73,7 @@ void WModuleFactory::load()
boost::unique_lock< boost::shared_mutex > lock = boost::unique_lock< boost::shared_mutex >( m_prototypesLock );
// currently the prototypes are added by hand. This will be done automatically later.
m_prototypes.insert( boost::shared_ptr< WModule >( new WMTemplate() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMBoundingBox() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMData() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMNavSlices() ) );
......
This diff is collapsed.
......@@ -22,30 +22,35 @@
//
//---------------------------------------------------------------------------
#ifndef WMTEST_H
#define WMTEST_H
#ifndef WMTEMPLATE_H
#define WMTEMPLATE_H
#include <string>
#include <osg/Geode>
#include "../../kernel/WModule.h"
#include "../../kernel/WModuleInputData.h"
#include "../../kernel/WModuleOutputData.h"
/**
* Simple module for testing some WKernel functionality.
* This module is intended to be a simple template and example module. It can be used for fast creation of new modules by copying and refactoring
* the files. It shows the basic usage of properties, update callbacks and how to wait for data.
* \ingroup modules
*/
class WMTest: public WModule
class WMTemplate: public WModule
{
public:
/**
* Default constructor.
*/
WMTest();
WMTemplate();
/**
* Destructor.
*/
virtual ~WMTest();
virtual ~WMTemplate();
/**
* Gives back the name of this module.
......@@ -62,7 +67,7 @@ public:
/**
* Due to the prototype design pattern used to build modules, this method returns a new instance of this method. NOTE: it
* should never be initialized or modified in some other way. A simple new instance is required.
*
*
* \return the prototype used to create every module in OpenWalnut.
*/
virtual boost::shared_ptr< WModule > factory() const;
......@@ -74,8 +79,109 @@ protected:
*/
virtual void moduleMain();
/**
* Initialize the connectors this module is using.
*/
virtual void connectors();
/**
* Initialize the properties for this module.
*/
virtual void properties();
/**
* The root node used for this modules graphics. For OSG nodes, always use osg::ref_ptr to ensure proper resource management.
*/
osg::ref_ptr<osg::Geode> m_rootNode;
private:
/**
* An input connector used to get datasets from other modules. The connection management between connectors must not be handled by the module.
*/
boost::shared_ptr< WModuleInputData< WDataSetSingle > > m_input;
/**
* This is a pointer to the dataset the module is currently working on.
*/
boost::shared_ptr< WDataSetSingle > m_dataSet;
/**
* A condition used to notify about changes in several properties.
*/
boost::shared_ptr< WCondition > propCondition;
/**
* En/Disables an feature.
*/
WPropBool m_enableFeature;
/**
* An integer value.
*/
WPropInt m_anInteger;
/**
* A double value.
*/
WPropDouble m_aDouble;
/**
* A string.
*/
WPropString m_aString;
/**
* A filename.
*/
WPropFilename m_aFile;
/**
* A color.
*/
WPropColor m_aColor;
/**
* Node callback to change the color of the shapes inside the root node. For more details on this class, refer to the documentation in
* moduleMain().
*/
class SafeUpdateCallback : public osg::NodeCallback
{
public: // NOLINT
SafeUpdateCallback( WMTemplate* module ): m_module( module ) {};
/**
* operator () - called during the update traversal.
*
* \param node the osg node
* \param nv the node visitor
*/
virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
/**
* Pointer used to access members of the module to modify the node.
*/
WMTemplate* m_module;
};
/**
* This shows how to write custom constraints for your modules. Please refer to the documentation in properties() for more details.
*
* \note: always use WPVBaseTypes to specialize the PropertyVariable template.
*/
class StringLength: public WPropertyVariable< WPVBaseTypes::PV_STRING >::PropertyConstraint
{
/**
* You need to overwrite this method. It decides whether the specified new value should be accepted or not.
*
* \param property the property thats going to be changed.
* \param value the new value
*
* \return true if the new value is OK.
*/
virtual bool accept( boost::shared_ptr< WPropertyVariable< WPVBaseTypes::PV_STRING > > property, WPVBaseTypes::PV_STRING value );
};
};
#endif // WMTEST_H
#endif // WMTEMPLATE_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 <iostream>
#include <string>
#include <osg/ShapeDrawable>
#include <osg/Group>
#include <osg/Geode>
#include "WMTest.h"
#include "../../kernel/WKernel.h"
WMTest::WMTest():
WModule()
{
// initialize members
}
WMTest::~WMTest()
{
// cleanup
}
boost::shared_ptr< WModule > WMTest::factory() const
{
return boost::shared_ptr< WModule >( new WMTest() );
}
const std::string WMTest::getName() const
{
return "Test Module";
}
const std::string WMTest::getDescription() const
{
return "This module is for testing and development";
}
void WMTest::moduleMain()
{
// signal ready state
ready();
// load the sample scene.
osg::ref_ptr<osg::Geode> sceneDataGeode = new osg::Geode();
// 20 units into the screen
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Box( osg::Vec3( -6, 5, -20 ), 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Sphere( osg::Vec3( -3, 5, -20 ), 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Cone( osg::Vec3( 0, 5, -20 ), 1.0, 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Cylinder( osg::Vec3( 3, 5, -20 ), 1.0, 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Capsule( osg::Vec3( 6, 5, -20 ), 1.0, 1.0 ) ) );
// 25 units into the screen
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Box( osg::Vec3( -6, 0, -25 ), 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Sphere( osg::Vec3( -3, 0, -25 ), 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Cone( osg::Vec3( 0, 0, -25 ), 1.0, 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Cylinder( osg::Vec3( 3, 0, -25 ), 1.0, 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Capsule( osg::Vec3( 6, 0, -25 ), 1.0, 1.0 ) ) );
// 30 units into the screen
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Box( osg::Vec3( -6, -5, -30 ), 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Sphere( osg::Vec3( -3, -5, -30 ), 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Cone( osg::Vec3( 0, -5, -30 ), 1.0, 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Cylinder( osg::Vec3( 3, -5, -30 ), 1.0, 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Capsule( osg::Vec3( 6, -5, -30 ), 1.0, 1.0 ) ) );
// 35 units into the screen
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Box( osg::Vec3( -6, -10, -35 ), 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Sphere( osg::Vec3( -3, -10, -35 ), 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Cone( osg::Vec3( 0, -10, -35 ), 1.0, 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Cylinder( osg::Vec3( 3, -10, -35 ), 1.0, 1.0 ) ) );
sceneDataGeode->addDrawable(
new osg::ShapeDrawable( new osg::Capsule( osg::Vec3( 6, -10, -35 ), 1.0, 1.0 ) ) );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->addChild( sceneDataGeode );
// Since the modules run in a separate thread: such loops are possible
while ( !m_FinishRequested )
{
// do fancy stuff
sleep( 1 );
}
// clean up stuff
}
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