#!/usr/agenttcl/bin/agent-tk
# #############################################################################
# CODE
# #############################################################################
# identify the directory that contains the script
set scriptDirectory [file dirname [info script]]
# source the tracker code
source "AgentTrack.tcl"
# source the "include" procedure and the configuration file
source $scriptDirectory/include.tcl
source $scriptDirectory/demo.config
# add to the include path
addToIncludePath $config(demoPath)
# include the logging facilities, the banking facilities, the utility
# routines and the status facilities
include control/common
include econ/usebank
include log
include startAgents
include utility
include status
# initialize the list of demo agents
start_createAgentList
# Turn on the logging facilities if specified in the configuration file
if {$config(logging) == "on"} {
turnOnLogging
setLoggingMachine $config(loggingMachine)
}
# get the vendor information
set vendors [getVendorList $config(vendorPath)/machines]
# register with the agent system
agent_begin
agent_name "starter"
track 1
# establish a default handler for incoming messages
mask add $mask(message) "default -event messageHandler"
mask add $mask(event) "default -event eventHandler"
# create the main window
main create -name "Agent Starter"
# create the status area
status_createStatusArea . start_agentList start_agentOrder
frame .holder
set starterButtons \
{ bankStart arbiterStart vendorStart walletMgrStart toDemo killAllAgents quit}
set buttonState \
{ normal disabled disabled disabled disabled normal normal}
set buttonText { "Start Bank" "Start Arbiter" "Start Vendors" "Start Wallet Manager" \
"Start Demo" "Kill all agents" "Quit" }
set i 0
foreach quick_button $starterButtons {
button .holder.$quick_button -state [lindex $buttonState $i] -text [lindex $buttonText $i]
pack .holder.$quick_button -side top -fill x
incr i
}
.holder.quit configure -command {
killAllAgents
agent_end
exit 0
}
.holder.killAllAgents configure -command {
killAllAgents
}
.holder.bankStart configure -command {
bankStarter
.holder.bankStart configure -state disabled
}
.holder.walletMgrStart configure -command {
walletMgrStarter
.holder.walletMgrStart configure -state disabled
}
.holder.arbiterStart configure -command {
arbiterStarter
.holder.arbiterStart configure -state disabled
}
.holder.vendorStart configure -command {
vendorStarter
.holder.vendorStart configure -state disabled
}
.holder.toDemo configure -command {
global config
set pid [exec $config(demoPath)/demo.tcl &]
}
# pack the gui
pack .holder -side top -fill x
status_createTextArea .
## End of Gui Setup -----------------------------------------#
# -----------------------Procedures Called By Gui ------------------------#
proc resetDemo {} {
global starterButtons
global buttonText
global buttonState
global start_agentList
global start_agentCounts
# reset the buttons
set i 0
foreach quick_button $starterButtons {
.holder.$quick_button configure -state [lindex $buttonState $i]
.holder.$quick_button configure -text [lindex $buttonText $i]
incr i
}
# reset the status area
status_resetStatus . start_agentList start_agentCounts
}
proc eventHandler {source security tag string} {
global start_agentList
global start_agentCounts
if {$tag == "bank"} {
status_updateStatus . bank running $source start_agentList start_agentCounts
init_bank $string
status_displayMessage . "Bank initialized!" $string
.holder.bankStart configure -text "Bank ready!"
.holder.arbiterStart configure -state normal
} elseif {$tag == "arbiter"} {
status_updateStatus . arbiter running $source start_agentList start_agentCounts
status_displayMessage . "Arbiter initialized!" $string
.holder.arbiterStart configure -text "Arbiter ready!"
.holder.vendorStart configure -state normal
} elseif {$tag == "wallet"} {
status_updateStatus . wallet running $source start_agentList start_agentCounts
status_displayMessage . "Wallet manager initialized!" $string
.holder.walletMgrStart configure -text "Wallet manager ready!"
.holder.toDemo configure -state normal
} else {
status_updateStatus . $tag running $source start_agentList start_agentCounts
status_displayMessage . "Vendor $tag initialized!" $string
}
}
proc messageHandler {source security code string} {
global start_agentList
global start_agentCounts
# identify the agent
set name [status_findAgent $source start_agentList]
# update the status information
if {$code == 0} {
if {$name != ""} {
status_updateStatus . $name stopped $source start_agentList start_agentCounts
}
} else {
if {[lindex $string 1] != "NONE"} {
set string [list $string NONE NONE]
}
status_displayAgentError . "Runtime failure in agent" $source $string
if {$name != ""} {
status_updateStatus . $name "stopped with error" $source start_agentList start_agentCounts
} else {
status_displayMessage . "RESETTING DEMO DUE TO AGENT FAILURE!"
killAllAgents
resetDemo
return
}
}
# check if we still have running agents
if {[status_getAgentCount start_agentCounts] == 0} {
status_displayMessage . "RESETTING DEMO SINCE ALL AGENTS HAVE STOPPED!"
resetDemo
return
}
}
# ==============================================================
# Procedure: killEconAgents
# Arguments: none
# Returns: nothing
# Purpose: Kills the bank, arbiter, and walletmgr by
# sending them and "agent_force" command
# ==============================================================
proc killAllAgents {} {
.holder.killAllAgents configure -text "Killing agents ..."
.holder.killAllAgents configure -state disabled
update idletasks
killVendors
killEconAgents
.holder.killAllAgents configure -text "Kill all agents"
.holder.killAllAgents configure -state normal
update idletasks
}
proc killEconAgents {} {
global config
# kill the bank agent
.holder.killAllAgents configure -text "Killing bank ..."
update idletasks
catch {
agent_send "$config(bankLocation) $config(bankName)" 0 STOP
}
status_displayMessage . "Bank killed!"
# kill the arbiter agent
.holder.killAllAgents configure -text "Killing arbiter ..."
update idletasks
catch {
agent_send "$config(arbiterLocation) $config(arbiterName)" 0 STOP
}
status_displayMessage . "Arbiter killed!"
# kill the wallet manager agent
.holder.killAllAgents configure -text "Killing wallet manager ..."
update idletasks
catch {
agent_send "$config(walletLocation) $config(walletName)" 0 STOP
}
status_displayMessage . "Wallet manager killed!"
}
# ==============================================================
# Procedure: killVendors
# Arguments: none
# Returns: nothing
# Purpose: Kills all of the vendors by sending them and "agent_force" command
# ==============================================================
proc killVendors {} {
global vendors
foreach vendor $vendors {
set vendorLocation [lindex $vendor 0]
set vendorName [lindex $vendor 1]
.holder.killAllAgents configure -text "Killing vendor $vendorName ..."
update idletasks
catch {
agent_send "$vendorLocation $vendorName" 0 STOP
}
status_displayMessage . "Vendor $vendorName killed!"
}
}
# ==============================================================
# Procedure: vendorStarter
# Arguments: machines
# Returns: nothing
# Purpose: starts up the vendors
# ==============================================================
proc vendorStarter {} {
global agent
global config
global vendors
global errorCode
global errorInfo
global start_agentList
global start_agentCounts
global starts_vendorsStarted
# user has just hit the "Start Vendors" button
.holder.vendorStart configure -state disabled
.holder.vendorStart configure -text "Starting vendors ..."
update idletasks
# foreach vendor defined in vendors list (where each entry is:
# machineName vendorName vendorFileName), spawn a new vendor named
# vendorName to machineName.
foreach vendor $vendors {
# get the vendor information
set vendorLocation [lindex $vendor 0]
set vendorName [lindex $vendor 1]
set vendorFile [lindex $vendor 2]
set soundPath [lindex $vendor 3]
# status report
.holder.vendorStart configure -text "Starting vendor $vendorName ..."
update idletasks
# submit the vendor
set code [
catch {
# initial vendor funds
set vendorWallet [splt $config(vendorFunds)]
# do the submission
set id [submit_with_includes \
{log} \
{} \
{config soundPath vendorName vendorFile vendorWallet \
vendorLocation \
} \
{
# read the vendor agent code
source $config(vendorPath)/vendorAgent.tcl
# get the catalog
set catalog [getCatalog $config(vendorPath)/$vendorFile]
# jump to the desired location and start the vendor
agent_jump $vendorLocation
vendor $soundPath $vendorName $catalog $vendorWallet $agent(root) \
$config(vendorLifetime)
}
]
} result
]
# display the message
if {$code} {
status_displayAgentError . "Unable to spawn vendor $vendorName" "THIS AGENT" [list $result $errorCode $errorInfo]
status_updateStatus . $vendorName "failed to start" {} start_agentList start_agentCounts
} else {
status_displayMessage . "Vendor $vendorName started!" "Waiting for initialization message ..."
status_updateStatus . $vendorName "running" $id start_agentList start_agentCounts
.holder.walletMgrStart configure -state normal
}
}
.holder.vendorStart configure -text "Vendors ready!"
update idletasks
}
# ==============================================================
# Procedure: bankStarter
# Arguments: none
# Returns: nothing
# Purpose: starts up the bank agent
# ==============================================================
proc bankStarter {} {
global agent
global config
global errorCode
global errorInfo
global start_agentList
global start_agentCounts
# user has just hit the "Start Bank" button
.holder.bankStart configure -state disabled
.holder.bankStart configure -text "Starting Bank ..."
update idletasks
# submit the banking agent
set code [
catch {
set id [submit_with_includes \
{log} \
{} \
{config} \
{
source $config(bankPath)/bank.tcl
agent_jump $config(bankLocation)
bank $config(bankName) $agent(root) $config(initialFunds) $config(bankLifetime)
}
]
} result
]
# display message
if {$code} {
status_displayAgentError . "Unable to spawn bank" "THIS AGENT" [list $result $errorCode $errorInfo]
status_updateStatus . bank "failed to start" {} start_agentList start_agentCounts
.holder.bankStart configure -text "Start bank!"
.holder.bankStart configure -state normal
update idletasks
} else {
status_displayMessage . "Bank started!" "Waiting for initialization message ..."
status_updateStatus . bank "running" $id start_agentList start_agentCounts
.holder.bankStart configure -text "Bank initializing ..."
update idletasks
}
}
# ==============================================================
# Procedure: arbiterStarter
# Arguments: none
# Returns: nothing
# Purpose: starts up the arbiter agent
# ==============================================================
proc arbiterStarter {} {
global agent
global config
global errorCode
global errorInfo
global start_agentList
global start_agentCounts
# user has just hit the "Start Arbiter" button
.holder.arbiterStart configure -state disabled
.holder.arbiterStart configure -text "Starting arbiter ..."
update idletasks
# submit the arbiter agent
set code [
catch {
# split the arbiter's initial funds out of our wallet
set arbiterWallet [splt $config(arbiterFunds)]
# do the submission
set id [submit_with_includes \
{log} \
{} \
{config arbiterWallet} \
{
source $config(arbiterPath)/arbiter.tcl
agent_jump $config(arbiterLocation)
arbiter $config(arbiterName) $agent(root) $arbiterWallet $config(arbiterLifetime)
}
]
} result
]
# display message
if {$code} {
status_displayAgentError . "Unable to spawn arbiter!" "THIS AGENT" [list $result $errorCode $errorInfo]
status_updateStatus . arbiter "failed to start" {} start_agentList start_agentCounts
.holder.arbiterStart configure -text "Arbiter failed!"
update idletasks
} else {
status_displayMessage . "Arbiter started!" "Waiting for initialization message ..."
status_updateStatus . arbiter "running" $id start_agentList start_agentCounts
.holder.arbiterStart configure -text "Arbiter initializing ..."
update idletasks
}
}
# ==============================================================
# Procedure: walletMgrStarter
# Arguments: none
# Returns: nothing
# Purpose: starts up the walletManger agent
# ==============================================================
proc walletMgrStarter {} {
global agent
global config
global errorCode
global errorInfo
global start_agentList
global start_agentCounts
# user has just hit the "Start Wallet Manager" button
.holder.walletMgrStart configure -state disabled
.holder.walletMgrStart configure -text "Starting wallet manager ..."
update idletasks
# submit the wallet manager agent
set code [
catch {
# all remaining cash goes to the wallet manager
set remainingCash [quit_bank]
# do the submission
set id [submit_with_includes \
{log} \
{} \
{config remainingCash} \
{
source $config(walletPath)/wallet.tcl
agent_jump $config(walletLocation)
wallet $config(walletName) $remainingCash $agent(root) $config(walletLifetime)
}
]
} result
]
# display the message
if {$code} {
status_displayAgentError . "Unable to spawn wallet manager!" "THIS AGENT" [list $result $errorCode $errorInfo]
status_updateStatus . wallet "failed to start" {} start_agentList start_agentCounts
.holder.walletMgrStart configure -text "Wallet manager failed!"
update idletasks
} else {
status_displayMessage . "Wallet manager started!" "Waiting for initialization message ..."
status_updateStatus . wallet "running" $id start_agentList start_agentCounts
.holder.walletMgrStart configure -text "Wallet manager initializing ..."
update idletasks
}
}