Commit 09ecec04 authored by T.J. Corona's avatar T.J. Corona

Develop registration process for managers and plugins.

This commit introduces smtk::common::Registry, a reference counted object
that manages the lifetime of the registration of a logical collection of
smtk resources & operations (usually denoted by its own namespace) and
instances of managers. It also introduces the singleton PluginManager for
centralizing plugin registration. Finally, it removes the concept of
environments that hold static managers and automatic registration.
parent 8f71fc71
......@@ -71,9 +71,7 @@ target_link_libraries(TemplateEditor
LINK_PRIVATE
smtkCore
smtkQtExt
smtkEnvironment
smtkOperationEnvironment
smtkPolygonSessionEnvironment
smtkPolygonSession
)
# ==============================================================================
......
......@@ -14,12 +14,16 @@
#include "smtk/operation/Manager.h"
#include "smtk/operation/operators/ReadResource.h"
#include "smtk/resource/Manager.h"
#include "smtk/attribute/Attribute.h"
#include "smtk/attribute/FileItem.h"
#include "smtk/attribute/IntItem.h"
#include "smtk/attribute/ResourceItem.h"
#include "smtk/environment/Environment.h"
#include "smtk/bridge/polygon/Registrar.h"
#include "smtk/common/Registry.h"
int main(int argc, char* argv[])
{
......@@ -40,7 +44,11 @@ int main(int argc, char* argv[])
if (argc >= 3)
{
char* filename = argv[2];
auto operMgr = smtk::environment::OperationManager::instance();
auto rsrcMgr = smtk::resource::Manager::create();
auto operMgr = smtk::operation::Manager::create();
auto polygonRegistry = smtk::common::Registry<smtk::bridge::polygon::Registrar,
smtk::resource::Manager, smtk::operation::Manager>(rsrcMgr, operMgr);
auto rdr = operMgr->create<smtk::operation::ReadResource>();
if (rdr)
{
......@@ -50,7 +58,6 @@ int main(int argc, char* argv[])
int(smtk::operation::Operation::Outcome::SUCCEEDED))
{
auto rsrc = result->findResource("resource")->value();
auto rsrcMgr = smtk::environment::ResourceManager::instance();
rsrcMgr->add(rsrc);
}
}
......
......@@ -123,6 +123,7 @@ install(
SharedFromThis.h
SharedPtr.h
SystemConfig.h
TupleTraits.h
DESTINATION
include/smtk/${SMTK_VERSION}/smtk
)
......@@ -167,13 +168,6 @@ if (SMTK_ENABLE_PYTHON_WRAPPING)
set(VTK_INSTALL_PYTHON_MODULES_DIR ${SMTK_PYTHON_MODULEDIR})
endif()
################################################################################
# Build smtk environment
# Construct an interface for applications that require a singleton
# representation of SMTK that uses auto-registration.
################################################################################
add_subdirectory(environment)
################################################################################
# Build smtk extensions
# Add libraries that extend other projects to have support for SMTK.
......
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//=========================================================================
#ifndef __smtk_TupleTraits_h
#define __smtk_TupleTraits_h
#include <tuple>
namespace smtk
{
namespace detail
{
/// If T is in Tuple, return std::tuple<T>. Otherwise, return std::tuple<>.
///
/// Examples:
/// tuple_if_unique<int, std::tuple<float, double>::type == std::tuple<int>
/// tuple_if_unique<int, std::tuple<int, double>::type == std::tuple<>
template <typename T, typename Tuple>
struct tuple_if_unique;
template <typename T>
struct tuple_if_unique<T, std::tuple<> >
{
using type = std::tuple<T>;
};
template <typename T, typename U, typename... Ts>
struct tuple_if_unique<T, std::tuple<U, Ts...> >
{
using type = typename tuple_if_unique<T, std::tuple<Ts...> >::type;
};
template <typename T, typename... Ts>
struct tuple_if_unique<T, std::tuple<T, Ts...> >
{
using type = std::tuple<>;
};
/// If T is a tuple containing a single type, return the type it contians.
/// Otherwise, return T.
///
/// Examples:
/// untuple<int>::type == int
/// untuple<std::tuple<int>::type == int
template <typename T>
struct untuple
{
using type = T;
};
template <typename T>
struct untuple<std::tuple<T> >
{
using type = typename untuple<T>::type;
};
}
/// Takes a tuple of tuples and types and returns a tuple of the tuple contents
/// and the plain types.
///
/// Examples:
/// flatten_tuple<std::tuple<int, float>>::type == std::tuple<int, float>
/// flatten_tuple<std::tuple<int, std::tuple<float, float>>>::type ==
/// std::tuple<int, float, float>
template <typename T>
struct flatten_tuple;
template <>
struct flatten_tuple<std::tuple<> >
{
using type = std::tuple<>;
};
template <typename T, typename... Args>
struct flatten_tuple<std::tuple<T, Args...> >
{
using type = decltype(
std::tuple_cat(std::declval<std::tuple<typename detail::untuple<T>::type> >(),
std::declval<typename flatten_tuple<std::tuple<Args...> >::type>()));
};
/// Takes a tuple of potentially duplicate types and returns a tuple with the
/// duplicate types removed.
///
/// Examples:
/// unique_tuple<std::tuple<int, float>>::type == std::tuple<int, float>
/// unique_tuple<std::tuple<int, int, float>>::type == std::tuple<int, float>
template <typename T, typename... Args>
struct unique_tuple;
template <>
struct unique_tuple<std::tuple<> >
{
using type = std::tuple<>;
};
template <typename T>
struct unique_tuple<std::tuple<T> >
{
using type = std::tuple<T>;
};
template <typename T, typename... Args>
struct unique_tuple<std::tuple<T, Args...> >
{
using type = decltype(
std::tuple_cat(std::declval<typename detail::tuple_if_unique<T, std::tuple<Args...> >::type>(),
std::declval<typename unique_tuple<std::tuple<Args...> >::type>()));
};
/// Takes a type and a tuple of types and returns a tuple with all of the
/// original types sans the input type.
///
/// Examples:
/// remove_from_tuple<bool, std::tuple<int, float>>::type ==
/// std::tuple<int, float>
/// remove_from_tuple<int, std::tuple<int, float>>::type == std::tuple<float>
template <typename T, typename Tuple>
struct remove_from_tuple;
template <typename T, typename... Args>
struct remove_from_tuple<T, std::tuple<T, Args...> >
{
using type = decltype(std::declval<typename remove_from_tuple<T, std::tuple<Args...> >::type>());
};
template <typename T, typename X, typename... Args>
struct remove_from_tuple<T, std::tuple<X, Args...> >
{
using type = decltype(std::tuple_cat(std::declval<std::tuple<X> >(),
std::declval<typename remove_from_tuple<T, std::tuple<Args...> >::type>()));
};
template <typename T>
struct remove_from_tuple<T, std::tuple<> >
{
using type = std::tuple<>;
};
}
#endif
......@@ -109,8 +109,7 @@ set(attributeHeaders
ReferenceItemDefinition.h
RefItem.h
RefItemDefinition.h
RegisterOperations.h
RegisterResources.h
Registrar.h
ResourceItem.h
ResourceItemDefinition.h
SearchStyle.h
......@@ -157,8 +156,7 @@ set(attributeSrcs
RefItemDefinition.cxx
ReferenceItem.cxx
ReferenceItemDefinition.cxx
RegisterOperations.cxx
RegisterResources.cxx
Registrar.cxx
ResourceItem.cxx
ResourceItemDefinition.cxx
StringItem.cxx
......@@ -172,8 +170,6 @@ set(attributeSrcs
#install the headers
smtk_public_headers(${attributeHeaders})
add_subdirectory(environment)
if (SMTK_ENABLE_PYTHON_WRAPPING)
add_subdirectory(pybind11)
endif()
......
//=============================================================================
//
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
//=============================================================================
#include "smtk/attribute/RegisterOperations.h"
namespace smtk
{
namespace attribute
{
void registerOperations(smtk::operation::Manager::Ptr& operationManager)
{
(void)operationManager;
}
void unregisterOperations(smtk::operation::Manager::Ptr& operationManager)
{
(void)operationManager;
}
}
}
......@@ -9,7 +9,7 @@
// PURPOSE. See the above copyright notice for more information.
//
//=============================================================================
#include "smtk/attribute/RegisterResources.h"
#include "smtk/attribute/Registrar.h"
#include "smtk/attribute/Collection.h"
......@@ -17,13 +17,12 @@ namespace smtk
{
namespace attribute
{
void registerResources(smtk::resource::Manager::Ptr& resourceManager)
void Registrar::registerTo(const smtk::resource::Manager::Ptr& resourceManager)
{
resourceManager->registerResource<smtk::attribute::Collection>();
}
void unregisterResources(smtk::resource::Manager::Ptr& resourceManager)
void Registrar::unregisterFrom(const smtk::resource::Manager::Ptr& resourceManager)
{
resourceManager->unregisterResource<smtk::attribute::Collection>();
}
......
......@@ -7,8 +7,8 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//=========================================================================
#ifndef __smtk_attribute_RegisterResources_h
#define __smtk_attribute_RegisterResources_h
#ifndef __smtk_attribute_Registrar_h
#define __smtk_attribute_Registrar_h
#include "smtk/CoreExports.h"
......@@ -18,9 +18,12 @@ namespace smtk
{
namespace attribute
{
SMTKCORE_EXPORT void registerResources(smtk::resource::Manager::Ptr&);
SMTKCORE_EXPORT void unregisterResources(smtk::resource::Manager::Ptr&);
class SMTKCORE_EXPORT Registrar
{
public:
static void registerTo(const smtk::resource::Manager::Ptr&);
static void unregisterFrom(const smtk::resource::Manager::Ptr&);
};
}
}
......
set(environmentSrcs
Environment.cxx
)
add_library(smtkAttributeEnvironment ${environmentSrcs})
target_link_libraries(smtkAttributeEnvironment PUBLIC smtkCore smtkEnvironment)
smtk_export_header(smtkAttributeEnvironment Exports.h)
smtk_install_library(smtkAttributeEnvironment)
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//=========================================================================
#include "smtk/environment/Environment.h"
#include "smtk/attribute/RegisterOperations.h"
#include "smtk/attribute/RegisterResources.h"
#include "smtk/attribute/environment/Environment.h"
namespace
{
static unsigned int registerToEnvironmentCounter = 0;
}
namespace smtk
{
namespace attribute
{
namespace environment
{
RegisterToEnvironment::RegisterToEnvironment()
{
if (registerToEnvironmentCounter++ == 0)
{
registerOperations(smtk::environment::OperationManager::instance());
registerResources(smtk::environment::ResourceManager::instance());
}
}
RegisterToEnvironment::~RegisterToEnvironment()
{
if (--registerToEnvironmentCounter == 0)
{
unregisterOperations(smtk::environment::OperationManager::instance());
unregisterResources(smtk::environment::ResourceManager::instance());
}
}
}
}
}
//=========================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//=========================================================================
#ifndef __smtk_attribute_environment_Environment_h
#define __smtk_attribute_environment_Environment_h
#include "smtk/attribute/environment/Exports.h"
namespace smtk
{
namespace attribute
{
namespace environment
{
struct SMTKATTRIBUTEENVIRONMENT_EXPORT RegisterToEnvironment
{
RegisterToEnvironment();
~RegisterToEnvironment();
RegisterToEnvironment(const RegisterToEnvironment&) = delete;
RegisterToEnvironment& operator=(const RegisterToEnvironment&) = delete;
};
// Uses schwartz counter idiom for management
static RegisterToEnvironment registerToEnvironment;
}
}
}
#endif
......@@ -24,7 +24,6 @@ foreach(tst ${attributeTests})
add_executable(${tst} ${tst}.cxx)
target_link_libraries(${tst}
smtkCore
smtkAttributeEnvironment
${Boost_LIBRARIES}
)
add_test(NAME ${tst} COMMAND ${tst} ${${tst}_ARGS})
......@@ -74,8 +73,4 @@ smtk_unit_tests(
SOURCES ${unit_tests}
LIBRARIES
smtkCore
smtkEnvironment
smtkAttributeEnvironment
smtkOperationEnvironment
smtkPolygonSessionEnvironment
)
......@@ -25,8 +25,6 @@
#include "smtk/model/EntityTypeBits.h"
#include "smtk/environment/Environment.h"
#include "smtk/io/AttributeReader.h"
#include "smtk/io/AttributeWriter.h"
#include "smtk/io/Logger.h"
......@@ -57,8 +55,7 @@ int main(int argc, char* argv[])
std::cerr << "Usage: " << argv[0] << " FullAttributeFilename InstanceOnlyFileName\n";
return -1;
}
auto rsrcMgr = smtk::environment::ResourceManager::instance();
auto sysptr = rsrcMgr->create<smtk::attribute::Collection>();
auto sysptr = smtk::attribute::Collection::create();
smtk::attribute::Collection& collection(*sysptr.get());
std::cout << "Collection Created\n";
// Lets add some analyses
......@@ -202,7 +199,7 @@ int main(int argc, char* argv[])
}
// Sanity check readback
auto inputSysptr = rsrcMgr->create<smtk::attribute::Collection>();
auto inputSysptr = smtk::attribute::Collection::create();
smtk::io::AttributeReader reader;
if (reader.read(inputSysptr, argv[1], logger))
{
......
......@@ -10,8 +10,6 @@
#include "smtk/PublicPointerDefs.h"
#include "smtk/environment/Environment.h"
#include "smtk/operation/operators/ReadResource.h"
#include "smtk/model/Manager.h"
......@@ -31,12 +29,18 @@
#include "smtk/attribute/RefItemDefinition.h"
#include "smtk/attribute/ReferenceItem.h"
#include "smtk/attribute/ReferenceItemDefinition.h"
#include "smtk/attribute/Registrar.h"
#include "smtk/attribute/StringItem.h"
#include "smtk/attribute/StringItemDefinition.h"
#include "smtk/attribute/VoidItemDefinition.h"
#include "smtk/common/Registry.h"
#include "smtk/io/Logger.h"
#include "smtk/operation/Manager.h"
#include "smtk/resource/Manager.h"
#include "smtk/attribute/json/jsonDirectoryItem.h"
#include "smtk/attribute/json/jsonItem.h"
#include "smtk/attribute/json/jsonReferenceItem.h"
......@@ -64,8 +68,12 @@ int unitJsonItems(int argc, char* argv[])
argc = 2;
argv = &dataArgs[0];
}
auto rsrcMgr = smtk::environment::ResourceManager::instance();
auto operMgr = smtk::environment::OperationManager::instance();
auto rsrcMgr = smtk::resource::Manager::create();
auto operMgr = smtk::operation::Manager::create();
auto registry = smtk::common::Registry<smtk::attribute::Registrar, smtk::resource::Manager,
smtk::operation::Manager>(rsrcMgr, operMgr);
smtk::resource::ResourceArray rsrcs;
for (int i = 1; i < argc; i++)
{
......
......@@ -134,7 +134,7 @@ set(_module_src
)
set(discreteSessionSrcs
RegisterSession.cxx
Registrar.cxx
Resource.cxx
Session.cxx
Operation.cxx
......@@ -156,7 +156,7 @@ set(discreteSessionSrcs
)
set(discreteSessionHeaders
RegisterSession.h
Registrar.h
Resource.h
Session.h
Operation.h
......@@ -254,8 +254,6 @@ smtk_public_headers(${discreteSessionHeaders} ${DiscreteModelHeaders})
#install the library and exports the library when used from a build tree
smtk_install_library(smtkDiscreteSession)
add_subdirectory(environment)
if(SMTK_ENABLE_PARAVIEW_SUPPORT AND SMTK_ENABLE_DISCRETE_SESSION)
add_subdirectory(plugin)
endif()
......
......@@ -9,7 +9,7 @@
// PURPOSE. See the above copyright notice for more information.
//
//=============================================================================
#include "smtk/bridge/discrete/RegisterSession.h"
#include "smtk/bridge/discrete/Registrar.h"
#include "smtk/bridge/discrete/operators/CreateEdgesOperation.h"
#include "smtk/bridge/discrete/operators/EdgeOperation.h"
......@@ -39,13 +39,27 @@ namespace bridge
namespace discrete
{
namespace
{
typedef std::tuple<CreateEdgesOperation, EdgeOperation, EntityGroupOperation, GrowOperation,
ImportOperation, LegacyReadResource, MergeOperation, ReadOperation, ReadResource, RemoveModel,
SetProperty, SplitFaceOperation, WriteOperation, WriteResource>
OperationList;
}
void Registrar::registerTo(const smtk::resource::Manager::Ptr& resourceManager)
{
resourceManager->registerResource<smtk::bridge::discrete::Resource>(readResource, writeResource);
// When moving from CJSON to nlohmann::json, the file format for discrete
// models changed slightly. This call facilitates reading the old format
// using our new tools.
resourceManager->addLegacyReader("discrete", legacyReadResource);
}
void registerOperations(smtk::operation::Manager::Ptr& operationManager)
void Registrar::registerTo(const smtk::operation::Manager::Ptr& operationManager)
{
// Register operations
operationManager->registerOperations<OperationList>();
smtk::operation::ImporterGroup(operationManager)
......@@ -62,25 +76,15 @@ void registerOperations(smtk::operation::Manager::Ptr& operationManager)
.registerOperation<smtk::bridge::discrete::Resource, smtk::bridge::discrete::WriteResource>();
}
void registerResources(smtk::resource::Manager::Ptr& resourceManager)
void Registrar::unregisterFrom(const smtk::resource::Manager::Ptr& resourceManager)
{
resourceManager->registerResource<smtk::bridge::discrete::Resource>(readResource, writeResource);
// When moving from CJSON to nlohmann::json, the file format for discrete
// models changed slightly. This call facilitates reading the old format
// using our new tools.
resourceManager->addLegacyReader("discrete", legacyReadResource);
resourceManager->unregisterResource<smtk::bridge::discrete::Resource>();
}
void unregisterOperations(smtk::operation::Manager::Ptr& operationManager)
void Registrar::unregisterFrom(const smtk::operation::Manager::Ptr& operationManager)
{
operationManager->unregisterOperations<OperationList>();
}
void unregisterResources(smtk::resource::Manager::Ptr& resourceManager)
{
resourceManager->unregisterResource<smtk::bridge::discrete::Resource>();
}
}
}
}
......@@ -7,11 +7,14 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//=========================================================================
#ifndef __smtk_session_discrete_RegisterSession_h
#define __smtk_session_discrete_RegisterSession_h
#ifndef __smtk_session_discrete_Registrar_h
#define __smtk_session_discrete_Registrar_h
#include "smtk/bridge/discrete/Exports.h"
#include "smtk/model/Registrar.h"
#include "smtk/operation/Manager.h"
#include "smtk/operation/Registrar.h"
#include "smtk/resource/Manager.h"
namespace smtk
......@@ -21,11 +24,17 @@ namespace bridge
namespace discrete
{
SMTKDISCRETESESSION_EXPORT void registerOperations(smtk::operation::Manager::Ptr&);
SMTKDISCRETESESSION_EXPORT void registerResources(smtk::resource::Manager::Ptr&);
class SMTKDISCRETESESSION_EXPORT Registrar
{
public:
using Dependencies = std::tuple<operation::Registrar, model::Registrar>;
static void registerTo(const smtk::operation::Manager::Ptr&);
static void unregisterFrom(const smtk::operation::Manager::Ptr&);
SMTKDISCRETESESSION_EXPORT void unregisterOperations(smtk::operation::Manager::Ptr&);
SMTKDISCRETESESSION_EXPORT void unregisterResources(smtk::resource::Manager::Ptr&);
static void registerTo(const smtk::resource::Manager::Ptr&);
static void unregisterFrom(const smtk::resource::Manager::Ptr&);
};
}
}
}
......
set(environmentSrcs
Environment.cxx
)
add_library(smtkDiscreteSessionEnvironment ${environmentSrcs})
target_link_libraries(smtkDiscreteSessionEnvironment
PUBLIC
smtkEnvironment