smgl 0.11.0
Structured Metadata Engine and Graph Objects Library
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
smgl::Node Class Reference

Generic Node class. More...

#include <smgl/Node.hpp>

Inheritance diagram for smgl::Node:
[legend]
Collaboration diagram for smgl::Node:
[legend]

Classes

struct  Info
 Port registration information. More...
 

Public Types

enum class  State {
  Idle , Waiting , Ready , Updating ,
  Error
}
 
using Pointer = std::shared_ptr< Node >
 

Public Member Functions

void update ()
 Update the Node.
 
auto serialize (bool useCache, const filesystem::path &cacheRoot) -> Metadata
 Serialize the Node to Metadata, optionally caching to disk.
 
void deserialize (const Metadata &meta, const filesystem::path &cacheRoot)
 Deserialize the Node to Metadata.
 
auto getInputPortsInfo () const -> std::vector< Info >
 Get registered InputPort info.
 
auto getOutputPortsInfo () const -> std::vector< Info >
 Get registered OutputPort info.
 
auto getInputPort (const Uuid &uuid) -> Input &
 Get a registered InputPort by Uuid.
 
auto getInputPort (const std::string &name) -> Input &
 Get a registered InputPort by registered name.
 
auto getOutputPort (const Uuid &uuid) -> Output &
 Get a registered OutputPort by Uuid.
 
auto getOutputPort (const std::string &name) -> Output &
 Get a registered OutputPort by registered name.
 
auto getInputConnections () const -> std::vector< Connection >
 Get a list of active input connections.
 
auto getNumberOfInputConnections () const -> size_t
 Get the number of active input connections.
 
auto getOutputConnections () const -> std::vector< Connection >
 Get a list of active output connections.
 
auto getNumberOfOutputConnections () const -> size_t
 Get the number of active output connections.
 
auto state () -> State
 Get the current update state.
 
- Public Member Functions inherited from smgl::UniquelyIdentifiable
auto uuid () const -> Uuid
 
void setUuid (const Uuid &uuid)
 

Protected Member Functions

 Node ()
 
 Node (bool usesCacheDir)
 
virtual ~Node ()=default
 
template<typename T >
void registerInputPort (const std::string &name, InputPort< T > &port)
 Register an InputPort instance with this class.
 
template<typename T >
void registerPort (const std::string &name, InputPort< T > &port)
 Register an InputPort instance with this class.
 
template<typename T , typename... Args>
void registerOutputPort (const std::string &name, OutputPort< T, Args... > &port)
 Register an OutputPort instance with this class.
 
template<typename T , typename... Args>
void registerPort (const std::string &name, OutputPort< T, Args... > &port)
 Register an OutputPort instance with this class.
 
- Protected Member Functions inherited from smgl::UniquelyIdentifiable
 UniquelyIdentifiable ()=default
 

Protected Attributes

std::function< void()> compute
 Function executed when Node's InputPorts have queued updates and update() is called.
 
std::function< bool()> usesCacheDir
 
- Protected Attributes inherited from smgl::UniquelyIdentifiable
Uuid uuid_ {Uuid::Uuid4()}
 

Private Member Functions

virtual auto serialize_ (bool useCache, const filesystem::path &cacheDir) -> Metadata
 Serialize the Node's state to Metadata.
 
virtual void deserialize_ (const Metadata &data, const filesystem::path &cacheDir)
 Deserialize the Node's state from Metadata.
 
auto update_input_ports_ () -> bool
 
void notify_output_ports_ (Port::State s)
 
auto update_output_ports_ () -> bool
 

Static Private Member Functions

template<class PortType >
static void LoadAndRegisterPort (const std::string &name, const Metadata &data, std::unordered_map< Uuid, PortType * > &byUuid, std::map< std::string, PortType * > &byName)
 

Private Attributes

std::unordered_map< Uuid, Input * > inputs_by_uuid_
 
std::map< std::string, Input * > inputs_by_name_
 
std::unordered_map< Uuid, Output * > outputs_by_uuid_
 
std::map< std::string, Output * > outputs_by_name_
 
State state_ {State::Idle}
 

Detailed Description

Generic Node class.

Provides a base class for custom computation nodes. Typically, inputs and outputs are defined by adding public InputPort and OutputPort members. To customize Node behavior, assign or override the members Node::compute, Node::serialize_, and Node::deserialize_.

using namespace smgl;
class SumNode : public Node {
private:
// Custom internal state
int a_{0};
int b_{0};
int c_{a_ + b_};
public:
// Define ports
SumNode() : Node() {
// Must register ports
registerInputPort("a", a);
registerInputPort("b", b);
registerOutputPort("c", c);
// Define compute behavior
compute = [=]() { c_ = a_ + b_; };
}
// Serialize state to Metadata
Metadata serialize_(bool, const filesystem::path&) override {
return {{"a", a_}, {"b", b_}, {"c", c_}};
}
// Deserialize state from Metadata
void deserialize_(const Metadata& m, const filesystem::path&) override {
a_ = m["a"].get<int>();
b_ = m["b"].get<int>();
c_ = m["c"].get<int>();
}
}
Typed InputPort class.
Definition Ports.hpp:213
Generic Node class.
Definition Node.hpp:70
Typed OutputPort class.
Definition Ports.hpp:295
Project top-level namespace.
nlohmann::ordered_json Metadata
Metadata storage class.
Definition Metadata.hpp:12

