1 #ifndef __LUNAIX_CHANGELING_H
2 #define __LUNAIX_CHANGELING_H
4 #include <lunaix/types.h>
5 #include <lunaix/ds/llist.h>
6 #include <lunaix/spike.h>
7 #include <lunaix/ds/hstr.h>
9 #define CHLG_ID (unsigned short)0x4c43
11 #define morphable(struct_name) chlg_##struct_name
12 #define __morpher_id(struct_name, field) morphable(struct_name)
13 #define morpher_id(morpher) __morpher_id(morpher)
15 enum changeling_idents
18 #include <listings/changeling.lst>
22 * changeling - a proud changeling of her majesty :)
23 * changeling reginae superbum
42 struct changeling *parent;
43 struct llist_header sibs;
44 struct llist_header subs;
48 typedef struct changeling morph_t;
50 #define morphable_attrs(struct_name, field) struct_name, field
51 #define morphed_ptr(ptr_like) ((morph_t*)__ptr(ptr_like))
52 #define morpher_uid(mobj) ((mobj)->uid)
53 #define morpher_name(mobj) ((mobj)->name.value)
55 #define __changeling_morph(parent, chlg, name, struct_name, field) \
57 changeling_init(parent, &(chlg), chlg_##struct_name, name); \
61 #define __morph_type_of(chlg, struct_name, field) \
62 ((chlg)->ident == chlg_##struct_name)
64 #define __changeling_cast(chlg, struct_name, field) \
65 container_of(chlg, struct struct_name, field)
67 #define __changeling_try_reveal(chlg, struct_name, field) \
69 struct struct_name* __r = NULL; \
70 if (__changeling_of(chlg, struct_name, field)) \
71 __r = __changeling_cast(chlg, struct_name, field); \
75 #define __changeling_reveal(chlg, struct_name, field) \
77 struct struct_name* __r; \
78 __r = __changeling_try_reveal(chlg, struct_name, field); \
82 #define __changeling_of(chlg, struct_name, field) \
83 (chlg && (chlg)->sig == CHLG_ID \
84 && __morph_type_of(chlg, struct_name, field))
87 #define changeling_morph(parent, chlg, name, morpher) \
88 __changeling_morph(parent, chlg, name, morpher)
91 #define changeling_morph_anon(parent, chlg, morpher) \
92 __changeling_morph(parent, chlg, NULL, morpher)
95 #define is_changeling(maybe_chlg) \
96 ((maybe_chlg) && morphed_ptr(maybe_chlg)->sig == CHLG_ID)
99 #define morph_type_of(chlg, morpher) \
100 __morph_type_of(chlg, morpher)
102 #define changeling_of(chlg, morpher) \
103 __changeling_of(chlg, morpher)
105 #define changeling_try_reveal(chlg, morpher) \
106 __changeling_try_reveal(chlg, morpher)
108 #define changeling_reveal(chlg, morpher) \
109 __changeling_reveal(chlg, morpher)
111 #define changeling_for_each(pos, n, parent) \
112 llist_for_each(pos, n, &(parent)->subs, sibs)
114 static inline morph_t*
115 changeling_ref(morph_t* chlg)
117 return ({ chlg->ref++; chlg; });
120 static inline morph_t*
121 changeling_unref(morph_t* chlg)
123 assert(chlg->ref > 0);
124 return ({ chlg->ref--; chlg; });
128 changeling_detach(morph_t* obj)
130 if (llist_empty(&obj->sibs)) {
134 changeling_unref(obj);
135 llist_delete(&obj->sibs);
138 static inline morph_t*
139 changeling_attach(morph_t* parent, morph_t* obj)
141 changeling_detach(obj);
143 llist_append(&parent->subs, &obj->sibs);
144 obj->parent = parent;
146 return changeling_ref(obj);
150 changeling_isolate(morph_t* obj)
152 changeling_detach(obj);
153 assert(obj->ref == 0);
157 changeling_init(morph_t* parent, morph_t* chlg,
158 unsigned int id, const char* name);
161 changeling_spawn(morph_t* parent, const char* name);
164 changeling_find(morph_t* parent, struct hstr* str);
167 changeling_get_at(morph_t* parent, int index);
170 changeling_setname(morph_t* chlg, const char* name);
172 #endif /* __LUNAIX_CHANGELING_H */