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)
54 #define __changeling_morph(parent, chlg, name, struct_name, field) \
56 changeling_init(parent, &(chlg), chlg_##struct_name, name); \
60 #define __morph_type_of(chlg, struct_name, field) \
61 ((chlg)->ident == chlg_##struct_name)
63 #define __changeling_cast(chlg, struct_name, field) \
64 container_of(chlg, struct struct_name, field)
66 #define __changeling_try_reveal(chlg, struct_name, field) \
68 struct struct_name* __r = NULL; \
69 if (__changeling_of(chlg, struct_name, field)) \
70 __r = __changeling_cast(chlg, struct_name, field); \
74 #define __changeling_reveal(chlg, struct_name, field) \
76 struct struct_name* __r; \
77 __r = __changeling_try_reveal(chlg, struct_name, field); \
81 #define __changeling_of(chlg, struct_name, field) \
82 (chlg && (chlg)->sig == CHLG_ID \
83 && __morph_type_of(chlg, struct_name, field))
86 #define changeling_morph(parent, chlg, name, morpher) \
87 __changeling_morph(parent, chlg, name, morpher)
90 #define changeling_morph_anon(parent, chlg, morpher) \
91 __changeling_morph(parent, chlg, NULL, morpher)
94 #define is_changeling(maybe_chlg) \
95 ((maybe_chlg) && morphed_ptr(maybe_chlg)->sig == CHLG_ID)
98 #define morph_type_of(chlg, morpher) \
99 __morph_type_of(chlg, morpher)
101 #define changeling_of(chlg, morpher) \
102 __changeling_of(chlg, morpher)
104 #define changeling_try_reveal(chlg, morpher) \
105 __changeling_try_reveal(chlg, morpher)
107 #define changeling_reveal(chlg, morpher) \
108 __changeling_reveal(chlg, morpher)
110 #define changeling_for_each(pos, n, parent) \
111 llist_for_each(pos, n, &(parent)->subs, sibs)
113 static inline morph_t*
114 changeling_ref(morph_t* chlg)
116 return ({ chlg->ref++; chlg; });
119 static inline morph_t*
120 changeling_unref(morph_t* chlg)
122 assert(chlg->ref > 0);
123 return ({ chlg->ref--; chlg; });
127 changeling_detach(morph_t* obj)
129 if (llist_empty(&obj->sibs)) {
133 changeling_unref(obj);
134 llist_delete(&obj->sibs);
137 static inline morph_t*
138 changeling_attach(morph_t* parent, morph_t* obj)
140 changeling_detach(obj);
142 llist_append(&parent->subs, &obj->sibs);
143 obj->parent = parent;
145 return changeling_ref(obj);
149 changeling_isolate(morph_t* obj)
151 changeling_detach(obj);
152 assert(obj->ref == 0);
156 changeling_init(morph_t* parent, morph_t* chlg,
157 unsigned int id, const char* name);
160 changeling_spawn(morph_t* parent, const char* name);
163 changeling_find(morph_t* parent, struct hstr* str);
166 changeling_get_at(morph_t* parent, int index);
169 changeling_setname(morph_t* chlg, const char* name);
171 #endif /* __LUNAIX_CHANGELING_H */