シーンタスクの下に別のタスクを走らせる場合、子タスクを用意
その下に孫、ひ孫となっていく場合もあるので
すべてをまとめて処理する方法を考えます。
削除するときは一斉に削除できるとメモリリークも防げそうです。
#include
#include
// 連結リスト
class List{
public :
List* next;
virtual ~List()
{
}
};
// 循環リスト
class RingBuffer{
public :
List header;
public :
// コンストラクタ
RingBuffer()
{
header.next = &header; // 循環させておく
}
~RingBuffer()
{
}
// ノードの追加
void insert( List* item )
{
List* bottom; // 一番最後の部分
List* bottom_prev; // 一番最後の直前
bottom = header.next;
bottom_prev = &header;
if( bottom != NULL ){
while( bottom != &header ){
bottom_prev = bottom;
bottom = bottom->next;
}
}
item->next = bottom;
bottom_prev->next = item;
}
// 連結解除
List* remove( List* item )
{
List* p1 = header.next;
List* p2 = &header;
while( p1 != &header ){
if( p1 == item ){
p2->next = p1->next;
return p1;
}
p2 = p1;
p1 = p1->next;
}
return NULL;
}
List* remove_top()
{
return remove( header.next );
}
// ヒープから確保していない限り使わない
void finalize()
{
for( List* iter = header.next ; iter != &header ; ){
List* rmv = remove( iter );
iter = iter->next;
delete rmv;
}
}
// イテレータ使うときとかに
List* begin()
{
return header.next;
}
};
// タスクオブジェクト
class Task : public List{
public :
RingBuffer child;
public :
virtual void update()
{
}
virtual void draw()
{
}
virtual ~Task()
{
}
};
// 孫タスク
class GrandsonTask : public Task{
public :
void update()
{
printf( "[GrandsonTask] update()\n" );
}
~GrandsonTask()
{
printf( "[GrandsonTask] Destruct\n" );
}
};
// 子タスクその1
class ChildTask : public Task{
public :
ChildTask()
{
child.insert( new GrandsonTask() );
}
void update()
{
printf( "[ChildTask] update()\n" );
}
~ChildTask()
{
printf( "[ChildTask] Destruct\n" );
}
};
// 子タスクその2
class ChildTask2 : public Task{
public :
ChildTask2()
{
}
void update()
{
printf( "[ChildTask2] update()\n" );
}
~ChildTask2()
{
printf( "[ChildTask2] Destruct\n" );
}
};
// 親タスク
class ParentTask : public Task{
public :
ParentTask()
{
child.insert( new ChildTask() );
child.insert( new ChildTask2() );
}
void update()
{
printf( "[ParentTask] update()\n" );
}
~ParentTask()
{
printf( "[ParentTask] Destruct\n" );
}
};
void process_task( RingBuffer* ring ); // タスクへの処理
void finalize_task( RingBuffer* ring ); // タスクの解放
void main()
{
RingBuffer ring;
ring.insert( new ParentTask() );
process_task( &ring );
finalize_task( &ring );
}
// タスクへの処理命令
void process_task( RingBuffer* ring )
{
for( List* list = ring->begin() ; list != &ring->header ; list = list->next ){
Task* task = ( Task* )list;
// 子タスクを持っているなら、そのタスクの処理を行う
if( task->child.header.next != &task->child.header ){
process_task( &task->child );
}
task->update();
task->draw();
}
}
// タスクの削除
void finalize_task( RingBuffer* ring )
{
for( List* list = ring->begin() ; list != &ring->header ; ){
Task* task = ( Task* )ring->remove( list );
if( task->child.header.next != &task->child.header ){
finalize_task( &task->child );
}
list = list->next;
delete task;
}
}
ではでは