モジュールクラスの例

概要

SnowProcessorは、モジュールに追加可能なクラスの例です。このクラスはProcessorクラスの拡張で、onDraw()メソッドが周囲のボリュームに含まれる下降する雪片を描画するように変更されています。ユーザーは、雪の効果速度を調整できます。すべての雪片の正確な位置は、ツリーの一部として保存されます。

この例は実用的というより面白いという意味合いが強いものですが、いくつかの主要なモジュールの概念が示されています。

準備

この例を作成する前に、「FlexSimのモジュール開発」を必ず読んでください。ここには、動作モジュールを作成する方法が示されています。この例を使用するには、動作モジュールが必要です。動作モジュールを用意してから、次のステップに従います。

  1. Snowflake.hファイルを追加します。
    1. Visual Studioでソリューションエクスプローラーを開きます。
    2. [ヘッダーファイル]フィルタを右クリックします。
    3. [追加] > [新しい項目...]を選択します。
    4. アイテムのリストから、追加するヘッダーファイルを選択します。
    5. 名前]フィールドに「Snowflake.h」と入力します。
    6. 追加]ボタンをクリックします。
    7. Snowflake.hのテキストを新しいファイルにコピーします。
    8. [ModuleName](getClassFactory()内)を、使用するモジュールの名前に置き換えます。
  2. Snowflake.cppファイルを追加します。
    1. Visual Studioでソリューションエクスプローラーを開きます。
    2. [ソースファイル]フィルタを右クリックします。
    3. [追加] > [新しい項目...]を選択します。
    4. アイテムのリストから、追加するC++ファイルを選択します。
    5. 名前]フィールドに「Snowflake.cpp」と入力します。
    6. 追加]ボタンをクリックします。
    7. Snowflake.cppのテキストを新しいファイルにコピーします。
  3. SnowProcessor.hファイルを追加します。

    Snowflake.hを追加する手順に従いますが、ファイル名に「SnowProcessor.h」を使用し、ソースコードとしてSnowProcessor.hを使用します。また、このファイルのテキストを置き換える必要はありません。

  4. SnowProcessor.cppファイルを追加します。

    Snowflake.cppを追加する手順に従いますが、ファイル名に「SnowProcessor.cpp」を使用し、ソースコードとしてSnowProcessor.cppを使用します。

  5. SnowProcessorクラスを登録します。
    1. モジュールのメインcppファイル(名前はmodule.cpp)を開きます。
    2. 必ず#include "SnowProcessor.h"を含めます。
    3. このコードを、createodtderivativecreatesdtderivativeではありません)関数に含めます(returnステートメントの前)。
      if (strcmp(classname, "SnowProcessor") == 0)
      			return new SnowProcessor();
  6. Snowflakeクラスを登録します。
    1. モジュールのメインcppファイル(名前はmodule.cpp)を開きます。
    2. このコードを、createsdtderivative関数に含めます(returnステートメントの前)。
      if (strcmp(classname, "Snowflake") == 0)
      			return new Snowflake();
  7. モジュールを構築し、FlexSimを開きます(または、DLLを再ロードします)。
  8. MAIN:/project/library/fixedresourcesツリーで、Processorノードを新しいノードにコピーします。
  9. 新しいノードを、追加ノードとしてモジュールに追加します。
  10. ノードの名前を「SnowProcessor」に変更します。
  11. 「classes」属性のサブノードをProcessorから[moduleName]::SnowProcessorに変更します。
  12. 「superclasses」属性のサブノードをFixedResourceからProcessorに変更します。
  13. 次の属性ノードの内容をクリアします。
    • variables
    • stats
    • behavior
  14. 次のノードを、variables属性に追加します。
    1. 「rate」という名前の数値データのノード、値0.5
    2. 「flakeCount」という数値ノード、値100
  15. 次のノードを、stats属性に追加します。
    1. 「lastFallTime」という名前の数値データのノード、値0
    2. 「flakes」という名前の、データなしのノード
  16. カスタムのツールバーボタンを使用して、デフォルトを保存します。
  17. SnowProcessorをモデルにドラッグしてドロップします。

