Commit 591edec8 authored by Hossain Mahmud's avatar Hossain Mahmud
Browse files

failed variadic until give-up

parent 75aa45ba
......@@ -9,9 +9,11 @@ LIST(APPEND CampvisModulesHeaders
modulesapi.h
gen_pipelineregistration.h
pipelinefactory.h
processorfactory.h
)
LIST(APPEND CampvisModulesSources
pipelinefactory.cpp
processorfactory.cpp
)
......
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#include "processorfactory.h"
//#include "gen_processorregistration.h"
#include <sstream>
namespace campvis {
// declare one single symbol for the ProcessorFactory singleton
tbb::atomic<ProcessorFactory*> ProcessorFactory::_singleton;
ProcessorFactory& ProcessorFactory::getRef() {
if (_singleton == 0) {
std::cout << "creating ProcessorFactory...\n";
ProcessorFactory* tmp = new ProcessorFactory();
if (_singleton.compare_and_swap(tmp, 0) != 0) {
delete tmp;
}
}
return *_singleton;
}
void ProcessorFactory::deinit() {
delete _singleton;
_singleton = nullptr;
}
template<typename... Args>
std::vector<std::string> ProcessorFactory::getRegisteredProcessors() const {
tbb::spin_mutex::scoped_lock lock(_mutex);
std::vector<std::string> toReturn;
toReturn.reserve(_processorMap.size());
for (auto it = _processorMap.begin(); it != _processorMap.end(); ++it)
toReturn.push_back(it->first);
return toReturn;
}
template<typename... Args>
AbstractProcessor* ProcessorFactory::createProcessor(const std::string& id, Args... args) const {
tbb::spin_mutex::scoped_lock lock(_mutex);
auto it = _processorMap.find(id);
if (it == _processorMap.end())
return nullptr;
else
return (it->second)._createFunction(args);
}
}
// ================================================================================================
//
// This file is part of the CAMPVis Software Framework.
//
// If not explicitly stated otherwise: Copyright (C) 2012-2014, all rights reserved,
// Christian Schulte zu Berge <christian.szb@in.tum.de>
// Chair for Computer Aided Medical Procedures
// Technische Universitaet Muenchen
// Boltzmannstr. 3, 85748 Garching b. Muenchen, Germany
//
// For a full list of authors and contributors, please refer to the file "AUTHORS.txt".
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
//
// ================================================================================================
#ifndef PROCESSORFACTORY_H__
#define PROCESSORFACTORY_H__
#include "cgt/logmanager.h"
#include "cgt/singleton.h"
#include <tbb/atomic.h>
#include <tbb/spin_mutex.h>
#include "modules/modulesapi.h"
#include <map>
#include <string>
#include <vector>
#include <functional>
namespace campvis {
class AbstractProcessor;
class DataContainer;
//template<typename... Args>
class VArgs {
private:
public:
//std::string _processorName;
//Args*... type;
//void *func;
AbstractProcessor*(*_createFunction)(...);
template<typename... Args>
VArgs(std::function<AbstractProcessor*(Args...)> *_createFunction) {
//this->_processorName = _processorName;
this->_createFunction = _createFunction;
}
//template<typename... Args>
//VArgs(std::function < AbstractProcessor*(Args*...)> *create) {
// this->create = create;
//}
//template<typename... Args>
//std::function < AbstractProcessor*(Args*...)> *create;
//std::map< std::string, std::function < AbstractProcessor*(Args...)>> _processorMap;
};
/**
* Factory for creating processors by their name.
* Using some template-magic, ProcessorFactory is able to register processors during static
* initialization in cooperation with the ProcessorRegistrar.
*
* \note ProcessorFactory is a thread-safe lazy-instantiated singleton.
*/
class CAMPVIS_MODULES_API ProcessorFactory {
public:
/**
* Returns a reference to the ProcessorFactory singleton.
* Creates the singleton if necessary
* \return *_singleton
*/
static ProcessorFactory& getRef();
static void deinit();
template<typename... Args>
std::vector<std::string> getRegisteredProcessors() const;
template<typename... Args>
AbstractProcessor* createProcessor(const std::string& id, Args... args) const;
/**
* Statically registers the processor of type T using \a callee as factory method.
* \note The template instantiation of ProcessorRegistrar takes care of calling this method.
* \param callee Factory method to call to create an instance of type T
* \return The registration index.
*/
template<typename T, typename... Args>
size_t registerProcessor(AbstractProcessor*(callee)(Args...)) {
tbb::spin_mutex::scoped_lock lock(_mutex);
auto it = _processorMap.lower_bound(T::getId());
if (it == _processorMap.end() || it->first != T::getId()) {
_processorMap.insert(it, std::make_pair(T::getId(), VArgs(callee)));
}
else {
cgtAssert(false, "Registered two processors with the same ID.");
}
return _processorMap.size();
}
private:
mutable tbb::spin_mutex _mutex;
static tbb::atomic<ProcessorFactory*> _singleton; ///< the singleton object
std::map< std::string, VArgs> _processorMap;
};
// ================================================================================================
template<typename T, typename... Args>
class ProcessorRegistrar {
public:
/**
* Static factory method for creating the processor of type T.
* \param args DataContainer for the created processor to work on.
* \return A newly created processor of type T. Caller has to take ownership of the pointer.
*/
static AbstractProcessor* create(Args... args) {
size_t argc = sizeof...(args);
//return new T(args);
}
private:
/// static helper field to ensure registration at static initialization time.
static const size_t _factoryId;
};
template<typename T, typename... Args>
const size_t ProcessorRegistrar<T, Args...>::_factoryId = ProcessorFactory::getRef().registerProcessor<T, Args...>(&ProcessorRegistrar<T, Args...>::create);
}
#endif // PROCESSORFACTORY_H__
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