SimpleDataType

説明

SimpleDataTypeクラスは、すべてのFlexSimオブジェクトの中心となります。どの種類でもオブジェクトデータを持つノードは、最終的にはSimpleDataTypeのインスタンスに関連付けられます。これは、CouplingDataTypeの親クラスでもあります。

SimpleDataTypeオブジェクトは、ツリーの単一のノードとして、複数の変数を保持できます。ただし、FlexSimイベント(停止、リセット、開始など)や、クリックなどのユーザーイベントのいずれにも反応しません。このため、必要なメモリはごくわずかです。このクラスは一般に、より大きなオブジェクトの一部として、ツリーに保存できるデータを保持するため使用されます。

ツリーノードホルダー

SimpleDataTypeで定義されるメンバー変数はholderのみで、このオブジェクトを参照するツリー内ノードへのポインターです。すべての子クラスにより、この目的で使用されます。

直接の子クラス

クラス 説明
ObjectDataType FlexsimObjectの親(すべてのライブラリオブジェクトのコア)
CouplingDataType ノードからノードポインターへの機能を提供します。
FlexSimEvent FlexSimが使用できるイベントリストのイベントのベースクラス。

実装

仮想メソッド

メソッド 説明
void bind() クラスの変数をバインドして、FlexSim内で可視となり、保存できるようにします(必須)。
void bindEvents() クラスのイベントをバインドします。詳細については、「バインド済みイベント」を参照してください。
void bindStatistics() クラスの統計をバインドします。詳細については、「バインドされた統計」を参照してください。
const char* getClassFactory() クラス名をFlexSimに返し、オブジェクトのインスタンスを正しく作成できるようにします(必須)
char* toString(int verbose) FlexSim内で表示される文字列を返します(オプション)。

bind()

bind()メソッドは、さまざまな時点で呼び出されます。このメソッドの動作は、現在のバインドモードにより異なります。bind()は、FlexSimで必要な動作に応じて、各種のバインドモードで起動されます。正しいbind()メソッドを実装するために必須ではありませんが、bind()メソッド内でgetBindMode()を使用して、バインドモードを明示的に取得できます。次のバインドモードが存在します。

  • SDT_BIND_ON_LOAD - ノードの状態がツリーからロードされたとき(モデルのロード、DLLの再接続など)。
  • SDT_BIND_ON_SAVE - ノードがツリーに保存されたとき(モデルの保存、DLLの切断など)。
  • SDT_BIND_ON_CREATE - SDTの新しいインスタンスがnodeaddsimpledata()で作成されたとき(FlexScriptでは使用できません)。
  • SDT_BIND_ON_DISPLAY - ツリーにノードが表示されたとき。
  • SDT_BIND_SET_VALUE - アプリケーションコマンドsetsdtvalueの一部として、flexscriptによりクラスメンバーの値を設定できます。
  • SDT_BIND_GET_VALUE - アプリケーションコマンドgetsdtvalueの一部として、flexscriptによりクラスメンバーの値を設定できます。

保存/ロード - ノードが保存されるとき、bind()はオブジェクトの各変数についてサブノードを作成し、結果としてでき上がる構造を保存します。ノードがロードされたとき、bind()は保存されている構造から値を取得し、オブジェクトに格納します。ロードプロセスの別の部分で、構造ノードが削除されます。

この動作を、次の図に示します。この動作に関係するDotクラスは、SimpleDataTypeクラスを拡張したものです。Dotクラスには変数x、y、z、widthがあります。変数x、y、zは「継続的な」サブノードとしてバインドされていることに注意してください。これは、「x」という名前のノードはロードフェーズの後もサブノードとして継続することを意味します。また、継続的なサブノードはクラスメンバーの値に「バインド」され、ノードの値を変更すると、クラスメンバーの値も自動的に変更されます。

Dotクラスのコードは、このドキュメントの「例」セクションにあります。Dotのインスタンスがツリー内でどのように表示されるかを、次の図に示します。すべての値が表示され、xはサブノードであることに注意してください。

この図は、同じオブジェクトの保存される構造を示しています。以前はノードでなかった各変数が、sdt::attributetree内のノードになっています。

