-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathComponentBaseImpl.h
194 lines (165 loc) · 5.51 KB
/
ComponentBaseImpl.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#ifndef __ADDIN_NATIVE__H__
#define __ADDIN_NATIVE__H__
#include "ComponentBase.h"
#include "AddInDefBase.h"
#include "IMemoryManager.h"
#include "Map.h"
#include "register.h"
#include <string>
#include <functional>
////////////////////////////////////////////////////////////////////////////////
/// @class base implementation of the IComponent iterface
////////////////////////////////////////////////////////////////////////////////
class ComponentBaseImpl : public IComponentBase {
public:
// Registration support
typedef std::function<IComponentBase*()> factory_f;
struct Property {
typedef std::function<bool(tVariant*)> prop_f;
Property(const std::wstring& name);
Property(Property&& rhs);
Property& operator=(Property&& rhs);
std::wstring name;
std::wstring eng_name;
prop_f get;
prop_f set;
}; // Property
struct Method {
typedef std::function<bool(tVariant*, long, tVariant*)> method_f;
typedef std::function<bool(tVariant*)> get_arg_f;
typedef std::vector<get_arg_f> get_arg_list_t;
static bool empty_argument(tVariant* arg);
Method(const std::wstring& name);
Method(Method&& rhs);
Method& operator=(Method&& rhs);
method_f func;
get_arg_list_t args;
std::wstring name;
std::wstring eng_name;
bool is_func;
}; // Method
ComponentBaseImpl(const std::wstring& name, long version);
// IInitDoneBase
virtual bool ADDIN_API Init(void* conn);
virtual bool ADDIN_API setMemManager(void* mem);
virtual long ADDIN_API GetInfo();
virtual void ADDIN_API Done();
// ILanguageExtenderBase
virtual bool ADDIN_API RegisterExtensionAs(WCHAR_T** extName);
virtual long ADDIN_API GetNProps();
virtual long ADDIN_API FindProp(const WCHAR_T* wsPropName);
virtual const WCHAR_T* ADDIN_API GetPropName(
long lPropNum,
long lPropAlias);
virtual bool ADDIN_API GetPropVal(
const long lPropNum,
tVariant* pvarPropVal);
virtual bool ADDIN_API SetPropVal(
const long lPropNum,
tVariant* varPropVal);
virtual bool ADDIN_API IsPropReadable(const long lPropNum);
virtual bool ADDIN_API IsPropWritable(const long lPropNum);
virtual long ADDIN_API GetNMethods();
virtual long ADDIN_API FindMethod(const WCHAR_T* wsMethodName);
virtual const WCHAR_T* ADDIN_API GetMethodName(
const long lMethodNum,
const long lMethodAlias);
virtual long ADDIN_API GetNParams(const long lMethodNum);
virtual bool ADDIN_API GetParamDefValue(
const long lMethodNum,
const long lParamNum,
tVariant *pvarParamDefValue);
virtual bool ADDIN_API HasRetVal(const long lMethodNum);
virtual bool ADDIN_API CallAsProc(
const long lMethodNum,
tVariant* paParams,
const long lSizeArray);
virtual bool ADDIN_API CallAsFunc(
const long lMethodNum,
tVariant* pvarRetValue,
tVariant* paParams,
const long lSizeArray);
// LocaleBase
virtual void ADDIN_API SetLocale(const WCHAR_T* loc);
void* malloc(unsigned long size) const;
void free(void** ptr) const;
template<typename T, typename... Args>
typename std::enable_if<!std::is_array<T>::value, T*>::type
alloc(Args&&... args) const {
T* ptr = static_cast<T*>(malloc(sizeof(T)));
if (ptr) {
try {
::new (static_cast<void*>(ptr)) T(std::forward<Args>(args)...);
} catch (...) {
free(reinterpret_cast<void**>(&ptr));
throw;
}
}
return ptr;
}
template<typename T>
typename std::enable_if<
std::is_array<T>::value && std::extent<T,0>::value == 0,
typename std::remove_extent<T>::type*
>::type alloc(size_t count) const {
typedef typename std::remove_extent<T>::type type;
type* ptr = static_cast<type*>(malloc(sizeof(type)*count));
if (ptr) {
try {
::new (static_cast<void*>(ptr)) type[count];
} catch (...) {
free(reinterpret_cast<void**>(&ptr));
throw;
}
}
return ptr;
}
protected:
void add_property(
const std::wstring& name,
const Property::prop_f& get = Property::prop_f(),
const Property::prop_f& set = Property::prop_f(),
const std::wstring& eng_name = std::wstring());
void add_method(
const std::wstring& name, bool is_func,
const Method::method_f& func,
const Method::get_arg_list_t& args = {},
const std::wstring& eng_name = std::wstring());
IAddInDefBase* connect_;
IMemoryManager* memory_;
private:
Map<Method> methods_;
Map<Property> props_;
std::wstring name_;
long ver_;
}; // ComponentBase
class ComponentRegister
: public generic_register<
std::wstring,
ComponentBaseImpl::factory_f,
ComponentRegister> {
public:
static std::wstring& class_names() {
return class_names_;
}
template<typename Component>
static void reg_name() {
if (!class_names_.empty()) {
class_names_ += '|';
}
class_names_ += Component::class_name();
}
private:
static std::wstring class_names_;
}; // ComponentRegister
template<typename Component>
struct ComponentRegisterer : generic_registerer<ComponentRegister> {
ComponentRegisterer()
: generic_registerer<ComponentRegister>(Component::class_name(), &Component::make) {
ComponentRegister::reg_name<Component>();
}
}; // ComponentRegisterer
#define REGISTER_COMPONENT__(component_name, line) static ComponentRegisterer<component_name> component_registerer ## _ ## line
#define REGISTER_COMPONENT_EXPANDER__(component_name, line) REGISTER_COMPONENT__(component_name, line)
#define REGISTER_COMPONENT(component_name) REGISTER_COMPONENT_EXPANDER__(component_name, __LINE__)
#endif // __ADDIN_NATIVE__H__