Definition at line 69 of file Node.hpp.

Member Typedef Documentation

◆ Pointer

Pointer type

Definition at line 87 of file Node.hpp.

Member Enumeration Documentation

◆ State

enum class smgl::Node::State
strong

Node update state

Enumerator
Idle 

Does not need to be updated

Waiting 

Waiting on an upstream dependency to update

Ready 

Ready to be updated

Updating 

Updating

Error 

Error updating

Definition at line 73 of file Node.hpp.

Constructor & Destructor Documentation

◆ Node() [1/2]

smgl::Node::Node ( )
protected

Protected constructor can only be called by child class

◆ Node() [2/2]

smgl::Node::Node ( bool  usesCacheDir)
explicitprotected

Protected constructor to set usesCacheDir value

◆ ~Node()

virtual smgl::Node::~Node ( )
protectedvirtualdefault

Protected virtual destructor should override by child class

Member Function Documentation

◆ deserialize()

void smgl::Node::deserialize ( const Metadata meta,
const filesystem::path cacheRoot 
)

Deserialize the Node to Metadata.

Accepts a Metadata structure generated by serialize(). If that method was called with useCache == true, then cacheRoot should point to the same cache root directory.

Typically, users do not need to call this function directly and should instead use Graph::Load

◆ deserialize_()

virtual void smgl::Node::deserialize_ ( const Metadata data,
const filesystem::path cacheDir 
)
privatevirtual

Deserialize the Node's state from Metadata.

This method is called by deserialize() and is expected to load any custom state information needed to faithfully clone a previous Node instance. The Metadata argument data is one produced by the serialize_(). If that method was called with useCache == true, then cacheDir should point to the same node cache directory.

By default, this method does nothing. Child classes of Node wishing to make use of the smgl serialization behavior should override both serialize_() and deserialize_(). If the child implementation needs to use the cache directory, it should either call the Node(bool) constructor or redefine Node::usesCacheDir.

Metadata supports direct deserialization of many internal types and STL containers using the get template method. For data types which are not supported, data may be loaded from disk instead. It is good practice to serialize the name of any files that need to be loaded during deserialization when overriding serialize_().

