こんにちは、開発Gの杉原です。
ゴールデンウィークは結局1、2日と仕事です。
別に強要されたわけではなく、どちらかというとこう、有給の消化率が低い日本人ならではって感じですかね。
休んだところで引きこもってゲームしてそうなので、このほうがずっとか健全という気もします。
(四六時中パソコンの前にいることを健全というかどうかははなはだ疑問ではありますが)
さて、先週より始まったTransferのお話ですが、今週からは各プロセスについて説明していきます。
今回は下図の赤枠の中、搬送の「生成」と「開始」についてです。
上図にもありますように、搬送元がTransferを生成し、搬送先がそれを開始しています。
この構図は非常に重要です。
例えば搬送元が一方的にTransferを生成・開始したとして、搬送先が搬送対象となるワークを受け入れる準備ができていなければどうすることもできません。
しかしこの構図であれば、搬送元がワークを搬送するためにTransferを生成、すなわち「搬送開始の要求」を行い、搬送先は受け入れ態勢が整っていればそのTransferを開始する、ということができます。
さて、このTransferの生成と開始について、それぞれ詳しく見ていきたいと思います。
例えば左図のような、LoadCreatorとコンベアしかないようなモデルがあったとします。
ほとんどのDemo3Dモデルでは、実行する前の状態(Resetされた状態)ではワークが存在しておらず、[Start]ボタンを押すなどして動作を開始させることでどこかしらにワークが現れます。
今回は[Start]ボタンではなく、その右隣にある[Next]ボタンを押してモデルを開始してみます。
[Next]ボタンを押すと、およそ1フレーム分(FPS設定とPCスペックに依存しますが、標準なら0.04秒分)の動作だけして停止します。
すると左図のように、LoadCreatorによって空のパレットが生成されるかと思います。
このように「何もないところからワークを生み出す」ことは「搬送」ではないのでTransferは利用されません。
本題はそのあとです。
この時点では空パレットの所有権はLoadCreatorにあります。そこでLoadCreatorは空パレットの所有権をコンベアへ渡すための搬送を行おうとします。
「搬送を行おうとする」とき、内部的にイベントが発生します。
そのうちの、「搬出しようとする」イベントがOnDispatchOutイベントです。
OnDispatchOutイベント処理では、
・今所有しているワークのうち、どれを搬送するか
・どこに対して搬送するか
の2つを選択し、Transferを生成します。
非常に単純なOnDispatchOutイベント処理が次のコードです。
function OnDispatchOut( visual : Demo3D.Visuals.Visual ) { var txConnector = visual.FindConnector("End"); var rxConnector = txConnector.ConnectedTo; var load = visual.TransferState.Processed[0]; Transfer.Create(txConnector, rxConnector, load); }
[Auto] void OnDispatchOut( Demo3D.Visuals.Visual visual ) { Connector txConnector = visual.FindConnector("End"); Connector rxConnector = txConnector.ConnectedTo; Visual load = visual.TransferState.Processed[0]; Transfer.Create(txConnector, rxConnector, load); }
ここでは「自身のEndコネクタ」から、「その接続先」に対して、「Processedの先頭にあるワーク」を搬送するためのTransferを生成しています。
(※Processedについては後々、「Transferの流れ⑤:業務処理」で説明します)
なお、実際には、Processedに必ずワークがあるわけではないのでそのチェックが必要だったりするので注意してください。
このようにしてTransferが生成されると、搬送先にて「搬入しようとする」イベントが発生します。これがOnDispathInイベントです。
OnDispatchInイベントでは、受け取ったTransferの中から開始したいものを選択し、開始する処理を行います。
非常に単純なOnDispathInイベント処理が次のようになります。
function OnDispatchIn( visual : Demo3D.Visuals.Visual ) { var transfer = visual.TransferState.FirstIncomingWaitingToStart; transfer.Run(); }
[Auto] void OnDispatchIn( Demo3D.Visuals.Visual visual ) { Transfer transfer = visual.TransferState.FirstIncomingWaitingToStart; transfer.Run(); }
ここでは最初に到着したTransferを開始させています。
なお、Transferが1つもない状態でこのイベントが発生することもあるので、実際にはTransferが存在するかの確認などが必要になります。
こうしてTransferが開始され、搬送元と搬送先はそれぞれ受け渡し、受け取りのための準備を始めます。
この先については次回「Tranferの流れ②:前処理」にて説明いたします。
ここまで説明してきましたが、実際のところOnDispatchOutイベント処理、OnDispatchInイベント処理を明示的に定義する必要はあまりないかなと思います。
注釈としても書いたようにワークやTransferの有無のチェックは必要ですし、搬送先が1つずつワークを処理したいのであれば排他制御なんかも必要になり、結構実装は複雑になるかと思います。
明示的に定義しない場合、Demo3Dで定義された標準の処理が実行されるので、素直にそちらを使ったほうがいいと思います。
もし「搬送先を選択する」ためのルールを決めたいのであれば、プロパティにあるTransferStateのDispatchOutRulesを定義したり、TargetSelectorを使ったりすることでも対応できます。
なので、今回のお話は「Transferの仕組みとしてこういうものがある」程度に受け取ってもらえればと思っています。
ちなみに、搬送先を選択する方法については過去に次のような記事を掲載しておりますので、そちらも参考にしてみてください。
◆スクリプトの変更を伴わない方法
荷物の種類別に搬送先を分ける方法 (ソーターを使用する方法)
荷物の種類別に搬送先を分ける方法2 (TargetSelectorを使用する方法)
荷物の種類別に搬送先を分ける方法3 (BasicProcessを使用する方法)
◆スクリプトの変更を伴う方法
ということで次回の【How to Demo3D Scripting】は「Transferの流れ②:前処理」をお送りします。
更新は5/3(木)と言いつつ、実際は5/2(水)には更新されているかもしれません。
コメントをお書きください