This guide shows how to understand and modify the code of existing HubNet activities and write your own new ones. It assumes you are familiar with running HubNet activities, basic NetLogo code and NetLogo interface elements. For more general information about HubNet see the HubNet Guide.
このガイドはHubNetアクティビティにあるコードの理解と変更、自分自身のコードの書き方の方法を示す。 HubNetアクティビティの実行、NetLogoの基本コード、インターフェース要素に馴染んでいることを前提とする。 HubNetの一般的な情報はHubNet Guideを参照のこと。
Many HubNet activities will share bits of the same code. That is the code that it used to setup the network and the code that is used to receive information from and send information to the clients. If you understand this code you should be able to easily make modifications to existing activities and you should have a good start on writing your own activities. To get you started we have provided a Template model (in HubNet Activities -> Code Examples) that contains the most basic components that will be in the majority of HubNet activities. You should be able to use this activity as a starting point for most projects.
多くのHubNetアクティビティは一部同じコードを共有する。共有コードは、ネットワークの設定やクライアントとの情報送受信などである。このコードを理解すると、既存のアクティビティを簡単に変更できたり、自分自身のアクティビティを書くときのよい練習になる。作成を始めるために、HubNetアクティビティのほとんどの基本的なコンポーネントを含んだテンプレート(HubNet Activities -> Code Examples)が用意されている。ほとんどのプロジェクトでこのアクティビティが使える。
Code Example: Template
コード例: テンプレート(Template HubNet)
To make a NetLogo model into a HubNet activity you must first initialize the network. In most HubNet activities you will use the startup procedure to initialize the network. startup is a special procedure that NetLogo runs automatically when you open any model. That makes it a good place to put code that you want to run once and only once (no matter how many times the user runs the model). For HubNet we put the command that initializes the network in startup because once the network is setup we don't need to do so again. We initialize the system using hubnet-reset, which will ask the user for a session name and open up the HubNet Control Center. Here is the startup procedure in the template model:
NetLogoモデルをHubNetアクティビティへ作り変えるために、まずネットワークを初期化する。ほとんどのHubNetアクティビティでは、ネットワークを初期化するためにstartupプロシージャーを使用する。startupは特殊なプロシージャーで、モデルを開いた時にNetLogoを自動的に実行する。一回だけ実行したいコードを正しい場所に作る。HubNetのために、startupに中にネットワークを初期化するコマンドを置く。ネットワークが初期化されると、再び初期化する必要はない。hubnet-resetを使ってシステムを初期化する。それはセッション名をユーザに尋ね、HubNetコントロールを開く。以下がテンプレートモデルのstartupプロシージャである。
to startup hubnet-reset end
Now that the network is all setup you don't need to worry about calling hubnet-reset again. Take a look at the setup procedure in the template model:
ネットワークがすべて設定されれば、再びhubnet-resetを呼ぶ不必要はない。テンプレートモデルのsetupプロシージャーを見ること。
to setup cp cd clear-output ask turtles [ set step-size 1 hubnet-send user-id "step-size" step-size ] end
For the most part it looks like most other setup procedures, however, you should notice that it does not call clear-all. In this model, and in the great majority of HubNet activities in the Models Library, we have a breed of turtles that represent the currently logged in clients. In this case we've called this breed students. Whenever a client logs in we create a student and record any information we might need later about that client in a turtle variable. Since we don't want to require users to log out and log back in every time we setup the activity we don't want to kill all the turtles, instead, we want to set all the variables back to initial values and notify the clients of any changes we make (more on that later).
ほとんどは多くの他のsetupプロシージャのように見えるが、clear-allを呼び出していないことに注意すること。このモデル、またモデルライブラリの大多数のHubNetアクティビティでは、現在ログインしているクライアントを表すタートルのbreedを持つ。この事例では、breedはstudentsである。クライアントがログインする時にstudentを生成し、タートル変数の中でそのクライアントについて後で必要とする情報を記録する。アクティビティをsetupするたびに、ユーザーにログアウトやログバックを要求したくないので、すべてのタートルをkillせず、代わりに、初期値に戻すようにすべての変数を設定し、変更するものをクライアントに通知する。
During the activity you will be transferring data between the HubNet clients and the server. Most HubNet activities will call a procedure in the go loop that checks for new messages from clients in this case it's called listen clients:
アクティビティの間、HubNetクライアントとサーバ間でデータが転送される。多くのHubNetアクティビティは、goループの中で、listen clientsと呼ばれるこの例のようなクライアントからの新しいメッセージをチェックするプロシージャを呼ぶ。
to listen-clients while [ hubnet-message-waiting? ] [ hubnet-fetch-message ifelse hubnet-enter-message? [ create-new-student ] [ ifelse hubnet-exit-message? [ remove-student ] [ execute-command hubnet-message-tag ] ] ] end
As long as there are messages in the queue this loop fetches each message one at a time. hubnet-fetch-message makes the next message in the queue the current message and sets the reporters hubnet-message-source, hubnet-message-tag, and hubnet-message to the appropriate values. The clients send messages when the users login and logout any time the user manipulates one of the interface elements, that is, pushes a button, moves a slider, clicks in the view, etc. We step through each message and decide what action to take depending on the type of message (enter, exit, or other), the hubnet-message-tag (the name of the interface element), and the hubnet-message-source of the message (the name of the client the message came from).
キューの中にメッセージがあるかぎり、このループは1回に1つのメッセージ取得する。hubnet-fetch-messageは、キューの中の次のメッセージを現在のメッセージとして、レポーター hubnet-message-source, hubnet-message-tag, hubnet-messageを適切な値にセットする。クライアントはユーザーがログイン、ログアウトした時や、ユーザーがボタンを押したり、スライダーを動かしたり、ビューをクリックしたりなど、インターフェース要素のどれかを操作した時にメッセージを送る。それぞれのメッセージを通し、メッセージの型(enter, exit, その他)、hubnet-message-tag (インターフェース要素の名前)、メッセージの hubnet-message-source(メッセージを送ったクライアントの名前)によって何のアクションが取られたのかを決定する。
On an enter message we create a turtle with a user-id that matches the hubnet-message-source which is the name that each user enters upon entering the activity, it is guaranteed to be unique.
入力メッセージで、アクティビティを入力したユーザ名であるhubnet-message-sourceに一致するuser-idを持つタートルを生成する。これは唯一な値を保証する。
to create-new-student create-students 1 [ set user-id hubnet-message-source set label user-id set step-size 1 send-info-to-clients ] end
At this point we set any other client variables to default values and send them to the clients if appropriate. We declared a students-own variable for every interface element on the client that holds state, that is, anything that would be a global variable on the server, sliders, choosers, switches and input boxes. It is important to make sure that these variables stay synchronized with the values visible on the client.
この時点で、デフォルト値を他のクライアント変数にセットし、適切であればそれをクライアントへ送信する。クライアントのすべてのインターフェース要素に対してstudents-own変数を宣言する。それらは、サーバー上のグローバル変数、スライダー、チューザー、スイッチ、入力ボックスなど何かしらの状態を持つ。重要な事は、これらの変数はクライアントに見える値として同期される。
When the clients logout they send an exit message to the server which gives you a chance to clean up any information you have been storing about the client, in this case we merely have to ask the appropriate turtle to die.
クライアントがログアウトする時、サーバーへ退出メッセージを送る。それはクライアントに関して保存していた情報を削除する機会となる。この例では、適切なタートルが「死ぬ」ことを依頼するだけである。
to remove-student ask students with [user-id = hubnet-message-source] [ die ] end
All other messages are interface elements identified by the hubnet-message-tag which is the name that appears in the client interface. Every time an interface element changes a message is sent to the server. Unless you store the state of the values currently displayed in the client interface will not be accessible in other parts of the model. That's why we've declared a students-own variable for every interface element that has a state (sliders, switches, etc). When we receive the message from the client we set the turtle variable to the content of the message:
他のすべてのメッセージは、hubnet-message-tagによって認識されるインターフェース要素であり、クライアントインターフェースの中に表示する名前である。インターフェース要素が変化する度に、メッセージがサーバに送られる。もしクライントインターフェースの中に表示される現在値の状態を保存しなければ、モデルの他の部分でアクセスできなくなる。それは、状態を持つすべてのインターフェース要素(スライダー、スイッチなど)に対し、students-ownの値を宣言した理由である。クライントからメッセージを受信したら、メッセージ内容をタートル変数に設定する。
if hubnet-message-tag = "step-size" [ ask students with [user-id = hubnet-message-source] [ set step-size hubnet-message ] ]
Since buttons don't have any associated data there is generally no associated turtle variable, instead they indicate an action taken by the client, just as with a regular button there is often procedure associated with each button that you call whenever you receive a message indicating the button has been pressed. Though it is certainly not required, the procedure is often a turtle procedure, that is, something that the student turtle associated with the message source can execute:
ボタンはデータを持たないので、通常はタートル変数がない。代わりに、クライントによって起こされるアクションを表す。普通のボタンのように、ボタンが押されたことを示すメッセージを受け取るそれぞれのボタンに関連したプロシージャがある。必ずそれが求められている訳ではないが、プロシージャはタートルプロシージャであることが多く、メッセージ元に関連した学生タートルが実行できるものとなる。
if command = "move left" [ set heading 270 fd 1 ]
As mentioned earlier you can also send values to any interface elements that display information: monitors, sliders, switches, choosers, and input boxes (note that plots and the view are special cases that have their own sections).
先に述べたように、情報を表示するモニターやスライダー、スイッチ、チューザー、入力ボックスなどの任意のインターフェース要素に値を送ることができる(プロットとビューはそれら自身のsectionを持つ特殊なケースであることに注意すること)。
There are two primitives that allow you to send information hubnet-send and hubnet-broadcast. Broadcast sends the information to all the clients; send sends to one client, or a selected group.
hubnet-send と hubnet-broadcastという情報を送ることができる2つのプリミティブがある。ブロードキャストはすべてのクライアントや選ばれたグループに情報を送る。
As suggested earlier, nothing on the client updates automatically. If a value changes on the server, it is your responsibility as the activity author to update monitors on the client.
先に示したように、クライアントの上では何も自動的に更新しない。サーバー上で値が変化したなら、アクティビティオーサーとして自分の責任でクライアント上のモニターを更新する。
For example, say you have a slider on the client called step-size and a monitor called Step Size (note that the names must be different) you might write updating code like this:
例えば、step-sizeというスライダーとStep Sizeというモニターがあれば、次のように更新コードを書く。
if hubnet-message-tag = "step-size" [ ask student with [ user-id = hubnet-message-source ] [ set step-size hubnet-message hubnet-send user-id "Step Size" step-size ] ]
You can send any type of data you want, numbers, strings, lists, lists of lists, lists of strings, however, if the data is not appropriate for the receiving interface element (say, if you were to send a string to a slider) the message will be ignored. Here are a few code examples for different types of data:
任意のデータ型(数値、文字列、リスト、リストのリスト、文字列のリスト)を送信できる。しかしデータが受け取るインターフェース要素に対して不適切であれば(スライダーへ文字列を送るなど)、メッセージは無視される。次に異なるデータ型の例を掲げる。
data type | hubnet-broadcast example | hubnet-send example |
---|---|---|
number | hubnet-broadcast "A" 3.14 | hubnet-send "jimmy" "A" 3.14 |
string | hubnet-broadcast "STR1" "HI THERE" | hubnet-send ["12" "15"] "STR1" "HI THERE" |
list of numbers | hubnet-broadcast "L2" [1 2 3] | hubnet-send hubnet-message-source "L2" [1 2 3] |
matrix of numbers | hubnet-broadcast "[A]" [[1 2] [3 4]] | hubnet-send "susie" "[A]" [[1 2] [3 4]] |
list of strings | hubnet-broadcast "user-names" [["jimmy" "susie"] ["bob" "george"]] | hubnet-send "teacher" "user-names" [["jimmy" "susie"] ["bob" "george"]] |
Study the models in the "HubNet Activities" section of the Models Library to see how these primitives are used in practice in the Code tab. Disease is a good one to start with.
モデルライブラリーにあるハブネットアクティビティの章のモデルで学習ができる。 どのようにコードタブ内でプリミティブが実際に使用されるのかを見ることができる。
Open the HubNet Client Editor, found in the Tools Menu. Add any buttons, sliders, switches, monitors, plots, choosers, or notes that you want just as you would in the interface tab. You'll notice that the information you enter for each of the widgets is slightly different than in the Interface panel. Widgets on the client don't interact with the model in the same way. Instead of a direct link to commands and reporters the widgets send messages back to the server and the model then determines how those messages affect the model. All widgets on the client have a tag which is a name that uniquely identifies the widget. When the server receives a message from that widget the tag is found in hubnet-message-tag
ツールメニューにあるクライアントエディターを開く。インターフェースタブで、任意のボタン、スライダー、スイッチ、モニター、プロット、チューザー、ノートなどを追加する。それぞれのウィジェット(部品)に入力した情報がインターフェースパネルとは少し異なることに気付くだろう。クライアントの部品はモデルと同じようには作用しない。コマンドやレポーターへの直接的なリンクの代わりに、ウィジェットはサーバーへメッセージを返し、モデルはこのメッセージがモデルにどのように影響するかを決定する。クライアント上のすべてのウィジェットは、ユニークにウィジェットを識別するタグ名を持つ。サーバーがウィジェットからのメッセージを受信すると、タグはhubnet-message-tagの中にある。
For example, if you have a button called "move left", a slider called "step-size", a switch called "all-in-one-step?", and a monitor called "Location:", the tags for these interface elements will be as follows:
例えば、move leftというボタン、step-sizeというスライダー、all-in-one-stepというスイッチ、Locationというモニターがあった場合、これらのインターフェース要素のタグは以下のようになる。
interface element | tag |
---|---|
move left | move left |
step-size | step-size |
all-in-one-step? | all-in-one-step? |
Location: | Location: |
Note that you can only have one interface element with a specific name. Having more than one interface element with the same tag in the client interface will result in unpredictable behavior since it is not clear which element you intended to send the information to.
特有の名前のインターフェース要素は一つだけ持てることに注意すること。クライアントインターフェース上で、複数の同一タグのインターフェース要素を持つことは、情報を送付する要素が明確にならないので、予期できない動作を招く。
View mirroring lets views of the world be displayed in clients as well on the server. View mirroring is enabled using a checkbox in the HubNet Control Center.
ビューミラーリングはWorldのビューをサーバーと同じようにクライアントに表示させる。ビューミラーリングはHubNetコントロールセンターのチェックボックスを使うことで可能になる。
When mirroring is enabled, client views update whenever the view on the server does. To avoid excessive network traffic, the view should not update more often than necessary. Therefore we strongly recommend using tick-based updates, rather than continuous updates. See the View Updates section of the Programming Guide for an explanation of the two types of updates.
ミラーリングが有効になると、サーバーが表示更新するとクライアント表示も更新する。過度なネットワークトラフィックを避けるために、表示は必要以上に更新すべきではない。従って、連続更新よりもティックベースの更新を強く推奨する。ふたつのタイプの更新の説明は、プログラミングガイドのビュー更新の章を見ること。
With tick-based updates, updates happen when a tick or display command runs. We recommend using these commands only inside an every block, to limit the frequency of view updates and thus also limit network traffic. For example:
ティックベースの更新を使うと、tick か display コマンドが実行した時に更新が起きる。これらのコマンドは、表示更新の頻度を制限しネットワークトラフィックを抑えるために、 every ブロックの中でのみ使用することを推奨する。例:
every 0.1 [ display ]
If there is no View in the clients or if the Mirror 2D View on Clients checkbox in the HubNet Control Center is not checked, then no view updates are sent to the clients.
クライアントのビューがないか、HubNetコントロールセンターの中のクライアントチェックボックス上でのミラー2D表示がチェックされていないなら、表示更新はクライアントへ送られない。
If the View is included in the client, two messages are sent to the server every time the user clicks in the view. The first message, when the user presses the mouse button, has the tag "View". The second message, sent when the user releases the mouse button, has the tag "Mouse Up". Both messages consist of a two item list of the x and y coordinates. For example, to turn any patch that was clicked on by the client red, you would use the following NetLogo code:
ビューがクライアントに含まれていると、二つのメッセージがビューの中でユーザーがクリックするたびにサーバーに送られる。
if hubnet-message-tag = "View" [ ask patches with [ pxcor = (round item 0 hubnet-message) and pycor = (round item 1 hubnet-message) ] [ set pcolor red ] ]
When view mirroring is enabled, by default clients see the same view the activity leader sees on the server. But you can change this so that each client sees something different, not just a literal "mirror".
表示ミラーリングが有効になっていると、デフォルトでクライアントはアクティビティーリーダーがサーバーで見ているものと同じものが見られる。しかし、文字通りの「ミラー」ではなく、各クライアントが何か違うものを見るように変更ができる。
You can change what a client sees in two distinct ways. We call them "client perspectives" and "client overrides".
二つの別の方法で、クライアントは見るものを変更できる。これを"client perspectives" と "client overrides"と呼ぶ。
Changing a client's perspective means making it "watch" or "follow" a particular agent, much like the watch and follow commands that work with ordinary NetLogo models. See the dictionary entries for hubnet-send-watch, hubnet-send-follow, and hubnet-reset-perspective.
クライアントの視野の変更とは、特定のエージェントを見るのか、フォローするのかを意味する。 それは通常のNetLogoモデルで使われる watch と follow コマンドによく似ている。以下の辞書を見ること hubnet-send-watch, hubnet-send-follow, hubnet-reset-perspective.
Code Example: Client Perspective Example
Code Example: クライアント視野の例(Client Perspective Example HubNet)
Client overrides let you change the appearance of patches, turtles, and links in the client views. You can override any of the variables affecting an agent's appearance, including the hidden? variable causing a turtle or link to be visible or invisible. See the dictionary entries for hubnet-send-override, hubnet-clear-override, and hubnet-clear-overrides.
クライアントオーバーライドはパッチ、タートル、リンクの外観を変える。これはエージェントの外観に影響する変数を上書きすることができる。これは、タートルやリンクの表示、非表示の変数を含む。以下の辞書を見ること。 hubnet-send-override, hubnet-clear-override, hubnet-clear-overrides.
Code Example: Client Overrides Example
コード例: クライアントオーバーライド例(Client Overrides Example Hubnet)
If plot mirroring is enabled (in the HubNet Control Center) and a plot in the NetLogo model changes and a plot with the exact same name exists on the clients, a message with that change is sent to the clients causing the client's plot to make the same change. For example, let's pretend there is a HubNet model that has a plot called Milk Supply in NetLogo and the clients. Milk Supply is the current plot in NetLogo and in the Command Center you type:
プロットミラーリングが(HubNetコントロールセンターで)有効になっていて、NetLogoモデルのプロットが変化し、かつ同じ名前のプロットがクライアントに存在するならば、変化のメッセージがクライアントに送られ、同様の変化がクライアントプロットに生じる。例えば、NetLogoとクライアントにMilk Supplyというプロットを持つHubNetモデルがあるとする。Milk SupplyはNetLogoの現在プロットであり、かつコマンドセンターの中にある。
plot 5
This will cause a message to be sent to all the clients telling them that they need to plot a point with a y value of 5 in the next position of the plot. Notice, if you are doing a lot of plotting all at once, this can generate a lot of plotting messages to be sent to the clients.
これは全クライアントに、プロットの次の位置に5というyの値の点をプロットすることを伝えるメッセージを発生する。