Цитировать#include "klist.h"
#include "kiter.h"
int main(KVOID)
{
KLIST* list = klist();
/* ... */
/* Заполнение списка. */
/* ... */
KITER iter;
kiter(&iter, (KOBJ*)list);
/* Печатаем каждое число. */
while(kiter_hasmore(&iter))
{
KANY v;
kiter_next(&iter, &v);
wprintf(L"%d ", kunboxi(&v));
}
return 0;
}
ЦитироватьKLIST* list = klist();Создаём тестовый список. Главное условие для существования любого объекта в моём фреймворке - это наличие m_refcnt в первых четырёх байтах (но оно в контексте темы неважно), а в последующих четырёх байтах - ссылка на функцию-обработчик. Эта функция обрабатывает сообщения, посылаемые объекту.
ЦитироватьKVOID klist_proc(KOBJ* self, KANY* res, KMSG msg, KARGLIST args);1-ый аргумент - ссылка на себя (любой объект приводим к KOBJ* через type-punning, ибо у каждого объекта первым полем стоит KOBJ m_base. Именно структура KOBJ располагает счётчиком ссылок и ссылкой на функцию-обработчик).
static KVOID klist_proc(KOBJ* self, KANY* res, KMSG msg, KARGLIST args)
{
KUINT n;
switch(msg)
{
case KOBJ_DEL:
klist_clr((KLIST*)self);
break;
case KITER_HASMORE:
{
n = knextarg(args, KUINT);
kboxb(res, n < ((KLIST*)self)->r_cnt);
}
break;
case KITER_NEXT:
{
n = knextarg(args, KUINT);
KANY* spec = knextarg(args, KANY*);
KLIST_ITEM* li;
if(kisnone(spec))
{
li = ((KLIST*)self)->m_fst;
kboxptr(spec, (KPTR)li);
memcpy(res, &li->val, sizeof(KANY));
}
else
{
li = ((KLIST_ITEM*)kunboxptr(spec))->next;
kboxptr(spec, (KPTR)li);
memcpy(res, &li->val, sizeof(KANY));
}
}
break;
default:
kobj_defproc(self, res, msg, args);
}
}
ЦитироватьKVOID ksend(KOBJ* o, KANY* res, KMSG msg, ...)
{
va_list ap;
va_start(ap, msg);
o->m_proc(o, res, msg, ap);
va_end(ap);
}
ЦитироватьKWRITER* wr = kwriter((KOBJ*)kfile(kstr(L"hello.txt")));
ЦитироватьKWRITER* wr = kwriter(kstdout());
Цитироватьkwriter_writestr(wr, kstr(L"some text"));
ЦитироватьKVOID kwriter_writestr(KWRITER* me, KSTR* val)Она просто посылает сообщение. А какому объекту и какого типа этот объект - нам без разницы, лишь бы понимал сообщение. Оно там само как-то решится
{
ksend(me->m_wrpd, 0, KSTREAM_WRITESTR, val);
}
ЦитироватьKBOOL kiter_hasmore(KITER* me)То есть мы можем применять этот итератор к объекту абсолютно любого нового класса, лишь бы этот объект понимал сообщения KITER_HASMORE и KITER_NEXT (всего два!). Никаких перемудрённых деревьев наследования и шаблонов, ничего.
{
KANY r;
ksend(me->m_iterd, &r, KITER_HASMORE, me->r_cur, &me->m_spec);
return kunboxb(&r);
}
KVOID kiter_next(KITER* me, KANY* res)
{
ksend(me->m_iterd, res, KITER_NEXT, me->r_cur, &me->m_spec);
/* Update index. */
me->r_cur++;
}
Страница создана за 0.078 сек. Запросов: 21.