class MyNode : public Node {
private:
void deserialize_(const Metadata& data, const path& cacheDir) override;
}
void MyNode::deserialize_(const Metadata& data, const path& cacheDir) {
if(data.contains("cacheFile") {
auto file = data["cacheFile"].get<std::string>();
std::ifstream fs(cacheDir / file);
std::getline(fs, value_);
fs.close();
}
}

◆ getInputPort() [1/2]

auto smgl::Node::getInputPort ( const std::string name) -> Input &

Get a registered InputPort by registered name.

Exceptions
std::out_of_rangeif name not registered with Node

◆ getInputPort() [2/2]

auto smgl::Node::getInputPort ( const Uuid uuid) -> Input &

Get a registered InputPort by Uuid.

Exceptions
std::out_of_rangeif Uuid not registered with Node

◆ getOutputPort() [1/2]

auto smgl::Node::getOutputPort ( const std::string name) -> Output &

Get a registered OutputPort by registered name.

Exceptions
std::out_of_rangeif name not registered with Node

◆ getOutputPort() [2/2]

auto smgl::Node::getOutputPort ( const Uuid uuid) -> Output &

Get a registered OutputPort by Uuid.

Exceptions
std::out_of_rangeif Uuid not registered with Node

◆ LoadAndRegisterPort()

template<class PortType >
void smgl::Node::LoadAndRegisterPort ( const std::string name,
const Metadata data,
std::unordered_map< Uuid, PortType * > &  byUuid,
std::map< std::string, PortType * > &  byName 
)
staticprivate

Convenience method for loading existing port information and updating port registrations

Definition at line 7 of file NodeImpl.hpp.

◆ notify_output_ports_()

void smgl::Node::notify_output_ports_ ( Port::State  s)
private

Notify output ports of this Node's update state

◆ registerInputPort()

template<typename T >
void smgl::Node::registerInputPort ( const std::string name,
InputPort< T > &  port 
)
protected

Register an InputPort instance with this class.

Note
Failing to register ports will cause errors in scheduling and computation which are not always easy to identify.

Definition at line 35 of file NodeImpl.hpp.

◆ registerOutputPort()

template<typename T , typename... Args>
void smgl::Node::registerOutputPort ( const std::string name,
OutputPort< T, Args... > &  port 
)
protected

Register an OutputPort instance with this class.

Note
Failing to register ports will cause errors in scheduling and computation which are not always easy to identify.

Definition at line 50 of file NodeImpl.hpp.

◆ registerPort() [1/2]

template<typename T >
void smgl::Node::registerPort ( const std::string name,
InputPort< T > &  port 
)
protected

Register an InputPort instance with this class.

Note
Failing to register ports will cause errors in scheduling and computation which are not always easy to identify.

Definition at line 44 of file NodeImpl.hpp.

◆ registerPort() [2/2]

template<typename T , typename... Args>
void smgl::Node::registerPort ( const std::string name,
OutputPort< T, Args... > &  port 
)
protected

Register an OutputPort instance with this class.

Note
Failing to register ports will cause errors in scheduling and computation which are not always easy to identify.

Definition at line 60 of file NodeImpl.hpp.

◆ serialize()

auto smgl::Node::serialize ( bool  useCache,
const filesystem::path cacheRoot 
) -> Metadata

Serialize the Node to Metadata, optionally caching to disk.

If useCache is true, this Node is allowed to create a subdirectory in cacheRoot where it can write intermediate results. If cacheRoot is empty, the current working directory will be used.

Typically, users do not need to call this function directly and should instead use Graph::Save.

◆ serialize_()

virtual auto smgl::Node::serialize_ ( bool  useCache,
const filesystem::path cacheDir 
) -> Metadata
privatevirtual

Serialize the Node's state to Metadata.

The public member function serialize() produces a Metadata object containing all Node state information including Uuid, registered ports, and custom state values. This method is called by serialize() and is expected to provide any custom state information needed to faithfully clone this Node instance.

By default, this method produces an empty Metadata object. Child classes of Node wishing to make use of the smgl serialization behavior should override both serialize_() and deserialize_(). If the child implementation needs to use the cache directory, it should either call the Node(bool) constructor or redefine Node::usesCacheDir.

Metadata supports direct serialization of many internal types and STL and containers. For data types which are not supported, data may be serialized directly to disk instead. If useCache is true, Node implementations may write data to the directory passed by cacheDir. It is good practice to serialize the name of any files written so that they can later be easily identified by the deserialize_() process:

class MyNode : public Node {
private:
Metadata serialize_(bool useCache, const path& cacheDir) override;
}
Metadata MyNode::serialize_(bool useCache, const path& cacheDir) {
if (useCache) {
std::ofstream fs(cacheDir / "value.txt");
fs << value_;
fs.close();
m["cacheFile"] = "value.txt";
}
return m;
}

◆ update()

void smgl::Node::update ( )

Update the Node.

Accepts any queued updates from registered InputPorts, computes a new result as needed, and signals OutputPort connections with updated results.

◆ update_input_ports_()

auto smgl::Node::update_input_ports_ ( ) -> bool
private

Receive all queued updates on registered InputPorts. Returns true if any port successfully updates.

◆ update_output_ports_()

auto smgl::Node::update_output_ports_ ( ) -> bool
private

Send queued update on all output ports

Member Data Documentation

◆ compute

std::function<void()> smgl::Node::compute
protected

Function executed when Node's InputPorts have queued updates and update() is called.

compute is of type std::function<void()> and can be assigned any function which meets this signature. This includes function references and lambda functions. By default, it is unassigned effectively a no-op. It is generally preferable to assign this function in the child Node's constructor.

// Free function
compute = &foo;
// Member function (using smgl::WrapFunc for convenience)
...
compute = smgl::WrapFunc(&bar, &Bar::doWork);
// Lambda function capturing local context
compute = [=]() { privateInt += 1; };
std::function< void()> compute
Function executed when Node's InputPorts have queued updates and update() is called.
Definition Node.hpp:234
auto WrapFunc(Obj *obj, ObjMemberFn &&fn, Args &&... args)
Wrap a member function w/ arguments into a lambda function.

Definition at line 234 of file Node.hpp.

◆ inputs_by_name_

std::map<std::string, Input*> smgl::Node::inputs_by_name_
private

Stores registered inputs by registered name

Definition at line 365 of file Node.hpp.

◆ inputs_by_uuid_

std::unordered_map<Uuid, Input*> smgl::Node::inputs_by_uuid_
private

Stores registered inputs by Uuid

Definition at line 363 of file Node.hpp.

◆ outputs_by_name_

std::map<std::string, Output*> smgl::Node::outputs_by_name_
private

Stores registered outputs by registered name

Definition at line 369 of file Node.hpp.

◆ outputs_by_uuid_

std::unordered_map<Uuid, Output*> smgl::Node::outputs_by_uuid_
private

Stores registered outputs by Uuid

Definition at line 367 of file Node.hpp.

◆ state_

State smgl::Node::state_ {State::Idle}
private

Current Node state

Definition at line 371 of file Node.hpp.

◆ usesCacheDir

std::function<bool()> smgl::Node::usesCacheDir
protected

Function flag for whether this Node uses the cacheDir when serializing. Replacing this function allows a child class to define whether or not a cache directory is needed at runtime. The default implementation returns false or the value passed to Node(bool).

struct Foo {
Foo() {
usesCacheDir = [&bar = bar](){ return bar != nullptr;};
}
}

Definition at line 251 of file Node.hpp.


The documentation for this class was generated from the following files: