Commit 141e91b7 authored by T.J. Corona's avatar T.J. Corona

Introduce ItemDefinitionManager

The ItemDefinitionManager is a new manager with which Registrars can interact
to register custom item definitions.
parent 3029aa96
......@@ -126,12 +126,11 @@ Added a class for utility methods. The current ones include:
SMTK's attribute system now supports the registration of user-defined attribute items and definitions by overloading `smtk::attribute::CustomItem` and `smtk::attribute::CustomItemDefinition`, respectively. The registration of custom item definition types must occur before the attribute is serialized. Custom item definitions can be listed in plugins' Registrar implementations as follows:
```c++
void Registrar::registerTo(const smtk::resource::Manager::Ptr& resourceManager)
void Registrar::registerTo(const smtk::attribute::ItemDefinitionManager::Ptr& manager)
{
typedef std::tuple<CustomItemDefinition1, CustomItemDefinition2> CustomItemDefinitions;
smtk::attribute::CustomItemDefinitions(resourceManager)
.registerDefinitions<CustomItemDefinitions>();
manager->registerDefinitions<CustomItemDefinitions>();
}
```
......
......@@ -109,6 +109,7 @@ set(attributeHeaders
IntItemDefinition.h
Item.h
ItemDefinition.h
ItemDefinitionManager.h
ModelEntityItem.h
ModelEntityItemDefinition.h
PathGrammar.h
......@@ -157,6 +158,7 @@ set(attributeSrcs
IntItemDefinition.cxx
Item.cxx
ItemDefinition.cxx
ItemDefinitionManager.cxx
ModelEntityItem.cxx
ModelEntityItemDefinition.cxx
ReferenceItem.cxx
......
......@@ -80,49 +80,6 @@ public:
return ItemPtr(new ItemType(owningItem, position, subGroupPosition));
}
};
/// Convenience code for simplifying the regsitration of custom item definitions
/// with a resource manager.
class SMTKCORE_EXPORT CustomItemDefinitions
{
public:
CustomItemDefinitions(std::shared_ptr<smtk::resource::Manager> manager)
: m_manager(manager)
{
}
template <typename CustomDefinitionTypes>
bool registerDefinitions()
{
auto registerCustomTypes = [](
const smtk::resource::Resource& resource, smtk::resource::EventType eventType) -> void {
if (eventType == smtk::resource::EventType::ADDED)
{
if (const smtk::attribute::Resource* attributeResource =
dynamic_cast<const smtk::attribute::Resource*>(&resource))
{
const_cast<smtk::attribute::Resource*>(attributeResource)
->customItemDefinitionFactory()
.registerTypes<CustomDefinitionTypes>();
}
}
};
if (auto manager = m_manager.lock())
{
manager->observers()
.insert(registerCustomTypes, "Register custom attribute types.")
.release();
return true;
}
return false;
}
private:
std::weak_ptr<smtk::resource::Manager> m_manager;
};
}
}
......
//=========================================================================
// 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/ItemDefinitionManager.h"
namespace smtk
{
namespace attribute
{
ItemDefinitionManager::ItemDefinitionManager(const smtk::resource::ManagerPtr& manager)
: m_manager(manager)
{
}
ItemDefinitionManager::~ItemDefinitionManager() = default;
}
}
//=========================================================================
// 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_ItemDefinitionManager_h
#define __smtk_attribute_ItemDefinitionManager_h
#include "smtk/CoreExports.h"
#include "smtk/PublicPointerDefs.h"
#include "smtk/attribute/Item.h"
#include "smtk/attribute/ItemDefinition.h"
#include "smtk/attribute/Resource.h"
#include <smtk/common/TypeName.h>
#include "smtk/resource/Manager.h"
#include "smtk/resource/Observer.h"
#include <string>
namespace smtk
{
namespace attribute
{
/// A manager for custom (i.e. user-defined) item definitions.
///
/// ItemDefinitionManager is an interface for registering user-defined item
/// definitions. SMTK Plugins can interact with the ItemDefinitionManager by
/// adding methods similar to the following to their Registrar:
///
/// registerTo(const smtk::attribute::ItemDefinitionManager::Ptr& manager)
/// {
/// manager->registerDefinition<MyCustomItemDefinition>();
/// }
///
/// unregisterFrom(const smtk::attribute::ItemDefinitionManager::Ptr& manager)
/// {
/// manager->unregisterDefinition<MyCustomItemDefinition>();
/// }
///
/// Additionally, the `smtk_add_plugin()` call for the plugin should be extended
/// to include `smtk::attribute::ItemDefinitionManager` in its list of managers.
/// Upon registration, attribute resources associated with the same resource
/// manager as the ItemDefinitionManager will be able to read, write and create
/// attributes that contain the newly registered custom items.
class SMTKCORE_EXPORT ItemDefinitionManager : std::enable_shared_from_this<ItemDefinitionManager>
{
public:
smtkTypedefs(smtk::attribute::ItemDefinitionManager);
static std::shared_ptr<ItemDefinitionManager> create(
const smtk::resource::ManagerPtr& resourceManager)
{
return smtk::shared_ptr<ItemDefinitionManager>(new ItemDefinitionManager(resourceManager));
}
virtual ~ItemDefinitionManager();
/// Register <CustomItemDefinitionType> to all attribute resources.
template <typename CustomDefinitionType>
bool registerDefinition()
{
auto registerCustomType = [](
const smtk::resource::Resource& resource, smtk::resource::EventType eventType) -> void {
if (eventType == smtk::resource::EventType::ADDED)
{
if (const smtk::attribute::Resource* attributeResource =
dynamic_cast<const smtk::attribute::Resource*>(&resource))
{
const_cast<smtk::attribute::Resource*>(attributeResource)
->customItemDefinitionFactory()
.registerType<CustomDefinitionType>();
}
}
};
if (auto manager = m_manager.lock())
{
m_observers.insert(std::make_pair(typeid(CustomDefinitionType).hash_code(),
manager->observers().insert(registerCustomType, "Register custom attribute type <" +
smtk::common::typeName<CustomDefinitionType>() + ">.")));
return true;
}
return false;
}
/// Unregister <CustomItemDefinitionType> from all attribute resources.
template <typename CustomDefinitionType>
bool unregisterDefinition()
{
if (auto manager = m_manager.lock())
{
for (auto resource : manager->find<smtk::attribute::Resource>())
{
resource->customItemDefinitionFactory().unregisterType<CustomDefinitionType>();
}
m_observers.erase(typeid(CustomDefinitionType).hash_code());
return true;
}
return false;
}
/// Register multiple definitions to all attribute resources.
template <typename Tuple>
bool registerDefinitions()
{
return ItemDefinitionManager::registerDefinitions<0, Tuple>();
}
/// Unregister multiple definitions from all attribute resources.
template <typename Tuple>
bool unregisterDefinitions()
{
return ItemDefinitionManager::unregisterDefinitions<0, Tuple>();
}
protected:
ItemDefinitionManager(const std::shared_ptr<smtk::resource::Manager>&);
template <std::size_t I, typename Tuple>
inline typename std::enable_if<I != std::tuple_size<Tuple>::value, bool>::type
registerDefinitions()
{
bool registered = this->registerDefinition<typename std::tuple_element<I, Tuple>::type>();
return registered && ItemDefinitionManager::registerDefinitions<I + 1, Tuple>();
}
template <std::size_t I, typename Tuple>
inline typename std::enable_if<I == std::tuple_size<Tuple>::value, bool>::type
registerDefinitions()
{
return true;
}
template <std::size_t I, typename Tuple>
inline typename std::enable_if<I != std::tuple_size<Tuple>::value, bool>::type
unregisterDefinitions()
{
bool unregistered = this->unregisterDefinition<typename std::tuple_element<I, Tuple>::type>();
return unregistered && ItemDefinitionManager::unregisterDefinitions<I + 1, Tuple>();
}
template <std::size_t I, typename Tuple>
inline typename std::enable_if<I == std::tuple_size<Tuple>::value, bool>::type
unregisterDefinitions()
{
return true;
}
std::weak_ptr<smtk::resource::Manager> m_manager;
std::unordered_map<std::size_t, smtk::resource::Observers::Key> m_observers;
};
}
}
#endif
......@@ -11,6 +11,7 @@
//=============================================================================
#include "smtk/attribute/Registrar.h"
#include "smtk/attribute/ItemDefinitionManager.h"
#include "smtk/attribute/Resource.h"
#include "smtk/attribute/operators/Associate.h"
......@@ -27,6 +28,8 @@
#include "smtk/operation/groups/ReaderGroup.h"
#include "smtk/operation/groups/WriterGroup.h"
#include "smtk/plugin/Manager.h"
namespace smtk
{
namespace attribute
......@@ -36,6 +39,23 @@ namespace
typedef std::tuple<Associate, Dissociate, Export, Import, Read, Signal, Write> OperationList;
}
void Registrar::registerTo(const smtk::common::Managers::Ptr& managers)
{
if (managers->contains<smtk::resource::Manager::Ptr>())
{
managers->insert(smtk::attribute::ItemDefinitionManager::create(
managers->get<smtk::resource::Manager::Ptr>()));
smtk::plugin::Manager::instance()->registerPluginsTo(
managers->get<smtk::attribute::ItemDefinitionManager::Ptr>());
}
}
void Registrar::unregisterFrom(const smtk::common::Managers::Ptr& managers)
{
managers->erase<smtk::attribute::ItemDefinitionManager::Ptr>();
}
void Registrar::registerTo(const smtk::operation::Manager::Ptr& operationManager)
{
operationManager->registerOperations<OperationList>();
......
......@@ -12,6 +12,7 @@
#include "smtk/CoreExports.h"
#include "smtk/common/Managers.h"
#include "smtk/operation/Manager.h"
#include "smtk/resource/Manager.h"
......@@ -22,6 +23,9 @@ namespace attribute
class SMTKCORE_EXPORT Registrar
{
public:
static void registerTo(const smtk::common::Managers::Ptr&);
static void unregisterFrom(const smtk::common::Managers::Ptr&);
static void registerTo(const smtk::operation::Manager::Ptr&);
static void unregisterFrom(const smtk::operation::Manager::Ptr&);
......
smtk_add_plugin(smtkAttributePlugin
REGISTRAR smtk::attribute::Registrar
MANAGERS smtk::operation::Manager
MANAGERS smtk::common::Managers
smtk::operation::Manager
smtk::resource::Manager
PARAVIEW_PLUGIN_ARGS
VERSION 1.0)
......@@ -24,6 +24,7 @@
#include "smtk/attribute/json/jsonItem.h"
#include "smtk/attribute/json/jsonItemDefinition.h"
#include "smtk/attribute/ItemDefinitionManager.h"
#include "smtk/attribute/Registrar.h"
#include "smtk/attribute/operators/Export.h"
#include "smtk/attribute/operators/Import.h"
......@@ -239,6 +240,7 @@ int unitCustomItem(int /*unused*/, char* /*unused*/ [])
{
auto resourceManager = smtk::resource::Manager::create();
auto operationManager = smtk::operation::Manager::create();
auto itemDefinitionManager = smtk::attribute::ItemDefinitionManager::create(resourceManager);
{
// Initialize smtk managers
smtk::attribute::Registrar::registerTo(resourceManager);
......@@ -247,8 +249,7 @@ int unitCustomItem(int /*unused*/, char* /*unused*/ [])
operationManager->registerResourceManager(resourceManager);
}
smtk::attribute::CustomItemDefinitions(resourceManager)
.registerDefinitions<CustomItemDefinitionsList>();
itemDefinitionManager->registerDefinitions<CustomItemDefinitionsList>();
// 1. Construct an attribute with a custom item
......@@ -439,5 +440,7 @@ int unitCustomItem(int /*unused*/, char* /*unused*/ [])
return status;
}
itemDefinitionManager->unregisterDefinitions<CustomItemDefinitionsList>();
return 0;
}
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