1 /*****************************************************************************
2  *
3  * Copyright (c) 2008-2010, CoreCodec, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *     * Redistributions of source code must retain the above copyright
9  *       notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above copyright
11  *       notice, this list of conditions and the following disclaimer in the
12  *       documentation and/or other materials provided with the distribution.
13  *     * Neither the name of CoreCodec, Inc. nor the
14  *       names of its contributors may be used to endorse or promote products
15  *       derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY CoreCodec, Inc. ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL CoreCodec, Inc. BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  ****************************************************************************/
29 
30 #ifndef __NODEBASE_H
31 #define __NODEBASE_H
32 
33 #define MAXDATA				(MAXPATH*sizeof(tchar_t))
34 
35 //----------------------------------------------------------------
36 // data types
37 
38 #define TYPE_BOOLEAN		1		// bool_t
39 #define TYPE_INT			2		// int
40 #define TYPE_FRACTION		3		// cc_fraction
41 #define TYPE_STRING			4		// null terminated tchar_t[]
42 #define TYPE_RECT			5		// rect
43 #define TYPE_POINT			6		// point
44 #define TYPE_RGB			7		// rgbval_t
45 #define TYPE_FOURCC			8		// fourcc_t
46 #define TYPE_FILEPOS		9		// filepos_t
47 #define TYPE_NODE			10		// node* (format1: node class)
48 #define TYPE_META		    11		// metanotify
49 #define TYPE_PACKET			12		// flow packet pin
50 #define TYPE_TICK			13		// tick_t
51 #define TYPE_NODENOTIFY     14      // nodenotify (private)
52 #define TYPE_PTR			15		// void*
53 #define TYPE_BINARY			16		// binary data (format1: size)
54 #define TYPE_NOTIFY			17		// notify
55 #define TYPE_INT8			18		// int8_t
56 #define TYPE_INT16			19		// int16_t
57 #define TYPE_INT32			20		// int32_t
58 #define TYPE_INT64			21		// int64_t
59 #define TYPE_FUNC			22		// nodefunc
60 #define TYPE_NODE_REF       23      // node*
61 #define TYPE_BOOL_BIT       24      // bool_t
62 #define TYPE_PIN            25      // pin
63 #define TYPE_EVENT          26      // void
64 #define TYPE_EXPR           27
65 #define TYPE_POINT16        28      // cc_point16
66 #define TYPE_RECT16         29      // int16_t[4]
67 #define TYPE_ARRAY          30
68 #define TYPE_EXPRSTRING     31
69 #define TYPE_EXPRPARAM      32
70 #define TYPE_DATETIME		33		// datetime_t
71 #define TYPE_DBNO     		34		// db_no
72 #define TYPE_GUID           35      // cc_guid
73 #define TYPE_FIX16          36      // int
74 #define TYPE_LUA_REF        37      // int
75 #define TYPE_NOTIFYEX       38
76 #define TYPE_ENUM           39      // dataenum
77 #define TYPE_ENUM_MULTI_SET 40      // multi_enum_set
78 #define TYPE_SIZE           41      // size_t
79 
80 #define MAX_PARAMTYPE		42
81 #define TYPE_MASK           0x3F
82 
83 #define PERCENT_ONE			1024
84 #define FIX16_SHIFT         16
85 #define FIX16_UNIT          (1<<FIX16_SHIFT)
86 
87 #define TFLAG_DEFAULT       0x00000100
88 #define TFLAG_RDONLY		0x00000200
89 #define TFLAG_SETUP			0x00000400
90 #define TFLAG_SETTINGS  	0x00000800 // should be managed in a settings page
91 #define TFLAG_INPUT         0x00001000
92 #define TFLAG_OUTPUT        0x00002000
93 #define TFLAG_NOSAVE        0x00004000
94 #define TFLAG_ENUM          0x00008000 // Id|DATA_ENUM can be used
95 #define TFLAG_NOTIFY        0x00010000
96 #define TFLAG_UPDATEMODE    0x00020000
97 #define TFLAG_NODUMP        0x00040000
98 #define TFLAG_HOTKEY        0x00080000
99 #define TFLAG_DISPLAY       0x00100000
100 #define TFLAG_AVAILABLE     0x00200000 // Id|DATA_AVAILABLE can be used
101 // TFLAG_ENUM (sub)flags
102 #define TFLAG_EDITABLE_ENUM 0x00400000
103 #define TFLAG_MULTI_ENUM    0x00800000 // Id|DATA_ENUM_MULTI can be used
104 #define TFLAG_POPUP         0x01000000
105 
106 #define TUNIT_SHIFT       24
107 #define TUNIT_MASK        0x1F000000
108 #define TUNIT_KBYTE       0x01000000
109 #define TUNIT_SECOND      0x02000000
110 #define TUNIT_MHZ         0x03000000
111 #define TUNIT_XCOORD      0x04000000
112 #define TUNIT_YCOORD      0x05000000
113 #define TUNIT_BYTERATE    0x06000000
114 #define TUNIT_FOLDER      0x07000000
115 #define TUNIT_NUMBER      0x08000000
116 #define TUNIT_FIX16       0x09000000 //TODO: replace TYPE_FIX16 with TYPE_INT|TUNIT_FIX16
117 #define TUNIT_IP          0x0A000000
118 #define TUNIT_COORD       0x0B000000
119 #define TUNIT_PASSWORD    0x0C000000
120 // TODO: not really units use the old TFORMAT_ for that (and a TFORMAT_MASK as well)
121 #define TUNIT_UPPER       0x0D000000
122 #define TUNIT_HOTKEY      0x0E000000
123 #define TUNIT_CHECKLIST   0x0F000000 // TYPE_BOOLEAN only
124 #define TUNIT_PERCENT     0x10000000
125 #define TUNIT_HEX         0x11000000
126 #define TUNIT_TASK        0x12000000 // TYPE_BOOLEAN only
127 
128 typedef uint_fast32_t dataid;
129 typedef uint_fast32_t datatype;
130 typedef uint_fast32_t dataflags;
131 typedef uint_fast32_t datameta;
132 
133 typedef struct datadef
134 {
135 	dataid Id;
136 	dataflags Flags;
137 
138 } datadef;
139 
140 //---------------------------------------------------------------
141 // future meta info...
142 
143 #define META_CLASS_SIZE			10 //size_t
144 #define META_CLASS_FLAGS		11 //int
145 #define META_CLASS_PRIORITY		12 //uint16_t
146 #define META_CLASS_CREATE		13 //int (*)(node*)
147 #define META_CLASS_DELETE		14 //void (*)(node*)
148 #define META_CLASS_VMT_SIZE		15 //size_t
149 #define META_CLASS_VMT_CREATE	16 //int (*)(fourcc_t,void*)
150 #define META_CLASS_VMT_DELETE	17 //void (*)(fourcc_t,void*)
151 #define META_CLASS_META         18 //bool_t (*)(nodecontext*,void*,datameta Meta,uintptr_t* Data)
152 
153 #define META_PARAM_NAME			30 //const tchar_t*
154 #define META_PARAM_TYPE		    31 //uint32_t (with flags)
155 #define META_PARAM_MIN			32 //int (for TYPE_INT or TYPE_TICK)
156 #define META_PARAM_MAX			33 //int (for TYPE_INT or TYPE_TICK)
157 #define META_PARAM_CLASS		34 //fourcc_t (for TYPE_NODE or TYPE_FOURCC)
158 #define META_PARAM_ENUMLANG     36 //fourcc_t (for TYPE_INT or TYPE_FOURCC)
159 #define META_PARAM_ENUMNAME     37 //const tchar_t* (for TYPE_INT or TYPE_FOURCC)
160 #define META_PARAM_BIT          38 //uint32_t (for TYPE_BOOL_BIT)
161 #define META_PARAM_SIZE			39 //size_t (for TYPE_BINARY or TYPE_STRING)
162 #define META_PARAM_GET			40 //nodeget
163 #define META_PARAM_SET			41 //nodeset
164 #define META_PARAM_UNSET		42 //nodeunset
165 #define META_PARAM_STRING		44 //const tchar_t*
166 #define META_PARAM_EVENT		45 //nodeupdatefunc (ERR_NONE result will cause searching more event handlers)
167 #define META_PARAM_CUSTOM       47
168 #define META_PARAM_UPDATETIME   48 //tick_t
169 #define META_PARAM_ARRAY_TYPE	49 //dataflags
170 #define META_PARAM_META         50 //bool_t (*)(node*,dataid Id,datameta Meta,uintptr_t* Data)
171 #define META_PARAM_ENUMVALUE    53 //void* array
172 #define META_PARAM_ENUMVALUESIZE 54 //size_t
173 #define META_PARAM_ENUMFILTER   55 //bool_t (*)(node*,dataid Id,const void* Value,size_t Size)
174 
175 // private
176 #define META_CLASS_PARENT_ID	0  //fourcc_t
177 #define META_CLASS_CLASS_ID		1  //fourcc_t
178 #define META_PARAM_DATA_FLAGS	2  //int      (must be after META_DATA)
179 #define META_PARAM_DATA_RELEASE	3  //nodeupdatefunc (must be after META_DATA,META_PARAM_DATA_FLAGS)
180 #define META_PARAM_DATA_UPDATE	4  //nodeupdatefunc (must be after META_DATA,META_PARAM_DATA_FLAGS,META_PARAM_DATA_RELEASE)
181 
182 #define DFLAG_RDONLY	        1
183 #define DFLAG_CMP 	            2
184 #define DFLAG_NOTIFY            4
185 #define DFLAG_VERIFY_CLASS      8
186 #define DFLAG_NODEFAULT         16
187 
188 #define META_MODE_MASK		192
189 #define META_MODE_DATA		64	   // param with data
190 #define META_MODE_CONST		128    // constant in object (set during NodeCreate)
191 #define META_MODE_VMT		192	   // constant in vmt (set during NodeRegisterClass)
192 
193 #if defined(CONFIG_CORECDOC)
194 // assume that only TYPE_FUNC is used with META_MODE_VMT so far (so we have up to 22 that are safe)
195 #define TYPE_DOC_PARAM_NO      (META_MODE_VMT|0)
196 #define TYPE_DOC_CLASS_ID      (META_MODE_VMT|1)
197 #define TYPE_DOC_VMT_STRUCT    (META_MODE_VMT|2)
198 #define TYPE_DOC_VMT_FUNC      (META_MODE_VMT|3)
199 
200 #define DOC_PARAM_DESCRIPTION  (META_MODE_VMT|4)
201 #define DOC_PARAM_NAME         (META_MODE_VMT|5)
202 #define DOC_CLASS_DESCRIPTION  (META_MODE_VMT|6)
203 #endif
204 
205 typedef struct nodemeta
206 {
207 	uint32_t Meta:8;
208 	uint32_t Id:24;
209 	uintptr_t Data;
210 
211 } nodemeta;
212 
213 #ifdef __cplusplus
214 #define META_START(name,id) extern "C" { extern const nodemeta name[]; } const nodemeta name[] = { META_START_CONTINUE(id)
215 #else
216 #define META_START(name,id) const nodemeta name[] = { META_START_CONTINUE(id)
217 #endif
218 #define META_START_CONTINUE(id) META_CLASS(CLASS_ID,id)
219 #define META_CLASS(meta,data) { META_CLASS_##meta,0,(uintptr_t)(data) },
220 #define META_PARAM(meta,no,data) { META_PARAM_##meta,no,(uintptr_t)(data) },
221 #define META_DATA(type,no,name,param) { META_MODE_DATA|(type),no,(uintptr_t)(OFS(name,param)) },
222 #define META_DATA_FLAGS(type,no,name,param,flags) META_DATA(type,no,name,param) META_PARAM(DATA_FLAGS,no,flags)
223 #define META_DATA_RDONLY(type,no,name,param) META_DATA_FLAGS(type,no,name,param,DFLAG_RDONLY)
224 #define META_DATA_UPDATE(type,no,name,param,update) META_DATA(type,no,name,param) META_PARAM(DATA_UPDATE,no,update)
225 #define META_DATA_UPDATE_FLAGS(type,no,name,param,update,flags) META_DATA(type,no,name,param) META_PARAM(DATA_FLAGS,no,flags) META_PARAM(DATA_UPDATE,no,update)
226 #define META_DATA_UPDATE_CMP(type,no,name,param,update) META_DATA_UPDATE_FLAGS(type,no,name,param,update,DFLAG_CMP)
227 #define META_DATA_UPDATE_RELEASE(type,no,name,param,update,release,flags) META_DATA(type,no,name,param) META_PARAM(DATA_FLAGS,no,flags) META_PARAM(DATA_RELEASE,no,release) META_PARAM(DATA_UPDATE,no,update)
228 #define META_DYNAMIC(type,no) { META_MODE_DATA|(type),no,(uintptr_t)-1 },
229 #define META_DYNAMIC_FLAGS(type,no,flags) META_DYNAMIC(type,no) META_PARAM(DATA_FLAGS,no,flags)
230 #define META_DYNAMIC_RDONLY(type,no) META_DYNAMIC_FLAGS(type,no,DFLAG_RDONLY)
231 #define META_DYNAMIC_UPDATE(type,no,update) META_DYNAMIC(type,no) META_PARAM(DATA_UPDATE,no,update)
232 #define META_DYNAMIC_UPDATE_FLAGS(type,no,update,flags) META_DYNAMIC(type,no) META_PARAM(DATA_FLAGS,no,flags) META_PARAM(DATA_UPDATE,no,update)
233 #define META_DYNAMIC_UPDATE_CMP(type,no,update) META_DYNAMIC_UPDATE_FLAGS(type,no,update,DFLAG_CMP)
234 #define META_VMT(type,name,param,value) { META_MODE_VMT|(type),OFS(name,param),(uintptr_t)(value) },
235 #define META_CONST(type,name,param,value) { META_MODE_CONST|(type),OFS(name,param),(uintptr_t)(value) },
236 #define META_END(parentid) { META_CLASS_PARENT_ID,0,(uintptr_t)(parentid) }};
237 #define META_END_CONTINUE(parentid) { META_CLASS_PARENT_ID,1,(uintptr_t)(parentid) },
238 
239 #define META_PARAM_DOC(type,no,data)
240 #define META_CLASS_DOC(type,data)
241 
242 #if defined(CONFIG_CORECDOC)
243 #undef META_START
244 #undef META_START_CONTINUE
245 #undef META_PARAM
246 #undef META_DATA
247 #undef META_DYNAMIC
248 #undef META_VMT
249 #undef META_PARAM_DOC
250 #undef META_CLASS_DOC
251 #define META_START_CONTINUE(id) META_CLASS(CLASS_ID,id) \
252 	                            { TYPE_DOC_CLASS_ID,id,(uintptr_t)T(#id) },
253 #ifdef __cplusplus
254 #define META_START(name,id) extern "C" { extern const nodemeta name[]; } const nodemeta name[] = { META_CLASS(CLASS_ID,id) \
255 	                            { TYPE_DOC_CLASS_ID,id,(uintptr_t)T(#id) },
256 #else
257 #define META_START(name,id) const nodemeta name[] = { META_CLASS(CLASS_ID,id) \
258 	                            { TYPE_DOC_CLASS_ID,id,(uintptr_t)T(#id) },
259 #endif
260 #define META_PARAM(meta,no,data) { META_PARAM_##meta,no,(uintptr_t)(data) },\
261                                  { TYPE_DOC_PARAM_NO,no,(uintptr_t)T(#no) },
262 #define META_DATA(type,no,name,param) { META_MODE_DATA|(type),no,(uintptr_t)(OFS(name,param)) },\
263                                       { TYPE_DOC_PARAM_NO,no,(uintptr_t)T(#no) },
264 #define META_DYNAMIC(type,no) { META_MODE_DATA|(type),no,(uintptr_t)-1 },\
265                               { TYPE_DOC_PARAM_NO,no,(uintptr_t)T(#no) },
266 #define META_VMT(type,name,param,value) { META_MODE_VMT|(type),OFS(name,param),(uintptr_t)(value) }, \
267                                         { TYPE_DOC_VMT_STRUCT,0,(uintptr_t)T(#name) },   \
268                                         { TYPE_DOC_VMT_FUNC,0,(uintptr_t)T(#param) },
269 
270 #define META_PARAM_DOC(type,no,data)  {type,no,(uintptr_t)data},
271 #define META_CLASS_DOC(type,data)     {type,0,(uintptr_t)data},
272 #endif
273 
274 #define META_PARAM_DOC_DESCRIPTION(no,data) META_PARAM_DOC(DOC_PARAM_DESCRIPTION,no,data)
275 #define META_CLASS_DOC_DESCRIPTION(data) META_CLASS_DOC(DOC_CLASS_DESCRIPTION,data)
276 
277 
278 #define CFLAG_SINGLETON		0x01
279 #define CFLAG_SETTINGS		0x02  // has elements with TFLAG_SETTINGS
280 #define CFLAG_CONFIG        0x04  // save the paramaters
281 #define CFLAG_ABSTRACT		0x08
282 #define CFLAG_LOCAL         0x10
283 #define CFLAG_OWN_MEMORY    0x20
284 
285 //---------------------------------------------------------------
286 // node variable data
287 
288 typedef struct nodedata nodedata;
289 
290 struct nodedata
291 {
292     nodedata* Next;
293 	size_t Code; // Type+(No<<8)
294     //...
295 };
296 
297 #define NodeData_Data(p)  (void*)((nodedata*)p+1)
298 
299 //---------------------------------------------------------------
300 
301 // dataid modifiers (max is 0x800000)
302 #define DATA_ENUM           0x10000 // get:dataenum / set:add named_value / unset:delete value
303 #define DATA_ICON           0x20000 // tchar_t*
304 #define DATA_AVAILABLE      0x40000 // bool_t
305 #define DATA_UPDATEMODE     0x80000 // bool_t
306 #define DATA_DYNNAME       0x100000 // tchar_t*
307 #define DATA_ENUM_MULTI    0x200000 // get:dataenum (with .Name a int flag to tell the status of each value) / set:individual value via multi_enum_set
308 // TODO: use a new dataenumex type for DATA_ENUM_MULTI
309 
310 #define DataidBase(Id) ((Id) & ~(DATA_ENUM|DATA_ICON|DATA_AVAILABLE|DATA_UPDATEMODE|DATA_DYNNAME|DATA_ENUM_MULTI))
311 #define DataidMask(Id) ((Id) &  (DATA_ENUM|DATA_ICON|DATA_AVAILABLE|DATA_UPDATEMODE|DATA_DYNNAME|DATA_ENUM_MULTI))
312 
IsExtendedId(dataid Id,dataid ExtensionStart,size_t ExtensionSize)313 static INLINE bool_t IsExtendedId(dataid Id, dataid ExtensionStart, size_t ExtensionSize)
314 {
315     Id = DataidBase(Id);
316     return (Id >= ExtensionStart && Id < ExtensionStart+ExtensionSize);
317 }
318 
319 typedef struct dataenum
320 {
321     size_t ValueSize;
322     array Name;  // tchar_t
323     array Value; // any type
324 
325 } dataenum;
326 
327 typedef struct multi_enum_set
328 {
329     void *Element;
330     size_t ElementSize;
331     int Value;
332 } multi_enum_set;
333 
334 //---------------------------------------------------------------
335 // node
336 
337 #define NODE_CLASS			FOURCC('N','O','D','E')
338 
339 // strings
340 #define NODE_NAME				0
341 #define NODE_CONTENTTYPE		1
342 #define NODE_EXTS				2
343 #define NODE_PROBE				3
344 #define NODE_PROTOCOL           4
345 #define NODE_ID                 5
346 
347 // events for singleton objects
348 #define NODE_SINGLETON_INSTALL            6
349 #define NODE_SINGLETON_UNINSTALL          7
350 #define NODE_SINGLETON_STARTUP            8  // after the module's classes registered and singleton objects are created
351 #define NODE_SINGLETON_CONFIGURED         9  // after configuration loaded for CFLAG_CONFIG objects
352 #define NODE_SINGLETON_SHUTDOWN           10 // before the module's singleton objects are deleted
353 
354 // events for any class
355 #define NODE_DELETING           11 // can be used as notify
356 #define NODE_SETTINGS_CHANGED   12 // can be used as notify
357 
358 // settings
359 #define NODE_GAP                13
360 #define NODE_SELECT_ALL         14 //TODO: remove
361 #define NODE_SELECT_NONE        15 //TODO: remove
362 
363 // for debug/dump (array)
364 #define NODE_CHILDREN			13
365 
366 // default param
367 #define NODE_DEFAULT_DATA       14 //TODO: fix collision with NODE_SELECT_ALL
368 
369 typedef	err_t (*nodefunc)(void* This);
370 typedef	err_t (*nodeupdatefunc)(void* This,dataid Id);
371 typedef bool_t (*nodeenumfilter)(void* This,dataid Id,const void* Value,size_t Size);
372 
373 typedef const void anynode;
374 typedef void* thisnode;
375 
376 typedef struct nodecontext nodecontext;
377 
378 typedef struct node
379 {
380 #ifdef CONFIG_DEBUGCHECKS
381     fourcc_t    FourCC; // help figure out memory leak
382     uint32_t    Magic;
383 #endif
384     const void* VMT;
385     nodedata*   Data;
386     size_t      RefCount;
387 
388 } node;
389 
390 typedef struct node_vmt
391 {
392 	nodecontext* Context;
393 	fourcc_t ClassId;
394 
395     void (*Enum)(thisnode,array* List);
396     err_t (*Get)(thisnode,dataid Id,void* Data,size_t Size);
397     err_t (*Set)(thisnode,dataid Id,const void* Data,size_t Size);
398     err_t (*UnSet)(thisnode,dataid Id,const void* Data,size_t Size);
399     uintptr_t (*Meta)(thisnode,dataid Id,datameta Meta);
400     dataid (*FindParam)(thisnode,const tchar_t* Token);
401     void* (*SetData)(thisnode,dataid Id, datatype Type,const void* Data);
402 
403 } node_vmt;
404 
405 #define Node_Enum(p,a) VMT_FUNC(p,node_vmt)->Enum(p,a)
406 #define Node_Get(p,a,b,c) VMT_FUNC(p,node_vmt)->Get(p,a,b,c)
407 #define Node_GET(p,a,b) VMT_FUNC(p,node_vmt)->Get(p,a,b,sizeof(*(b)))
408 #define Node_Set(p,a,b,c) VMT_FUNC(p,node_vmt)->Set(p,a,b,c)
409 #define Node_SET(p,a,b) VMT_FUNC(p,node_vmt)->Set(p,a,b,sizeof(*(b)))
410 #define Node_Trigger(p,a) VMT_FUNC(p,node_vmt)->Set(p,a,NULL,0)
411 #define Node_UnSet(p,a,b,c) VMT_FUNC(p,node_vmt)->UnSet(p,a,b,c)
412 #define Node_Meta(p,a,b)  VMT_FUNC(p,node_vmt)->Meta(p,a,b)
413 #define Node_FindParam(p,a) VMT_FUNC(p,node_vmt)->FindParam(p,a)
414 #define Node_SetData(p,i,t,d) VMT_FUNC(p,node_vmt)->SetData(p,i,t,d)
415 
416 //-----------------------------------------------------------------
417 
418 typedef struct pin
419 {
420 	node* Node;
421 	dataid Id;
422 
423 } pin;
424 
425 typedef pin nodeevt;
426 
427 typedef err_t (*notifyproc)(void* This, nodeevt* Evt);
428 
429 typedef	void (*metafunc)(void* Referer, fourcc_t Meta, int32_t Stream, const tchar_t* Value);
430 
431 typedef struct metanotify
432 {
433   	metafunc Func;
434 	void* Referer;
435     int Stream;
436 
437 } metanotify;
438 
439 typedef	err_t (*notifyfunc)(void* This,intptr_t Param,intptr_t Param2);
440 
441 typedef	void (*freefunc)(void* This,void *Ptr);
442 
443 typedef struct notify
444 {
445 	notifyfunc Func;
446 	void* This;
447 
448 } notify;
449 
450 typedef struct notifyex
451 {
452 	notifyfunc Func;
453 	void* This;
454     freefunc Free;
455     void* FreeCookie;
456 
457 } notifyex;
458 
459 typedef struct nodeexpr nodeexpr;
460 
461 //---------------------------------------------------------------
462 // node priority classes
463 
464 #define PRI_MINIMUM			1
465 #define PRI_DEFAULT		 1000
466 #define PRI_MAXIMUM		10000
467 
468 //---------------------------------------------------------------
469 // functions managing node meta information
470 
471 #define NODEMODULE_CLASS		FOURCC('N','M','O','D')
472 #define NODEMODULE_PATH         0x80
473 
474 typedef struct nodeclass nodeclass;
475 typedef struct nodemodule nodemodule;
476 
477 struct nodemodule
478 {
479     node Base;
480     nodemodule* Next;
481 	void* Module;
482 	void* Db;
483 	void* Func;
484 	uint8_t* Min;
485 	uint8_t* Max;
486 	datetime_t Stamp;
487 #if defined(CONFIG_DEBUG_LEAKS)
488     array ClassRefs;
489     void *LockRefs;
490 #endif
491 	uint8_t Found;
492     uint8_t Config;
493     uint8_t Changed;
494 };
495 
496 struct nodecontext
497 {
498     nodemodule Base;
499 	void* NodeLock;
500     const void* NodeCache;
501 	array NodeSingleton;
502 	array NodeClass; // ordered by id
503     const cc_memheap* NodeHeap;
504     const cc_memheap* NodeConstHeap;
505     bool_t (*LoadModule)(nodecontext*,nodemodule*);
506     void (*FreeModule)(nodecontext*,nodemodule*);
507 #if defined(CONFIG_MULTITHREAD)
508     uintptr_t ThreadId;
509     void* PostNotifyParam;
510     bool_t (*PostNotify)(nodecontext*,node*,dataid); // returns if the message has been queued
511 #endif
512     const tchar_t* (*ExternalStr)(nodecontext*,fourcc_t,int);
513     //TODO: runtime datatype meta information handling...
514     void (*ExprRelease)(nodeexpr*);
515     size_t (*ExprSize)(nodeexpr*);
516     void (*ExprDup)(node* Node, nodeexpr*, array* Dup);
517 #if defined(CONFIG_CORELUA)
518     void *LuaCookie;
519     void (*LuaRelease)(void* Cookie, int* Ref);
520     void (*LuaAddRef)(void* Cookie, int* Ref);
521 #endif
522 	void (*ReportError)(nodecontext*, node* Node, fourcc_t MsgClass, int MsgNo, va_list Args);
523 #if defined(TARGET_PALMOS)
524 	fourcc_t ProjFourCC;
525 #endif
526     int Build;
527     int Revision;
528     array Collect;
529     bool_t InCollect;
530     fourcc_t DynamicClass;
531 #if defined(TARGET_SYMBIAN)
532     void *FsSession;
533 #endif
534     uint16_t AppId;
535 };
536 
537 #define NODECONTEXT_CLASS		        FOURCC('N','C','T','X')
538 #define NODECONTEXT_PROJECT_NAME        0x100
539 #define NODECONTEXT_PROJECT_VENDOR      0x101
540 #define NODECONTEXT_PROJECT_VERSION     0x102
541 #define NODECONTEXT_PROJECT_FOURCC      0x103
542 #define NODECONTEXT_PROJECT_HELP        0x104
543 #define NODECONTEXT_PROJECT_BUILD       0x105
544 #define NODECONTEXT_PROJECT_MIME        0x106
545 #define NODECONTEXT_PROJECT_APPID       0x107
546 #define NODECONTEXT_PROJECT_PATH        0x108
547 
548 // notify
549 #define NODECONTEXT_CRASH               0x201
550 
551 NODE_DLL void NodeContext_Init(nodecontext*,const nodemeta* Custom, const cc_memheap* Heap, const cc_memheap* ConstHeap);
552 NODE_DLL void NodeContext_Done(nodecontext*);
553 NODE_DLL bool_t NodeContext_Cleanup(nodecontext* p,bool_t Force);
554 NODE_DLL dataflags NodeContext_FindDataType(const tchar_t* Type, const tchar_t* Format);
555 NODE_DLL size_t NodeTypeSize(datatype); // TODO: use nodecontext* when switching to runtime datatype meta information handling...
556 NODE_DLL const tchar_t *NodeContext_TypeName(datatype Type);
557 NODE_DLL const tchar_t *NodeContext_UnitName(datatype Unit);
558 
559 NODE_DLL void NodeRegisterClassEx(nodemodule*,const nodemeta*);
560 NODE_DLL fourcc_t NodeEnumClass(anynode*,array* List, fourcc_t Class); // List=NULL just returns the first class
561 NODE_DLL fourcc_t NodeEnumClassStr(anynode*,array* ListId, fourcc_t ClassId, int Id, const tchar_t* Str);
562 NODE_DLL void NodeEnumSingletons(anynode*,array* List);
563 NODE_DLL void NodeSingletonEvent(anynode*, dataid Cmd, nodemodule* Module); // Module = NULL for all modules
564 
565 typedef	int (*nodeenumclassfilterrated)(void* Cookie, const nodeclass* Class);
566 NODE_DLL fourcc_t NodeEnumClassFilterRated(anynode*,array* List, fourcc_t Class, nodeenumclassfilterrated Func, void* Cookie);
567 
568 NODE_DLL bool_t NodeIsClass(anynode*,fourcc_t Class, fourcc_t PartOfClass);
569 NODE_DLL const tchar_t* NodeStr2(anynode*,fourcc_t ClassId,int No);
570 NODE_DLL const tchar_t* NodeStrEx(anynode*,fourcc_t ClassId,int No);
571 NODE_DLL node* NodeCreate(anynode*,fourcc_t Class);
572 NODE_DLL node* NodeSingleton(anynode*,fourcc_t Class);
573 
574 NODE_DLL const tchar_t* NodeClass_Str(anynode* AnyNode, const nodeclass*, int No);
575 NODE_DLL uintptr_t NodeClass_Meta(const nodeclass*,dataid Id,datameta Meta);
576 NODE_DLL int NodeClass_Priority(const nodeclass*);
577 NODE_DLL fourcc_t NodeClass_Parent(const nodeclass*);
578 
579 NODE_DLL const nodeclass* NodeContext_FindClass(anynode*, fourcc_t Class);
580 NODE_DLL const nodeclass* NodeContext_FindClassEx(anynode*, fourcc_t Class, nodemodule* Prefered);
581 
582 // functions for existing nodes
583 
584 NODE_DLL void NodeDelete(node*); //TODO: use Node_Release() instead (but Node_Release doesn't support NULL)
585 NODE_DLL void Node_AddRef(thisnode This);
586 NODE_DLL void Node_Release(thisnode This);
587 NODE_DLL int NodeClassFlags(node*);
588 NODE_DLL void NodeClassSetPriority(node*,int Priority);
589 NODE_DLL nodemodule* NodeModule(node*);
590 NODE_DLL nodemodule* NodeClassModule(anynode*,fourcc_t Class);
591 NODE_DLL bool_t NodeFindDef(node*,const tchar_t* Token,datadef* Out);
592 NODE_DLL bool_t NodeDataDef(node* p, dataid Id, datadef* Out);
593 NODE_DLL void NodeEnumDef(node*,array* Out);
594 NODE_DLL void NodeParamName(node* p, dataid Id, tchar_t* Name, size_t NameLen);
595 NODE_DLL const tchar_t* NodeParamStr(const node* p,int No);
596 NODE_DLL void NodeReportError(anynode*, node* Node,fourcc_t MsgClass,int MsgNo,...);
597 
598 NODE_DLL err_t Node_Constructor(anynode*,node* Node,size_t Size, fourcc_t ClassId);
599 NODE_DLL void Node_Destructor(node* Node);
600 
601 NODE_DLL bool_t Node_Notify(node* Node, dataid Id); /// returns wether there were some receivers
602 #if defined(CONFIG_MULTITHREAD)
603 NODE_DLL bool_t Node_PostNotify(node* Node, dataid Id); // supports threading
604 #else
605 #define Node_PostNotify(x,y) Node_Notify(x,y)
606 #endif
607 NODE_DLL void Node_AddNotify(node*, dataid Id, notifyproc Func, void* Refered);
608 NODE_DLL void Node_AddNotify_Update(node*, dataid Id, notifyproc Func, void* Refered);
609 NODE_DLL void Node_RemoveNotify(node*, dataid Id, notifyproc Func, void* Refered);
610 
611 NODE_DLL size_t Node_MaxDataSize(node*, dataid Id, dataflags Flags, int QueryType);
612 NODE_DLL bool_t Node_EqData(node*, dataid Id, dataflags Flags, const void* a, const void* b);
613 NODE_DLL size_t Node_DataSize(node*, dataid Id, datatype Type, const void* Data, int QueryType);
614 NODE_DLL void Node_RemoveData(node*, dataid Id, datatype Type);
615 NODE_DLL void* Node_AddData(node*, dataid Id, datatype Type, const void* Data);
616 NODE_DLL void* Node_GetData(const node*, dataid Id, datatype Type);
617 NODE_DLL err_t Node_ReadData(node* p, dataid Id, datatype Type, void* Data, size_t Size); /// fills with 0 if the dynamic data doesn't exist
618 NODE_DLL const tchar_t* Node_GetDataStr(const node*, dataid Id);
619 NODE_DLL datetime_t Node_GetDataDatetime(const node*, dataid Id);
620 
621 // functions which should be exported in node DLLs
622 
623 DLLEXPORT err_t DLLRegister(nodemodule*);
624 DLLEXPORT void DLLUnRegister(nodemodule*);
625 DLLEXPORT void DLLTest(void);
626 DLLEXPORT void DLLTest2(void);
627 
628 NODE_DLL bool_t Node_IsPartOf(const void*, fourcc_t PartOfClass);
629 NODE_DLL err_t Node_Toggle(void* Node,dataid Id);
630 NODE_DLL void Node_Copy(node* Dst,node* Src,array* Dup);
631 
632 typedef struct nodedup
633 {
634     node* Orig;
635     node* Dup;
636 
637 } nodedup;
638 
639 void NodeDup_Replace(array* Dup, node** Ptr);
640 
641 #ifdef CONFIG_DEBUGCHECKS
642 #define VMT_FUNC(p,class_vmt) (assert((const void*)(p)!=NULL),(class_vmt*)((node*)(p))->VMT)
643 #else
644 #define VMT_FUNC(p,class_vmt) ((class_vmt*)((node*)(p))->VMT)
645 #endif
646 
647 #define Node_Context(p) (VMT_FUNC(p,node_vmt)->Context)
648 #define Node_ClassId(p) (VMT_FUNC(p,node_vmt)->ClassId)
649 
650 NODE_DLL const void* Node_InheritedVMT(node* p,fourcc_t ClassId);
651 
652 #define INHERITED(p,class_vmt,classid) ((const class_vmt*)Node_InheritedVMT((node*)(p),classid))
653 
654 void* NodeHeap_Alloc(anynode*, size_t Size);
655 void NodeHeap_Free(anynode*, void* Ptr, size_t Size);
656 
657 typedef	int (*memcollect)(void* Cookie, int Level);
658 
659 // collect levels
660 
661 #define COLLECT_UNUSED	        0
662 #define COLLECT_SOFT		    100
663 #define COLLECT_HARD		    200
664 
665 #define COLLECT_FOUND           -1 // return value when memory was collected on that level
666 
667 NODE_DLL bool_t NodeHibernate(anynode*); //TODO: rename
668 NODE_DLL void Mem_AddCollector(anynode*, memcollect Func, void* Cookie);
669 NODE_DLL void Mem_RemoveCollector(anynode*, memcollect Func, void* Cookie);
670 
671 #endif
672