You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/Module/GeoSigmaDraw/ObjectProxyFactory.h

210 lines
4.1 KiB
C

1 month ago
#pragma once
#include <functional>
#include <any>
#include "ActionAddItem.h"
#include "ItemEraser.h"
#include "DrawOperator/Util.h"
#include "Util.h"
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڻ<EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
class ObjectProxy
{
public:
virtual ~ObjectProxy() = default;
/**
* <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>ԣ<EFBFBD>Ϊ<EFBFBD><EFBFBD>ͨ<EFBFBD>ã<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>
*
* \param name <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
*/
virtual CString GetProperty(const CString& name) const = 0;
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param name <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param value <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
*/
virtual void SetProperty(const CString& name, const CString& value) = 0;
};
/**
* <EFBFBD><EFBFBD>Ƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
class CItemEraserProxy : public ObjectProxy
{
public:
CItemEraserProxy(CItemEraser* eraser)
: m_eraser(eraser)
{
assert(m_eraser != nullptr);
}
CString GetProperty(const CString& name) const override
{
if (name == EraserMode)
{
return GetEraserMode();
}
else if (name == EraserRadius)
{
return GetEraserRadius();
}
else
{
return "";
}
}
void SetProperty(const CString& name, const CString& value) override
{
if (name == EraserMode)
{
SetEraserMode(value);
}
else if (name == EraserRadius)
{
SetEraserRadius(value);
}
}
private:
CString GetEraserMode() const
{
switch (m_eraser->GetEraserMode())
{
case EraserMode::Normal:
return Normal;
break;
case EraserMode::Segments:
return Segments;
break;
case EraserMode::Nodes:
return Nodes;
break;
default:
return "";
}
}
void SetEraserMode(const CString& mode)
{
if (mode == Normal)
{
m_eraser->SetEraserMode(EraserMode::Normal);
}
else if (mode == Segments)
{
m_eraser->SetEraserMode(EraserMode::Segments);
}
1 month ago
if (mode == Nodes)
1 month ago
{
m_eraser->SetEraserMode(EraserMode::Nodes);
}
}
CString GetEraserRadius() const
{
return ToCString(m_eraser->GetEraserRadius());
}
void SetEraserRadius(const CString& value)
{
int radius = _ttoi(value);
m_eraser->SetEraserRadius(radius);
}
CItemEraser* m_eraser;
const LPCTSTR EraserMode = _T("EraserMode");
const LPCTSTR EraserRadius = _T("EraserRadius");
const LPCTSTR Normal = _T("Normal");
const LPCTSTR Segments = _T("Segments");
const LPCTSTR Nodes =_T("Nodes");
};
/**
* @class ObjectProxyFactory
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>󹤳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* <EFBFBD>˹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ά<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD>ͻ<EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƺ͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>̬<EFBFBD>Ժ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD>󹹽<EFBFBD><EFBFBD><EFBFBD>
*/
class ObjectProxyFactory
{
public:
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>Ĭ<EFBFBD>ϵĴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* ʹ<EFBFBD><EFBFBD> typeid ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD>ƴд<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD>Ĭ<EFBFBD>ϵ<EFBFBD> CItemEraser <EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
ObjectProxyFactory()
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2>ʱʹ<CAB1><CAB9> typeid <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׺<EFBFBD><D7BA>ƴд<C6B4><D0B4><EFBFBD>󣬵<EFBFBD><F3A3ACB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><D7A2><EFBFBD>ӿڲ<D3BF><DAB2><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E1B9A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
RegisterConstructor<CItemEraserProxy, CItemEraser*>(typeid(CItemEraser).name());
}
/**
* @brief ע<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @tparam Proxy Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̳<EFBFBD><EFBFBD><EFBFBD> ObjectProxy<EFBFBD><EFBFBD>
* @tparam Arg <EFBFBD><EFBFBD><EFBFBD><EFBFBD> Proxy <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD>
* @param name <EFBFBD><EFBFBD><EFBFBD>ڱ<EFBFBD>ʶ<EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD>һ<EFBFBD><EFBFBD>ΪĿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><EFBFBD><EFBFBD>
*/
template <typename Proxy, typename Arg>
void RegisterConstructor(const CString& name)
{
auto constructor = [](std::any arg) -> std::unique_ptr<ObjectProxy>
{
return std::make_unique<Proxy>(std::any_cast<Arg>(arg));
};
m_constructors[name] = constructor;
}
/**
* @brief ע<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param name Ҫע<EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
*/
void UnregisterConstructor(const CString& name)
{
auto it = m_constructors.find(name);
if (it != m_constructors.end())
{
m_constructors.erase(it);
}
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƺͲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* @param name Ŀ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param arg <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD>ʱһ<EFBFBD>£<EFBFBD><EFBFBD><EFBFBD>
* @return std::unique_ptr<ObjectProxy> <EFBFBD>ɹ<EFBFBD><EFBFBD>򷵻ش<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD> nullptr<EFBFBD><EFBFBD>
*/
std::unique_ptr<ObjectProxy> Create(const CString& name, std::any arg) const
{
auto it = m_constructors.find(name);
if (it != m_constructors.end())
{
return it->second(arg);
}
return nullptr;
}
private:
using constructor = std::function <std::unique_ptr<ObjectProxy>(std::any)>;
std::unordered_map<CString, constructor, CStringHash> m_constructors;
};