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