SnowProcessorが最初に作成されるときには雪片は存在しません。リセットを押すと、プロセッサの上部に雪片が表示されます。雪片の落下を見るには、モデルを実行します(モデルを実行するため、他のオブジェクトの追加が必要なことがあります)。

シンプルデータタイプクラスを拡張する

Snowflakeクラスは、SimpleDataTypeクラスを拡張したものです。SimpleDataTypeクラスは、FlexSimのツリーで使用できる最も単純なオブジェクトです。これは単純なオブジェクトを表す、またはオブジェクトが必要だが、通常のFlexSimオブジェクトのオーバーヘッドすべてが必要ではない場合に理想的です。たとえば、TrackedVariableオブジェクトはSimpleDataTypeクラスを拡張したものです。

Snowflakeクラスに格納されるメンバー変数は比較的少ないため、SimpleDataTypeで表現できます。

bind()

SimpleDataTypeオブジェクトをツリーに格納するには、bind()メソッドを実装し、実装の一部として親のbind()を呼び出す必要があります。

Snowflakeクラスは6つのdoubleをバインドします。bindDouble()関数の2番目のパラメータは、このクラスが値をサブノードとして格納することを示します。通常、変数をバインドする必要がある場合は、変数がサブノードとしてバインドされることを確認する必要があります。

一般に、メンバー変数をサブノードとバインドします。ただし、オブジェクトの状態を値なしで保存およびロードできる場合、バインドする必要はありません。

作成する各SimpleDataTypeまたはCouplingDataTypeクラスが正しくロードされるよう、createsdtderivativeに登録する必要があります。

NodeListArrayを使用する

NodeListArrayは、FlexSimでオブジェクトのリストを管理するため便利な方法です。SnowProcessorは、NodeListArrayを使用してSnowflakeオブジェクトのリストを格納します。NodeListArrayは、ツリーノードと同様にバインドできます。サブノードのオブジェクトストアについては、std::vector-likeメソッドと0ベースのインデックスアクセスを使用できます。NodeListArraysの他のタイプについては、datatypes.hで「NodeListArray」を検索してください。

Meshを使用する

Meshクラスでは、グラフィック上の目的で幾何的なメッシュを作成できます。SnowProcessorは単一のメッシュを使用して、各Snowflakeオブジェクトを描画できます。メッシュはバインドされないことに注意してください。その代わりに、SnowProcessorはブール値のメンバー変数(コンストラクト時の値はfalse)を使用して、メッシュが構築済みかどうかを示します。一般に、描画が必要になるごとにメッシュを構築すべきではありません。それぞれのSnowProcessオブジェクトはメッシュを必要なときのみ、1回しか構築しません。メッシュをバインドすることは可能ですが、多くのFlexSimオブジェクトはここに記載しているパターンを使用します。

ライブラリオブジェクトを拡張する

通常のライブラリオブジェクトを拡張できます。SnowProcessorの機能は通常のProcessorと同じですが、FlexSimオブジェクトの拡張についていくつかの重要なポイントが示されています。

bindVariables()

SimpleDataTypeのbind()メソッドと同様に、bindVariables()を使用して、ツリー内のノードをオブジェクトの変数にバインドできます。また、親クラスのbindVariables()を呼び出す必要があります。ただし、bindDouble()、bindObjRef、またはいずれかのタイプ付きのbind関数は使用できません。その代わりに、変数はbindVariable()を使用してバインドされます。

bindStateVariable()も使用できます。この2番目の関数は最初のものと同じですが、この方法でバインドされた変数はオブジェクトのvariablesノードではなく、statsノードに配置される点が異なります。この場合、variablesノードを入力または構成値に使用できます。他の状態データはstatsに保存できます。

bindVariables()の詳細については、FlexsimObjectクラスを参照してください。