Program Listing for File socket.cc#

↰ Return to documentation for file (src/socket.cc)

#include "nodes-graph/socket.h"


namespace ng {

Socket::Socket(
    const std::string& name,
    const socket_id_t& id,
    socket_t type,
    bool active,
    const std::set<qualifier_t>& on_added_link_callbacks,
    const std::set<qualifier_t>& on_broken_link_callbacks
): name_(name),
   id_(id),
   type_(type),
   active_(active),
   on_added_link_callbacks_(on_added_link_callbacks),
   on_broken_link_callbacks_(on_broken_link_callbacks)
{}


// ---


InputSocket::InputSocket(
    const std::string& name,
    const socket_id_t& id,
    socket_t type,
    bool active,
    const std::string& value,
    bool linkable,
    const std::set<std::string>& allowed_values,
    const std::set<qualifier_t>& on_added_link_callbacks,
    const std::set<qualifier_t>& on_broken_link_callbacks,
    const std::set<qualifier_t>& on_value_changed_callbacks
): Socket(name, id, type, active, on_added_link_callbacks, on_broken_link_callbacks),
   value_(value),
   allowed_values_(allowed_values),
   linkable_(linkable),
   on_value_changed_callbacks_(on_value_changed_callbacks)
{}


bool InputSocket::is_allowed_value(const std::string& value) const {
    return allowed_values_.empty() || allowed_values_.count(value) > 0;
}


bool InputSocket::set_value(const std::string& value) {
    if (!is_allowed_value(value)) { return false; }
    value_ = value;
    return true;
}


bool InputSocket::check_validity(const std::string& value) const {
    const ValidatorsRegistry& registry = ValidatorsRegistry::instance();
    bool found_validator = false;

    for (std::size_t i = 0 ; i < sizeof(socket_t) * 8 ; ++i) {
        socket_t type_flag = socket_t{1} << i;
        if (!(type_ & type_flag)) { continue; }
        validator_t validator = registry.get_safe(type_flag, nullptr);
        if (!validator) { continue; }
        if (validator(value)) { return true; }
        found_validator = true;
    }
    return !found_validator;
}


void InputSocket::trigger_on_value_changed_callbacks(Graph& graph, Node& node, const std::string& old_value) {
    const ValueChangedCallbacksRegistry& registry = ValueChangedCallbacksRegistry::instance();
    for (const qualifier_t& cb : on_value_changed_callbacks_) {
        value_changed_callback_t cb_function = registry.get_safe(cb, nullptr);
        if (cb_function) { cb_function(graph, node, *this, old_value); }
    }
}


void InputSocket::trigger_on_added_link_callbacks(Graph& graph, Node& node_from, OutputSocket& from, Node& node_to) {
    const LinkAddedCallbacksRegistry& registry = LinkAddedCallbacksRegistry::instance();
    for (const qualifier_t& cb : on_added_link_callbacks_) {
        link_added_callback_t cb_function = registry.get_safe(cb, nullptr);
        if (cb_function) { cb_function(graph, node_from, from, node_to, *this); }
    }
}


void InputSocket::trigger_on_broken_link_callbacks(Graph& graph, Node& node_from, OutputSocket& from, Node& node_to, LinkBreakReason reason) {
    const LinkBrokenCallbacksRegistry& registry = LinkBrokenCallbacksRegistry::instance();
    for (const qualifier_t& cb : on_broken_link_callbacks_) {
        link_broken_callback_t cb_function = registry.get_safe(cb, nullptr);
        if (cb_function) { cb_function(graph, node_from, from, node_to, *this, reason); }
    }
}


// ---


OutputSocket::OutputSocket(
    const std::string& name,
    const socket_id_t& id,
    socket_t type,
    bool active,
    const std::set<qualifier_t>& on_added_link_callbacks,
    const std::set<qualifier_t>& on_broken_link_callbacks
): Socket(name, id, type, active, on_added_link_callbacks, on_broken_link_callbacks) {}


void OutputSocket::trigger_on_added_link_callbacks(Graph& graph, Node& node_from, Node& node_to, InputSocket& to) {
    const LinkAddedCallbacksRegistry& registry = LinkAddedCallbacksRegistry::instance();
    for (const qualifier_t& cb : on_added_link_callbacks_) {
        link_added_callback_t cb_function = registry.get_safe(cb, nullptr);
        if (cb_function) { cb_function(graph, node_from, *this, node_to, to); }
    }
}


void OutputSocket::trigger_on_broken_link_callbacks(Graph& graph, Node& node_from, Node& node_to, InputSocket& to, LinkBreakReason reason) {
    const LinkBrokenCallbacksRegistry& registry = LinkBrokenCallbacksRegistry::instance();
    for (const qualifier_t& cb : on_broken_link_callbacks_) {
        link_broken_callback_t cb_function = registry.get_safe(cb, nullptr);
        if (cb_function) { cb_function(graph, node_from, *this, node_to, to, reason); }
    }
}

} // namespace ng