Templated class that will automatically register a type based on an identifier.
By making use of static
variables inside functions in our Shape class. This is also called the Construct On First Use Idiom.
struct Shape {
using deserialize_func = std::function<std::unique_ptr<Shape>(std::istream&)>;
virtual ~Shape() = default;
// Prevent anyone from directly inhereting from Shape
virtual void DoNotInheritFromShapeDirectlyButFromShapeInterfaceInstead() = 0;
static std::map<std::string, deserialize_func>& get_registry() {
static std::map<std::string, deserialize_func> registry;
return registry;
}
};
template<class T>
struct ShapeInterface : public Shape {
virtual ~ShapeInterface() { if(!registered_) cout << "bad" << endl; } // registerd_ needs to be accessed somewhere, otherwise it is opted away
static inline bool register_type() {
auto& registry = get_registry();
registry[T::class_identifier] = T::deserialize_func;
return true;
}
static const bool registered_;
protected:
virtual void DoNotInheritFromShapeDirectlyButFromShapeInterfaceInstead() final {}
};
template<class T>
const bool ShapeInterface<T>::registered_ = ShapeInterface<T>::register_type();
struct Rectangle : public ShapeInterface<Rectangle> {
static inline const std::string class_identifier = "rectangle";
static std::unique_ptr<Shape> deserialize_func(std::istream& in) { return make_unique<Rectangle>(); }
};
struct Circle : public ShapeInterface<Circle> {
static inline const std::string class_identifier = "circle";
static std::unique_ptr<Shape> deserialize_func(std::istream& in) { return make_unique<Circle>(); }
};
Alternative:
// Registry
template <typename T>
class AssetRegistry {
public:
using CreateFunction = std::function<std::shared_ptr<T>()>;
using CreateFunctionMap = std::unordered_map<EAssetDefType, CreateFunction>;
AssetRegistry(const AssetRegistry&) = delete;
AssetRegistry& operator=(const AssetRegistry&) = delete;
static bool Add(const EAssetDefType type, CreateFunction function) {
auto& map = GetCreateFunctionMap();
if (map.find(type) != map.end()) {
return false;
}
GetCreateFunctionMap()[type] = function;
return true;
}
static std::shared_ptr<T> Create(const EAssetDefType type) {
auto& map = GetCreateFunctionMap();
if (map.find(type) == map.end()) {
return nullptr;
}
return map[type]();
}
private:
static CreateFunctionMap& GetCreateFunctionMap() {
static CreateFunctionMap map;
return map;
}
};
// Registering class
template
<typename T>
class AssetDefRegister
{
public:
virtual ~AssetDefRegister() { if (!s_registered) { std::cout << "bad" << std::endl; } }
protected:
static bool s_registered;
};
template <typename T>
inline bool AssetDefRegister<T>::s_registered = AssetRegistry<AssetDef>::Add(T::GetStaticType(), T::Create);
// Class using registry
class MeshDef : public AssetDef, public AssetDefRegister<MeshDef> {
public:
constexpr static EAssetDefType GetStaticType() { return EAssetDefType::kMeshDef; }
static std::shared_ptr<AssetDef> Create();
std::string meta;
CollisionDef collision_def;
virtual void FromData(const json& json_data) override;
};
A plug is a point on a dependency node where a particular attribute can be connected. In simple cases the plug and attribute are equivalent. When you have array attributes, however, the plug is more specific in that it indicates which of the array elements is to be connected.
There are two main types of plugs: networked plugs and non-networked plugs. Non-networked plugs can be considered user plugs as they are created by users and belong to users. Networked plugs can be considered dependency node plugs as they are part of the dependency graph and can only be referenced by users.
In every dependency node there is a network or "tree" of plugs indicating connections that have been made to attributes of the node. The plugs in this tree are known as networked plugs as they belong to the dependency node's network.
Using MFnDependencyNode.findPlug will fail with an exception if the plug doesn't exist.
plug = om.MPlug()
try:
plug = fn_dependency.findPlug(plug_name, False)
except:
add_plug_to_node(node, plug_name)
plug = fn_dependency.findPlug(plug_name, False)
Convert ['string1','string2', ...]
to {"string1", "string2", ...}
def convert_strings_to_mel_array(py_strs):
return str([str(x) for x in py_strs]).replace("'","\"").replace("[","{").replace("]", "}")