-
Notifications
You must be signed in to change notification settings - Fork 2
/
oXCompLib.cpp
261 lines (210 loc) · 7.13 KB
/
oXCompLib.cpp
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
/*
* omnis.xcomp.framework
* =====================
*
* oXCompLib.h
* Base class for our library definition.
*
* You need to subclass this and implement the needed methods then instantiate your class as a global called gXCompLib
*
* Bastiaan Olij
*
* Todos:
* - finish implementation of static methods
*
* https://github.com/BastiaanOlij/omnis.xcomp.framework
*/
#include "oXCompLib.h"
// constructor
oXCompLib::oXCompLib(void){
// nothing to do here right now...
};
// destructor
oXCompLib::~oXCompLib(void) {
// Make sure we properly clear our memory
// we aren't freeing the memory for mComponents, mECOObjects, etc. itself, that will happen when the library unloads
// but we do need to free the memory allocated by the objects contained within.
// I guess one day we could subclass qArray<OXFComponent> and put this logic inside of clear and call clear from the destruct.
while (mComponents.numberOfElements() > 0) {
OXFcomponent lvComponent = mComponents.pop();
if (lvComponent.mProperties != 0) {
delete lvComponent.mProperties;
};
if (lvComponent.mMethods != 0) {
delete lvComponent.mMethods;
};
if (lvComponent.mEvents != 0) {
delete lvComponent.mEvents;
};
};
mECOobjects.clear();
};
// get our library resource id
qint oXCompLib::getResourceID(void) {
return 1000;
};
// get major version number
qshort oXCompLib::major() {
return 1;
};
// get minor version number
qshort oXCompLib::minor() {
return 0;
};
// return our objects as an Omnis structure
qECOobjects *oXCompLib::objects(void) {
return &mECOobjects;
};
// Add a component
void oXCompLib::addComponent(OXFcomponent pAdd) {
// qstring tmpString;
// tmpString.appendFormattedString("Adding component %li", pAdd.componentID);
// str255 tmpStr(tmpString.cString());
// ECOaddTraceLine(&tmpStr);
if (pAdd.componentType == cObjType_NVObject) {
// also add it to our mECOobjects list, this is how Omnis requires it...
ECOobject lvNVObject;
lvNVObject.mObjectID = pAdd.componentID; // Components' ID for the object
lvNVObject.mNameResID = pAdd.componentID; // Objects' name resource id (equals our component ID
lvNVObject.mFlags = pAdd.flags; // Flags
lvNVObject.mGroupResID = pAdd.groupResID; // Objects' group resource id (may be 0 for default)
mECOobjects.push(lvNVObject);
} else {
// We just need to map it as Omnis does not expect our visual components to be mixed with our non-visual ones.
mVisIndex.push((uint)mComponents.numberOfElements()); // as we're about to add our component but our index is 0 based, this works fine:)
};
mComponents.push(pAdd);
};
// return number of visual components
unsigned long oXCompLib::numberOfvisComps(void) {
return mVisIndex.numberOfElements();
};
// return visual component by index using our vis index
OXFcomponent oXCompLib::visCompByIndex(uint pIndex) {
uint lvIndex = (uint)mVisIndex[pIndex];
return componentByIndex(lvIndex);
};
// return the number of components in our library
unsigned long oXCompLib::numberOfComponents(void) {
return mComponents.numberOfElements();
};
// return component by index
OXFcomponent oXCompLib::componentByIndex(uint pIndex) {
return mComponents[pIndex];
};
// return component by component ID
OXFcomponent oXCompLib::componentByID(long pCompID) {
static OXFcomponent lvEmpty;
for (uint i = 0; i < mComponents.numberOfElements(); i++) {
OXFcomponent lvComponent = mComponents[i];
if (lvComponent.componentID == pCompID) {
return lvComponent;
}
}
lvEmpty.componentType = 0;
return lvEmpty;
};
// instantiate a component by component ID
oBaseComponent *oXCompLib::instantiateComponent(long pCompID, EXTCompInfo *pECI, HWND pHWND, LPARAM pParam) {
// Once we redo how we handle parameters and methods we can remove pCompID and use pECI->mCompId instead
OXFcomponent lvComponent = componentByID(pCompID);
if (lvComponent.componentType != 0) {
oBaseComponent *lvObject = (oBaseComponent *)lvComponent.newObjectFunction();
if ((lvObject != NULL) && (pECI != NULL)) {
// and insert into a chain of objects. The OMNIS library will maintain this chain
if (lvComponent.componentType == cObjType_NVObject) {
oBaseNVComponent *lvNVObject = (oBaseNVComponent *)lvObject;
lvNVObject->init(ECOgetApp(pECI->mInstLocp), (qobjinst)pParam);
ECOinsertNVObject(pECI->mOmnisInstance, pParam, (void *)lvObject);
} else {
oBaseVisComponent *lvVisObject = (oBaseVisComponent *)lvObject;
lvVisObject->init(ECOgetApp(pECI->mInstLocp), pHWND);
ECOinsertObject(pECI, pHWND, (void *)lvObject);
}
}
return lvObject;
}
return NULL;
};
// add methods to our vector
void oXCompLib::addStaticMethods(ECOmethodEvent *pMethods, int pCount) {
// for now we copy our methods into a vector. Seeing the nature of static methods we may change this in due course, not sure yet
for (int i = 0; i < pCount; i++) {
mStaticMethods.push_back(pMethods[i]);
};
};
// number of static methods in our library
unsigned long oXCompLib::numberOfStaticMethods(void) {
return mStaticMethods.size();
};
// return pointer to array of static methods in our library
ECOmethodEvent *oXCompLib::staticMethods(void) {
return mStaticMethods.data();
};
// return property meta data for this object
qProperties *oXCompLib::properties(long pCompID) {
OXFcomponent lvComponent = componentByID(pCompID);
if (lvComponent.componentType != 0) {
return lvComponent.mProperties;
};
return NULL;
};
// return method meta data for this object
qMethods *oXCompLib::methods(long pCompID) {
OXFcomponent lvComponent = componentByID(pCompID);
if (lvComponent.componentType != 0) {
return lvComponent.mMethods;
};
return NULL;
};
// return our event method resource ID
unsigned int oXCompLib::eventMethodID(long pCompID) {
OXFcomponent lvComponent = componentByID(pCompID);
if (lvComponent.componentType != 0) {
return lvComponent.mEventMethodID;
};
return 0;
};
// return event meta data for this object
qEvents *oXCompLib::events(long pCompID) {
OXFcomponent lvComponent = componentByID(pCompID);
if (lvComponent.componentType != 0) {
return lvComponent.mEvents;
};
return NULL;
};
// initialize our library
qint oXCompLib::ecm_connect(void) {
qint lvFlags = EXT_FLAG_LOADED | EXT_FLAG_ALWAYS_USABLE | EXT_FLAG_REMAINLOADED;
if ((this->numberOfStaticMethods() > 0) || (mECOobjects.numberOfElements() != 0)) {
lvFlags = lvFlags | EXT_FLAG_NVOBJECTS; // Let Omnis know we also include non-visual object, this means ECM_GETSTATICOBJECT and ECM_GETOBJECT will be called
}
return lvFlags;
};
// cleanup
qbool oXCompLib::ecm_disconnect(void) {
// should clear out gComponents...
return qtrue;
};
// invoke a static method
int oXCompLib::invokeMethod(qlong pMethodId, EXTCompInfo *pECI) {
// no static methods by default
qstring tmpString;
tmpString.appendFormattedString("Unknown static method call %li", pMethodId);
str255 tmpStr(tmpString.cString());
ECOaddTraceLine(&tmpStr);
return 1L;
};
mainlib *mainlib::singleton = NULL;
mainlib *mainlib::get_singleton() {
if (mainlib::singleton == NULL) {
mainlib::singleton = new mainlib();
}
return mainlib::singleton;
}
void mainlib::cleanup() {
if (mainlib::singleton != NULL) {
delete mainlib::singleton;
mainlib::singleton = NULL;
}
}