タスクの親子関係

アバター
せんちゃ
記事: 50
登録日時: 15年前
住所: 江別市東野幌町
連絡を取る:

タスクの親子関係

投稿記事 by せんちゃ » 12年前

タスクは基本的にはすべて独立して動かす必要があるため、
シーンタスクの下に別のタスクを走らせる場合、子タスクを用意
その下に孫、ひ孫となっていく場合もあるので
すべてをまとめて処理する方法を考えます。

削除するときは一斉に削除できるとメモリリークも防げそうです。

CODE:

#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;
	}
}
再帰呼び出しでそれっぽいのが作れました。
ではでは
最後に編集したユーザー せんちゃ on 2013年1月04日(金) 17:28 [ 編集 1 回目 ]

コメントはまだありません。