2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2021-08-20 13:14:39 +02:00
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "FN_multi_function.hh"
|
|
|
|
|
|
|
|
|
|
#include "DNA_node_types.h"
|
|
|
|
|
|
|
|
|
|
namespace blender::nodes {
|
|
|
|
|
|
|
|
|
|
class NodeMultiFunctions;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Utility class to help nodes build a multi-function for themselves.
|
|
|
|
|
*/
|
|
|
|
|
class NodeMultiFunctionBuilder : NonCopyable, NonMovable {
|
|
|
|
|
private:
|
2022-08-31 12:15:57 +02:00
|
|
|
const bNode &node_;
|
|
|
|
|
const bNodeTree &tree_;
|
2023-01-07 17:32:28 +01:00
|
|
|
std::shared_ptr<mf::MultiFunction> owned_built_fn_;
|
|
|
|
|
const mf::MultiFunction *built_fn_ = nullptr;
|
2021-08-20 13:14:39 +02:00
|
|
|
|
|
|
|
|
friend NodeMultiFunctions;
|
|
|
|
|
|
|
|
|
|
public:
|
2022-08-31 12:15:57 +02:00
|
|
|
NodeMultiFunctionBuilder(const bNode &node, const bNodeTree &tree);
|
2021-08-20 13:14:39 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Assign a multi-function for the current node. The input and output parameters of the function
|
|
|
|
|
* have to match the available sockets in the node.
|
|
|
|
|
*/
|
2023-01-07 17:32:28 +01:00
|
|
|
void set_matching_fn(const mf::MultiFunction *fn);
|
|
|
|
|
void set_matching_fn(const mf::MultiFunction &fn);
|
2021-08-20 13:14:39 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Utility method for creating and assigning a multi-function when it can't have a static
|
|
|
|
|
* lifetime.
|
|
|
|
|
*/
|
|
|
|
|
template<typename T, typename... Args> void construct_and_set_matching_fn(Args &&...args);
|
|
|
|
|
|
2024-10-15 06:51:42 +02:00
|
|
|
/**
|
|
|
|
|
* Similar to #construct_and_set_matching_fn, but can be used when the type name of the
|
|
|
|
|
* multi-function is not known (e.g. when using `mf::build::SI1_SO`).
|
|
|
|
|
*
|
|
|
|
|
* \param create_multi_function: A function that returns the multi-function by value.
|
|
|
|
|
*/
|
|
|
|
|
template<typename Fn> void construct_and_set_matching_fn_cb(Fn &&create_multi_function);
|
|
|
|
|
|
2022-08-31 12:15:57 +02:00
|
|
|
const bNode &node();
|
|
|
|
|
const bNodeTree &tree();
|
2024-10-15 06:51:42 +02:00
|
|
|
const mf::MultiFunction &function();
|
2021-08-20 13:14:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Gives access to multi-functions for all nodes in a node tree that support them.
|
|
|
|
|
*/
|
|
|
|
|
class NodeMultiFunctions {
|
2021-10-18 11:40:00 +02:00
|
|
|
public:
|
|
|
|
|
struct Item {
|
2023-01-07 17:32:28 +01:00
|
|
|
const mf::MultiFunction *fn = nullptr;
|
|
|
|
|
std::shared_ptr<mf::MultiFunction> owned_fn;
|
2021-10-18 11:40:00 +02:00
|
|
|
};
|
|
|
|
|
|
2021-08-20 13:14:39 +02:00
|
|
|
private:
|
2021-10-18 11:40:00 +02:00
|
|
|
Map<const bNode *, Item> map_;
|
2021-08-20 13:14:39 +02:00
|
|
|
|
|
|
|
|
public:
|
2022-09-13 08:44:26 +02:00
|
|
|
NodeMultiFunctions(const bNodeTree &tree);
|
2021-08-20 13:14:39 +02:00
|
|
|
|
2022-09-13 08:44:26 +02:00
|
|
|
const Item &try_get(const bNode &node) const;
|
2021-08-20 13:14:39 +02:00
|
|
|
};
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name #NodeMultiFunctionBuilder Inline Methods
|
|
|
|
|
* \{ */
|
2021-08-20 13:14:39 +02:00
|
|
|
|
2022-08-31 12:15:57 +02:00
|
|
|
inline NodeMultiFunctionBuilder::NodeMultiFunctionBuilder(const bNode &node, const bNodeTree &tree)
|
2021-10-18 11:40:00 +02:00
|
|
|
: node_(node), tree_(tree)
|
2021-08-20 13:14:39 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-31 12:15:57 +02:00
|
|
|
inline const bNode &NodeMultiFunctionBuilder::node()
|
2021-08-20 13:14:39 +02:00
|
|
|
{
|
|
|
|
|
return node_;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-31 12:15:57 +02:00
|
|
|
inline const bNodeTree &NodeMultiFunctionBuilder::tree()
|
2021-08-20 13:14:39 +02:00
|
|
|
{
|
|
|
|
|
return tree_;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-15 06:51:42 +02:00
|
|
|
inline const mf::MultiFunction &NodeMultiFunctionBuilder::function()
|
|
|
|
|
{
|
|
|
|
|
return *built_fn_;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-07 17:32:28 +01:00
|
|
|
inline void NodeMultiFunctionBuilder::set_matching_fn(const mf::MultiFunction *fn)
|
2021-08-20 13:14:39 +02:00
|
|
|
{
|
|
|
|
|
built_fn_ = fn;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-07 17:32:28 +01:00
|
|
|
inline void NodeMultiFunctionBuilder::set_matching_fn(const mf::MultiFunction &fn)
|
2021-08-20 13:14:39 +02:00
|
|
|
{
|
2021-10-18 11:40:00 +02:00
|
|
|
built_fn_ = &fn;
|
2021-08-20 13:14:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T, typename... Args>
|
|
|
|
|
inline void NodeMultiFunctionBuilder::construct_and_set_matching_fn(Args &&...args)
|
|
|
|
|
{
|
2021-10-18 11:40:00 +02:00
|
|
|
owned_built_fn_ = std::make_shared<T>(std::forward<Args>(args)...);
|
|
|
|
|
built_fn_ = &*owned_built_fn_;
|
2021-08-20 13:14:39 +02:00
|
|
|
}
|
|
|
|
|
|
2024-10-15 06:51:42 +02:00
|
|
|
template<typename Fn>
|
|
|
|
|
inline void NodeMultiFunctionBuilder::construct_and_set_matching_fn_cb(Fn &&create_multi_function)
|
|
|
|
|
{
|
|
|
|
|
using T = decltype(create_multi_function());
|
|
|
|
|
T *allocated_function = new T(create_multi_function());
|
|
|
|
|
owned_built_fn_ = std::shared_ptr<T>(allocated_function);
|
|
|
|
|
built_fn_ = &*owned_built_fn_;
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name #NodeMultiFunctions Inline Methods
|
|
|
|
|
* \{ */
|
2021-08-20 13:14:39 +02:00
|
|
|
|
2022-09-13 08:44:26 +02:00
|
|
|
inline const NodeMultiFunctions::Item &NodeMultiFunctions::try_get(const bNode &node) const
|
2021-08-20 13:14:39 +02:00
|
|
|
{
|
2021-10-18 11:40:00 +02:00
|
|
|
static Item empty_item;
|
2022-09-13 08:44:26 +02:00
|
|
|
const Item *item = map_.lookup_ptr(&node);
|
2021-10-18 11:40:00 +02:00
|
|
|
if (item == nullptr) {
|
|
|
|
|
return empty_item;
|
|
|
|
|
}
|
|
|
|
|
return *item;
|
2021-08-20 13:14:39 +02:00
|
|
|
}
|
|
|
|
|
|
2021-10-05 11:10:25 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
2021-08-20 13:14:39 +02:00
|
|
|
} // namespace blender::nodes
|