[Smtk-developers] Follow-up on resource metadata
David Thompson
david.thompson at kitware.com
Mon Nov 13 13:20:58 EST 2017
Hi TJ et al.,
I wanted to follow up a little on the discussion we had last week about resources. As I understand it, we are now talking about having the model manager (renamed to Resource?) and each subclass (call them smtk::bridge::xxx::Resource) register themselves like so:
smtk::resource::Manager::registerResource(
new smtk::resource::Metadata("xxx", type_id(smtk::bridge::xxx::Resource));
somewhere in their static initializer.
If so, it seems to make sense to do some combination of
1. Subclass metadata for smtk::model as shown below so that the inherited setup() method can fill out the create/read/write members; and/or
2. Change the create/read/write methods in the metadata to point to operators (but which ones?).
The subclass below shows some of the questions that pop up. Note in particular that as we change the model manager into a resource, it goes from being a single instance with potentially multiple sessions to multiple instances, each with a single session.
That seems to indicate that the smtk;:model::Session and SessionRegistrar classes should change a little. A session should not ask for its (sole) model manager, but rather a model resource should ask for its sole session. It would be easy for the SessionRegistrar to find an existing session or create one as required.
Is this what you had in mind? One variation of the below would be to make subclasses of Metadata templated on their resource type... then at least the create() member of Metadata could be implemented as "return T::create()->setId(uid);". If we add methods to Resource to return read/write (/import/export?) methods, then Metadata could be entirely templated.
David
#ifndef smtk_model_Metadata_h
#define smtk_model_Metadata_h
#include "smtk/model/Manaager.h"
#include "smtk/resource/Metadata.h"
namespace smtk
{
namespace model
{
class Metadata : public smtk::resource::Metadata
{
typedef smtk::resource::Metadata Superclass;
public:
Metadata()
: Superclass("model", typeid(smtk::model::Manager))
{
this->setup();
}
void setup()
{
this->create = [](const smtk::common::UUID& uid)
{
auto rsrc = smtk::model::Manager::create();
rsrc->setId(uid);
return rsrc;
};
this->read = [](const std::string& url)
{
// Find a session of the proper type
auto sess = smtk::model::SessionRegistrar::createSession(m_uniqueName);
if (sess)
{
// Order is important here: the session should be registered to the
// model resource before running operations. However, note that this
// causes a chicken and egg problem because the reader should obtain
// a UUID for the model resource. Assume the reader will modify its
// resource's UUID? Only on load and not import?
auto rsrc = smtk::model::Manager::create();
rsrc->registerSession(sess);
auto rdr = sess->op("load smtk model");
if (rdr)
{
rdr->findFile("filename")->setValue(0, url);
auto res = rdr->operate();
// Success returns the shared pointer, keeping the model resource alive.
// Failure discards the model resource.
if (res->findInteger("outcome")->value() == smtk::operation::OPERATION_SUCCEEDED)
{
return rsrc;
}
}
}
return nullptr;
};
this->write = [](const ResourcePtr& rawRsrc)
{
auto rsrc = dynamic_pointer_cast<smtk::model::Resource>(rawRsrc);
if (!rsrc)
{
return false;
}
auto wri = rsrc->session()->op("save smtk model");
if (wri)
{
// This will require changes to the "save smtk model" operator.
// Should we associate all the models in the resource?
// Should we have an attribute::ResourceItem just like we have
// attribute::ComponentItem so that an entire resource can be
// associated to an attribute? We could also abuse ComponentItem
// a little bit... if we have a way to create a Component with a
// null UUID but a valid parent resource, it could be interpreted
// as "the component that is the set of all components in the
// resource," making it a stand-in for the entire resource.
wri->associatedComponents()->setValue(0, xxx); // Associate all models in rsrc?
wri->findFile("filename")->setValue(0, rsrc->location());
auto res = wri->operate();
return res->findInteger("outcome")->value() == smtk::operation::OPERATION_SUCCEEDED;
}
return false;
}
}
};
}
}
More information about the Smtk-developers
mailing list