Mirai's Miscellaneous Misadventures
M31 / core / coroutines.c
#include <mimimi/coroutines.h>
#include <mimimi/coroutine-providers.h>
#include <mimimi/compound-behaviors.h>
#include <mimimi/behaviors.h>
#include <mimimi/allocators.h>
struct mimimi_coroutine
{
struct mimimi_allocator *allocator;
struct mimimi_behavior *behavior;
struct mimimi_behavior *compound0;
struct mimimi_behavior *compound;
struct mimimi_behavior *result;
void (*start)(struct mimimi_behavior *behavior, struct mimimi_behavior *compound, void *data);
void *data;
char finished;
};
static void mimimi_coroutine_start(struct mimimi_behavior *behavior, void *data)
{
struct mimimi_coroutine *coroutine = data;
(*coroutine->start)(behavior, coroutine->compound, coroutine->data);
}
static void mimimi_coroutine_finish_behavior(void *data)
{
struct mimimi_coroutine *coroutine = data;
mimimi_compound_remove(coroutine->compound0, coroutine->result);
(*coroutine->behavior->finish)(coroutine->behavior->data);
(*coroutine->compound->finish)(coroutine->compound->data);
mimimi_deallocate(coroutine->allocator, coroutine->result);
mimimi_deallocate(coroutine->allocator, coroutine);
}
static void mimimi_coroutine_finish(void *data)
{
struct mimimi_coroutine *coroutine = data;
coroutine->finished = 1;
if (mimimi_compound_empty(coroutine->compound) != 0)
mimimi_coroutine_finish_behavior(data);
}
static void mimimi_coroutine_behave(void *data)
{
struct mimimi_coroutine *coroutine = data;
if (coroutine->finished == 0)
(*coroutine->behavior->behave)(coroutine->behavior->data);
(*coroutine->compound->behave)(coroutine->compound->data);
if (coroutine->finished != 0)
if (mimimi_compound_empty(coroutine->compound) != 0)
mimimi_coroutine_finish_behavior(data);
}
void mimimi_coroutine(struct mimimi_coroutine_provider *coroutines, struct mimimi_behavior *compound, void (*start)(struct mimimi_behavior *behavior, struct mimimi_behavior *compound, void *data), void *data, struct mimimi_allocator *allocator)
{
struct mimimi_coroutine *coroutine = mimimi_allocate(allocator, sizeof *coroutine);
coroutine->start = start;
coroutine->data = data;
coroutine->allocator = allocator;
coroutine->compound0 = compound;
coroutine->compound = mimimi_compound_behavior(allocator);
coroutine->finished = 0;
struct mimimi_behavior *behavior = (*coroutines->create)(&mimimi_coroutine_start, &mimimi_coroutine_finish, coroutine, coroutines->data);
coroutine->behavior = behavior;
struct mimimi_behavior *result = mimimi_allocate(allocator, sizeof *result);
result->behave = &mimimi_coroutine_behave;
result->finish = &mimimi_coroutine_finish_behavior;
result->data = coroutine;
coroutine->result = result;
mimimi_compound(compound, result);
}