ゲームシステム講座3回
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
2011/11/24更新
単純な状態遷移ならば有限状態機械で十分なのですが、
処理の割り込みや処理同士の依存関係などがある場合では有限...
そこで処理自体をオブジェクトとして扱ったほうが何かと便利...
ここでは処理オブジェクトをタスクとして扱っています
今回の全ファイル
zip:&ref(tasksystem.zip);
つまり、タスクシステムとは、処理をオブジェクト単位(タス...
(タスク実行中でも)タスクの追加(+割り込み)・削除・取...
&ref(tasksystem.jpg);
タスクシステム実装にあたり、メモリプールと呼ばれる連続メ...
そこから配置newでメモリ確保するようにしています
理由は通常のnewはメモリ領域の探索とメモリ確保が低速なため
頻繁に必要になる処理オブジェクトの生成処理でシステム全体...
また、処理に必要なメモリ量も自分で把握できるというメリッ...
このように予め確保したメモリ領域を必要に応じて切り割りし...
&ref(allocator.jpg);
タスクには予め優先度の情報を持たせておき
タスクリストにタスクを優先度昇順になるように追加していき...
つまり、優先度の値が小さければ、先に処理されるため、
割り込みしたければ優先度の値を小さくしてタスクリストに追...
優先度が同じであれば追加したタスク順に実行します
&ref(primarylist.jpg);
さらにタスク生成のため、タスクのサイズ分確保できるメモリ...
探索の高速化のためにタスクのメモリ上でのリストの実装もし...
これはカーソルが一周した場合や、割り込みなどによるタスク...
連続メモリが断片化していることがあるので
メモリ上順番の関係にあるタスク間の断片領域を計算し、
新たに追加するタスクを確保できる領域ならば追加、
そうでなければ、次の断片領域に移るという処理を行います
この方法は1バイト単位で空き領域を探索するという手法より...
&ref(taglist.jpg);
連続メモリの容量は予め決められたサイズなので
大量のタスクが追加されてしまうと容量が足りなくなる場合が...
(本来は、そうならないようなサイズを予め算出しておくのが...
その場合、メモリを拡張する必要があります
通常のポインタでタスク間の連結を実装してしまうと
メモリ拡張に伴い、そのまま全タスクをコピーしたとき
ポインタの関係が崩れ、全タスクに対し、タスクリストのつな...
それを防ぐためにメモリプールの先頭アドレスからの相対位置...
タスク同士の連結の情報として持っておきます
実際のアドレスは連続メモリ領域(メモリプール)の先頭アド...
&ref(ptrdiff.jpg);
タスクの削除についてですが
これにはタスクの生成時にタスクIDを振り
そのIDが振られているタスクに関して、削除を行います
この際、SIZE(20){ COLOR(#ffaa00){実行中のタスクのメモリ領...
実行中のタスクは削除しないようにしなければなりません
タスクの差し替えに関しては、指定IDのタスクを削除して新し...
追加済みのタスクの優先度を変更させることもできます
これは指定IDのタスクの優先度を一括で変更し、タスクリスト...
ソート処理自体は負荷が大きい処理なので出来る限り使わない...
(できる限りタスクの追加のときに優先度を調整する)
割り込みの処理同様、必要になることがあるので追加しておき...
今回の実装は
・task.cpp
・task.h
に記述してあります
使い方は以下のようにします
各タスクはTaskクラスを継承して実装します
タスク間の共通データはTaskSystemクラスを継承したTaskSyste...
実際のタスク生成はTaskSystemクラスのAddTaskメンバ関数で行...
この際、デフォルトの優先度より低く設定すると既にタスクリ...
先に実行することができます(割り込み処理)
また、すでに登録したタスクをDeleteTaskメンバ関数を用いる...
タスクの差し替えは、タスクをID指定で差し替えることができ...
main.cpp
#include "task.h"
#include <crtdbg.h>
#include <windows.h>
#include <conio.h>
class InputTask;
class NetworkTask;
class DrawTask;
class Draw3DTask;
class Draw2DTask;
class DrawObjectTask;
// タスクID
enum{
TASKID_INPUT,
TASKID_NETWORK,
TASKID_DRAW,
TASKID_DRAW3D,
TASKID_DRAW2D
};
class TaskSystemEx : public TaskSystem
{
public:
int common; // タスク間共通データ
TaskSystemEx():common(0){}
virtual ~TaskSystemEx(){}
};
// キャストめんどくさいので置き換え
#define m_pTaskSystemEx dynamic_cast<TaskSystemEx*>(m_pT...
class InputTask : public Task
{
public:
virtual void Execute(){
m_pTaskSystemEx->common++;
printf("%d周目 InputTask id = %d\n",m_pTaskSystemEx->c...
m_pTaskSystem->AddTask<NetworkTask>(TASKID_NETWORK);
}
};
class NetworkTask : public Task
{
public:
virtual void Execute(){
printf("%d周目 NetworkTask id = %d\n",m_pTaskSystemEx-...
m_pTaskSystem->AddTask<DrawTask>(TASKID_DRAW);
}
};
class DrawTask : public Task
{
public:
virtual void Execute(){
printf("%d周目 DrawTask id = %d\n",m_pTaskSystemEx->co...
m_pTaskSystem->AddTask<InputTask>(TASKID_INPUT);
// プライオリティでタスクの割り込み(低い順に実行される)
for(int i = 0;i < 10;++i)
m_pTaskSystem->AddTask<Draw2DTask>(TASKID_DRAW2D,(dou...
for(int i = 0;i < 10;++i)
m_pTaskSystem->AddTask<Draw3DTask>(TASKID_DRAW3D,0.2);
// (現在実行中以外の)指定のIDのタスクを全て差し替え
m_pTaskSystem->SwapTask<DrawObjectTask>(TASKID_DRAW3D);
// (現在実行中以外の)全タスクを全て削除
//m_pTaskSystem->DeleteAllTask();
// (現在実行中以外の)指定のIDのタスクの優先度を全て...
m_pTaskSystem->SetTaskPriority(TASKID_DRAW3D,0.3);
// (現在実行中以外の)指定のIDのタスクを全て削除
//m_pTaskSystem->DeleteTask(TASKID_DRAW2D);
}
};
class Draw3DTask : public Task
{
public:
char a[100]; // 適当なデータ
virtual void Execute(){
printf("%d周目 Draw3DTask id = %d\n",m_pTaskSystemEx->...
}
};
class Draw2DTask : public Task
{
public:
char a[120];// 適当なデータ
virtual void Execute(){
printf("%d周目 Draw2DTask id = %d priority = %lf\n",m_...
GetTaskID(),GetPriority());
}
};
class DrawObjectTask : public Task
{
public:
virtual void Execute(){
printf("%d周目 DrawObject id = %d priority = %lf\n",m_...
GetTaskID(),GetPriority());
}
};
int main()
{
#ifdef _DEBUG
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _C...
//_CrtSetBreakAlloc(x);
#endif
TaskSystemEx tasksystem;
tasksystem.Create(1000);
tasksystem.AddTask<InputTask>(TASKID_INPUT);
while(tasksystem.ExecuteTask()){
// 出力が見やすいように0.1秒休む
//Sleep(100);
// キー入力で終了
if(_kbhit())
break;
}
// メモリダンプ
tasksystem.Dump("dump.txt");
return 0;
}
実行結果は次のようになります
&ref(exe.jpg);
追記:デフラグの処理は追加してあるのですが、
断片領域が増えた時の探索にかかるコストとデフラグにかかる...
vote(理解できた(^ω^)[4],なんぞこれーΣ(゚д゚lll)[6],ちょっと...
終了行:
2011/11/24更新
単純な状態遷移ならば有限状態機械で十分なのですが、
処理の割り込みや処理同士の依存関係などがある場合では有限...
そこで処理自体をオブジェクトとして扱ったほうが何かと便利...
ここでは処理オブジェクトをタスクとして扱っています
今回の全ファイル
zip:&ref(tasksystem.zip);
つまり、タスクシステムとは、処理をオブジェクト単位(タス...
(タスク実行中でも)タスクの追加(+割り込み)・削除・取...
&ref(tasksystem.jpg);
タスクシステム実装にあたり、メモリプールと呼ばれる連続メ...
そこから配置newでメモリ確保するようにしています
理由は通常のnewはメモリ領域の探索とメモリ確保が低速なため
頻繁に必要になる処理オブジェクトの生成処理でシステム全体...
また、処理に必要なメモリ量も自分で把握できるというメリッ...
このように予め確保したメモリ領域を必要に応じて切り割りし...
&ref(allocator.jpg);
タスクには予め優先度の情報を持たせておき
タスクリストにタスクを優先度昇順になるように追加していき...
つまり、優先度の値が小さければ、先に処理されるため、
割り込みしたければ優先度の値を小さくしてタスクリストに追...
優先度が同じであれば追加したタスク順に実行します
&ref(primarylist.jpg);
さらにタスク生成のため、タスクのサイズ分確保できるメモリ...
探索の高速化のためにタスクのメモリ上でのリストの実装もし...
これはカーソルが一周した場合や、割り込みなどによるタスク...
連続メモリが断片化していることがあるので
メモリ上順番の関係にあるタスク間の断片領域を計算し、
新たに追加するタスクを確保できる領域ならば追加、
そうでなければ、次の断片領域に移るという処理を行います
この方法は1バイト単位で空き領域を探索するという手法より...
&ref(taglist.jpg);
連続メモリの容量は予め決められたサイズなので
大量のタスクが追加されてしまうと容量が足りなくなる場合が...
(本来は、そうならないようなサイズを予め算出しておくのが...
その場合、メモリを拡張する必要があります
通常のポインタでタスク間の連結を実装してしまうと
メモリ拡張に伴い、そのまま全タスクをコピーしたとき
ポインタの関係が崩れ、全タスクに対し、タスクリストのつな...
それを防ぐためにメモリプールの先頭アドレスからの相対位置...
タスク同士の連結の情報として持っておきます
実際のアドレスは連続メモリ領域(メモリプール)の先頭アド...
&ref(ptrdiff.jpg);
タスクの削除についてですが
これにはタスクの生成時にタスクIDを振り
そのIDが振られているタスクに関して、削除を行います
この際、SIZE(20){ COLOR(#ffaa00){実行中のタスクのメモリ領...
実行中のタスクは削除しないようにしなければなりません
タスクの差し替えに関しては、指定IDのタスクを削除して新し...
追加済みのタスクの優先度を変更させることもできます
これは指定IDのタスクの優先度を一括で変更し、タスクリスト...
ソート処理自体は負荷が大きい処理なので出来る限り使わない...
(できる限りタスクの追加のときに優先度を調整する)
割り込みの処理同様、必要になることがあるので追加しておき...
今回の実装は
・task.cpp
・task.h
に記述してあります
使い方は以下のようにします
各タスクはTaskクラスを継承して実装します
タスク間の共通データはTaskSystemクラスを継承したTaskSyste...
実際のタスク生成はTaskSystemクラスのAddTaskメンバ関数で行...
この際、デフォルトの優先度より低く設定すると既にタスクリ...
先に実行することができます(割り込み処理)
また、すでに登録したタスクをDeleteTaskメンバ関数を用いる...
タスクの差し替えは、タスクをID指定で差し替えることができ...
main.cpp
#include "task.h"
#include <crtdbg.h>
#include <windows.h>
#include <conio.h>
class InputTask;
class NetworkTask;
class DrawTask;
class Draw3DTask;
class Draw2DTask;
class DrawObjectTask;
// タスクID
enum{
TASKID_INPUT,
TASKID_NETWORK,
TASKID_DRAW,
TASKID_DRAW3D,
TASKID_DRAW2D
};
class TaskSystemEx : public TaskSystem
{
public:
int common; // タスク間共通データ
TaskSystemEx():common(0){}
virtual ~TaskSystemEx(){}
};
// キャストめんどくさいので置き換え
#define m_pTaskSystemEx dynamic_cast<TaskSystemEx*>(m_pT...
class InputTask : public Task
{
public:
virtual void Execute(){
m_pTaskSystemEx->common++;
printf("%d周目 InputTask id = %d\n",m_pTaskSystemEx->c...
m_pTaskSystem->AddTask<NetworkTask>(TASKID_NETWORK);
}
};
class NetworkTask : public Task
{
public:
virtual void Execute(){
printf("%d周目 NetworkTask id = %d\n",m_pTaskSystemEx-...
m_pTaskSystem->AddTask<DrawTask>(TASKID_DRAW);
}
};
class DrawTask : public Task
{
public:
virtual void Execute(){
printf("%d周目 DrawTask id = %d\n",m_pTaskSystemEx->co...
m_pTaskSystem->AddTask<InputTask>(TASKID_INPUT);
// プライオリティでタスクの割り込み(低い順に実行される)
for(int i = 0;i < 10;++i)
m_pTaskSystem->AddTask<Draw2DTask>(TASKID_DRAW2D,(dou...
for(int i = 0;i < 10;++i)
m_pTaskSystem->AddTask<Draw3DTask>(TASKID_DRAW3D,0.2);
// (現在実行中以外の)指定のIDのタスクを全て差し替え
m_pTaskSystem->SwapTask<DrawObjectTask>(TASKID_DRAW3D);
// (現在実行中以外の)全タスクを全て削除
//m_pTaskSystem->DeleteAllTask();
// (現在実行中以外の)指定のIDのタスクの優先度を全て...
m_pTaskSystem->SetTaskPriority(TASKID_DRAW3D,0.3);
// (現在実行中以外の)指定のIDのタスクを全て削除
//m_pTaskSystem->DeleteTask(TASKID_DRAW2D);
}
};
class Draw3DTask : public Task
{
public:
char a[100]; // 適当なデータ
virtual void Execute(){
printf("%d周目 Draw3DTask id = %d\n",m_pTaskSystemEx->...
}
};
class Draw2DTask : public Task
{
public:
char a[120];// 適当なデータ
virtual void Execute(){
printf("%d周目 Draw2DTask id = %d priority = %lf\n",m_...
GetTaskID(),GetPriority());
}
};
class DrawObjectTask : public Task
{
public:
virtual void Execute(){
printf("%d周目 DrawObject id = %d priority = %lf\n",m_...
GetTaskID(),GetPriority());
}
};
int main()
{
#ifdef _DEBUG
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _C...
//_CrtSetBreakAlloc(x);
#endif
TaskSystemEx tasksystem;
tasksystem.Create(1000);
tasksystem.AddTask<InputTask>(TASKID_INPUT);
while(tasksystem.ExecuteTask()){
// 出力が見やすいように0.1秒休む
//Sleep(100);
// キー入力で終了
if(_kbhit())
break;
}
// メモリダンプ
tasksystem.Dump("dump.txt");
return 0;
}
実行結果は次のようになります
&ref(exe.jpg);
追記:デフラグの処理は追加してあるのですが、
断片領域が増えた時の探索にかかるコストとデフラグにかかる...
vote(理解できた(^ω^)[4],なんぞこれーΣ(゚д゚lll)[6],ちょっと...
ページ名: