#!/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

}

}