WModuleFactory.cpp 5.85 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
//---------------------------------------------------------------------------
//
// 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/>.
//
//---------------------------------------------------------------------------

25
#include <set>
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
26
#include <string>
27 28 29

#include "../common/WLogger.h"

30
#include "../modules/data/WMData.h"
31 32 33 34 35 36 37 38 39
#include "../modules/navSlices/WMNavSlices.h"
#include "../modules/coordinateSystem/WMCoordinateSystem.h"
#include "../modules/fiberDisplay/WMFiberDisplay.h"
#include "../modules/fiberCulling/WMFiberCulling.h"
#include "../modules/fiberClustering/WMFiberClustering.h"
#include "../modules/marchingCubes/WMMarchingCubes.h"
#include "../modules/eegTest/WMEEGTest.h"

#include "exceptions/WPrototypeUnknown.h"
40
#include "exceptions/WPrototypeNotUnique.h"
41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
#include "WModuleFactory.h"

// factory instance as singleton
boost::shared_ptr< WModuleFactory > WModuleFactory::m_instance = boost::shared_ptr< WModuleFactory >();

WModuleFactory::WModuleFactory()
{
    // initialize members
}

WModuleFactory::~WModuleFactory()
{
    // cleanup
}

57 58 59 60 61 62 63 64 65
void WModuleFactory::load()
{
    // load modules
    WLogger::getLogger()->addLogMessage( "Loading Modules", "ModuleFactory", LL_INFO );

    // operation must be exclusive
    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.
66
    m_prototypes.insert( boost::shared_ptr< WModule >( new WMData() ) );
67 68 69 70 71 72 73 74 75 76 77 78 79 80
    m_prototypes.insert( boost::shared_ptr< WModule >( new WMNavSlices() ) );
    m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberDisplay() ) );
    m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberCulling() ) );
    m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberClustering() ) );
    m_prototypes.insert( boost::shared_ptr< WModule >( new WMCoordinateSystem() ) );
    m_prototypes.insert( boost::shared_ptr< WModule >( new WMEEGTest() ) );
    m_prototypes.insert( boost::shared_ptr< WModule >( new WMMarchingCubes() ) );

    lock.unlock();

    // for this a read lock is sufficient
    boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );

    // initialize every module in the set
81 82 83
    std::set< std::string > names;  // helper to find duplicates
    for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypes.begin(); listIter != m_prototypes.end();
            ++listIter )
84
    {
85
        WLogger::getLogger()->addLogMessage( "Loading module: \"" + ( *listIter )->getName() + "\"", "ModuleFactory", LL_DEBUG );
Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
86

87 88 89
        // that should not happen. Names should not occur multiple times since they are unique
        if ( names.count( ( *listIter )->getName() ) )
        {
90
            throw WPrototypeNotUnique( "Module \"" + ( *listIter )->getName() + "\" is not unique. Modules have to have a unique name." );
91 92 93 94
        }
        names.insert( ( *listIter )->getName() );

        ( *listIter )->initialize();
95 96 97 98 99
    }

    slock.unlock();
}

100 101
boost::shared_ptr< WModule > WModuleFactory::create( boost::shared_ptr< WModule > prototype )
{
102 103 104 105 106 107
    // for this a read lock is sufficient
    boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );

    // ensure this one is a prototype and nothing else
    if ( m_prototypes.count( prototype ) == 0 )
    {
108
        throw WPrototypeUnknown( "Could not clone module \"" + prototype->getName() + "\" since it is no prototype." );
109 110 111 112
    }

    slock.unlock();

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
    // call prototypes factory function
    boost::shared_ptr< WModule > clone = boost::shared_ptr< WModule >( prototype->factory() );
    clone->initialize();

    return clone;
}

boost::shared_ptr< WModuleFactory > WModuleFactory::getModuleFactory()
{
    if ( !m_instance )
    {
        m_instance = boost::shared_ptr< WModuleFactory >( new WModuleFactory() );
    }

    return m_instance;
}

130 131 132 133 134 135

const boost::shared_ptr< WModule > WModuleFactory::getPrototypeByName( std::string name )
{
    // for this a read lock is sufficient
    boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );

Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
136
    // find first and only prototype (ensured during load())
137 138 139 140 141 142 143 144 145 146 147
    boost::shared_ptr< WModule > ret = boost::shared_ptr< WModule >();
    for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypes.begin(); listIter != m_prototypes.end();
            ++listIter )
    {
        if ( ( *listIter )->getName() == name )
        {
            ret = ( *listIter );
            break;
        }
    }

Sebastian Eichelbaum's avatar
[STYLE]  
Sebastian Eichelbaum committed
148
    slock.unlock();
149 150 151 152

    // if not found -> throw
    if ( ret == boost::shared_ptr< WModule >() )
    {
153
        throw WPrototypeUnknown( "Could not find prototype \"" + name + "\"." );
154 155 156 157 158 159 160 161 162 163 164
    }

    return ret;
}

const boost::shared_ptr< WModule > WModuleFactory::getPrototypeByInstance( boost::shared_ptr< WModule > instance )
{
    // TODO(ebaum): implement
    WLogger::getLogger()->addLogMessage( "Searching prototype by instance, NOT YET IMPLEMENTED", "ModuleFactory", LL_WARNING );
}