ノードがロードされるとき、オブジェクトのサブノードから値が取得され、オブジェクトの再作成に使用されます。これによって、オブジェクトの状態をいつでも保存できます。

nodeaddsimpledata() - モジュールのソースコード内で利用可能な関数です。通常は次の形式で呼び出されます。

nodeaddsimpledata(someTreenode, new SimpleDataTypeDerivative, 1)

このコードは、ツリーノードのデータポインターを、SimpleDataTypeDerivativeの新しいインスタンスに設定します。3番目のパラメータは1または0です。1なら、FlexSimはbind()をSDT_BIND_ON_CREATEモードで呼び出します。このモードでは、必要な継続的ノードがサブノード(Dotの例にあるxノードのように)としてアサートされることが確認されます。SDTクラスで継続的サブノードを使用しない場合、作成時にバインドする必要はありません。

表示 - SimpleDataType::toString()のデフォルト実装はbind()メソッドを呼び出し、ツリーに表示する値が文字列として返されます。toString()メソッドの詳細については、後で説明します。

getsdtvalue( theSDTNode, "memberName") / setsdtvalue( theSDTNode, "memberName", value ) - これらのコマンドは、bind()メソッドをそれぞれSDT_BIND_MODE_GET_VALUEとSDT_BIND_MODE_SET_VALUEのバインドモードで呼び出します。その後で、bind()メソッドでバインドする各メンバーは、メンバーの名前が目的の名前と一致しているかどうかを確認し、一致するならそのメンバーの値を取得/設定します。これらの関数は元に戻すに対応しているため、元の戻すのコンテキスト内で呼び出すと、変更は元に戻すレコードの一部となり、ユーザーが元に戻すを選択すると元に戻されることにも注意してください(変更を元に戻せるようにするには、dll内から直接SimpleDataType::setValue()メソッドを使用できます)。 

バージョン7のベータ版をまだ使用している場合、これらの関数はアプリケーションコマンドとしてのみ利用可能なため、FlexSimに問い合わせてください。

変数のバインド

SimpleDataTypeを継承するクラスは、bind()関数を使用して自分のメンバー変数をバインドする必要があります。これを行わないと、FlexSimの保存時に変数の値が保存されません。変数をバインドする方法は、次の表に示すようにタイプにより異なります。

バインド関数 データタイプ
bindDouble(double varName, int asSubNode) double bindDouble(x, 1) - double xをクラスのサブノードとしてバインドします。
bindNumber(Type varName) float、int、その他すべての数値プリミティブ bindNumber(y) - 数値プリミティブyをクラスにバインドします。
bindSubNode(treenode varName, int dataType) treenode bindSubNode(myTreenode, 0) - データなしでサブノードをバインドします。
bindVariant(Variant varName) Variant bindVariant(myVariant) - バリアントをバインドします。
bindNodePtr(treenode varName) treenode bindNodePtr(myTreenode)
bindNodeRef(NodeRef varName, int asSubNode) NodeRef bindNodeRef(myNodeRef)
bindObjPtr(SimpleDataType* varName) SimpleDataType* bindObjPtr(myObjPtr)
bindObjRef(ObjRef varName, int asSubNode) ObjRef bindObjRef(myObjRef)
bindString(std::string varName) std::string bindString(myStr)
bindByteBlock(ByteBlock varName, int asSubNode) ByteBlock bindByteBlock(bb, 1) - ByteBlockをサブノードとしてバインドします。ツリーでは、これはテキストデータを持つノードです。
bindStlContainer(std::container varName vector、stack、deque(std) bindStlContainer(myVectorOfDoubles)
bindStlSet(std::set varName) set、multiset、unordered_set(std) bindStlSet(mySet)
bindStlMap(std::map varName) map、multimap、unordered_map(std) bindStlMap(myMap)
bindCallback(funcName, ClassType) funcNameはバインドする関数の名前です。ClassTypeは、現在のクラスのクラス名です。 bindCallback(functionName, MyClass)

注:STLコンテナを処理するbind()関数では、コンテナがプリミティブタイプで構成されている必要があります。

コールバックのバインド

カスタムのSimpleDataTypeで関数を利用可能にすることが必要な場合があります。次に示すようなクラスを作成した場合、FlexScript function_s(talkerNode, "sayHello")を使用して、そのオブジェクトのsayHello関数を呼び出すことができます。

class Talker : public SimpleDataType
	{
	public:
		void sayHello() { pt("hello"); pr(); }
		Variant sayHello(FLEXSIMINTERFACE) { sayHello(); }
		virtual void bind() override { SimpleDataType::bind(); bindCallback(sayHello, Talker); } 
	};

getClassFactory()

このメソッドはSimpleDataTypeの仮想メンバーで、ツリーを保存するとき、そのクラスが何なのかをFlexSimに正しく通知するため、サブクラスに実装する必要があります。これによりFlexSimは、後でツリーをロードするときクラスファクトリーを読み取り、createsdtderivative()への正しい呼び出しを行って、クラスのインスタンスを正しく作成できます。

toString()

toString()メソッドは、FlexSimのツリーウィンドウに表示される文字列を返します。デフォルトではbind()関数呼び出しの結果の文字列が返されますが、この関数を上書きし、好きな形式のデータを返すことができます。

toString()は、2つの場合に対応する必要があります。最初は、ノードが選択されておらず、表示されているときです。デフォルトの実装では、1行の文字列が返されます。もう1つはノードが選択され、ノードに完全な表示エリアが与えられているときです。この場合、デフォルト実装では各変数とその値を別々の行で表示します。

どの文字列を返すべきかどうかを判定するには、「verbose」パラメータを使用します。1なら、完全なビューの文字列を返します。0なら、1行の文字列を返します。

基本的な例として、Dotクラスを使用します。位置とサイズ以外の情報は必要ありません。Dotクラスのヘッダーファイルは次のようになります。

#pragma once
	#include "FlexsimDefs.h"

	class Dot : public SimpleDataType
	{
	public:
		double x, y, z;
		float width;
		Dot() : x(0), y(0), z(0), width(0) {}
		Dot(double x, double y, double z, float w)
			: x(x), y(y), z(z), width(w) {}

		virtual const char* getClassFactory() override { return "ModuleName::Dot"; }
		virtual void bind() override {
			SimpleDataType::bind();

			bindDouble(x, 1);
			bindDouble(y, 1);
			bindDouble(z, 1);
			bindNumber(width);
		}
	};

下の図は、ツリー内のDotのインスタンスがどのように見えるかを示しています。変数x、y、zが実際にはサブノードであることに注意してください。これは、これらの変数のバインド方法によるものです。widthはテキストのみで一覧表示されます。

この例の作成方法

  1. このドキュメントを読んで、DLLモジュールを作成します。
  2. DLLプロジェクトに、Dot.hというヘッダーを追加します。
  3. 上に示したDotクラスをDot.hにコピーします。
  4. "ModuleName::Dot"を、モジュール名に合わせて変更します。
  5. モジュールのメイン.cppファイルで、createsdtderivative(char* classname)に次の行を追加します。
    if (strcmp(classname, "Dot") == 0)
    		return new Dot();
  6. FlexSimが実行中なら、すべてのDLLの接続を解除します。
  7. モジュールのDLLを構築します。
  8. FlexSimを開始するか、DLLを再接続します。
  9. 注:次の手順は、Dotのインスタンスを手動で作成するための回避策です。SimpleDataTypeオブジェクトは普通はnodeaddsimpledata()を使用して動的に作成されるため、通常はこの手順は使用されません。これらの最後の手順は、通常のプロジェクトでは必要ありません。
  10. ツリーのどこかに空白のノードを作成します。
  11. そのノードに名前とサブノードを指定します。
  12. サブノードに「sdt::attributetree」という名前を付けます。
  13. サブノードに「[moduleName]::Dot」というテキストデータを与えます。
  14. ノードをso()として割り当てます。
  15. スクリプトとして「nodeadddata(so(), DATATYPE_SIMPLE);」コマンドを実行します。
    これで、ノードがSimpleDataTypeオブジェクトになります。
  16. 「Ctrl-c」を使用してノードをコピーします。
  17. 「Ctrl-v」を使用して別の空白ノードに貼り付けます。これで、Dotクラスのインスタンスが作成されます。
  18. 貼り付けられたノードにサブノードを追加します。
  19. 再度コピーします。これで、サブノードとしてバインドされたデータが表示されます。