sarl-fireworks/src/main/sarl/io/sarl/demos/fireworks/agents/Fire.sarl

157 lines
3.3 KiB
Plaintext

package io.sarl.demos.fireworks.agents
import io.sarl.core.AgentTask
import io.sarl.core.Behaviors
import io.sarl.core.DefaultContextInteractions
import io.sarl.core.Initialize
import io.sarl.core.Lifecycle
import io.sarl.core.Logging
import io.sarl.core.Schedules
import io.sarl.demos.fireworks.Configuration
import io.sarl.demos.fireworks.Positions
import io.sarl.demos.fireworks.events.Exit
import io.sarl.demos.fireworks.events.FireReady
import io.sarl.demos.fireworks.events.Freeze
import io.sarl.demos.fireworks.events.UpdateFirePosition
import io.sarl.util.Scopes
import java.util.ArrayList
import java.util.List
import java.util.UUID
import java.util.Vector
/*
* Fire agent moving with a nice trajectory
*/
agent Fire {
uses Lifecycle, Logging, Behaviors, DefaultContextInteractions, Schedules
var x : List<Double>
var y : List<Double>
var lifetime = 300
var frozen = false
var destroyed = false
var exited = false
var grid : Positions
var xf : Double
var yf : Double
var vx : Double
var vy : Double
var id = UUID.randomUUID
var parentID : UUID
var move : AgentTask
var parentAgent : UUID
var gravity: Double
/*
* Freeze itself
*/
on Freeze {
this.frozen = occurrence.value
if (frozen)
move.cancel(true)
else
wake(new UpdateFirePosition)
}
/*
* Initialization step
*/
on Initialize {
x = new ArrayList()
y = new ArrayList()
if (occurrence.parameters.size.equals(5)) {
x.add(occurrence.parameters.get(0) as Double)
y.add(occurrence.parameters.get(1) as Double)
grid = occurrence.parameters.get(2) as Positions
parentID = occurrence.parameters.get(3) as UUID
gravity = occurrence.parameters.get(4) as Double
} else {
info("Error in fire Initialize : bad parameter number")
}
parentAgent = occurrence.spawner
xf = Math.random() * 10.0 - Math.random() * 5
yf = Math.random() * 10.0 + 1.0
vx = xf * 20.0
vy = yf * 30.0
}
/*
* Trigger fixed delay for waking UpdateFirePosition
*/
on FireReady {
move = atFixedDelay(Configuration.FireLifeCycleSchedulingRate) [
try {
wake(new UpdateFirePosition);
} catch (e : Exception) {
e.printStackTrace
}
]
}
/*
* Update position every time it's triggered by itself
*/
on UpdateFirePosition [isFromMe(occurrence) && !frozen && !destroyed] {
var newx : Double
var newy : Double
vy = vy - gravity * Configuration.FireLifeCycleSchedulingRate / 10.0
newx = x.last + vx * Configuration.FireLifeCycleSchedulingRate / 1000.0
newy = y.last + vy * Configuration.FireLifeCycleSchedulingRate / 1000.0
x.add(newx)
y.add(newy)
if (grid !== null) {
var list = new ArrayList<Vector<Double>>
x.forEach [pos |
{
var nvect = new Vector(2)
nvect.add(pos)
list.add(nvect)
}
]
y.forEach [pos, i |
{
var nvect = list.get(i)
nvect.add(pos)
list.set(i, nvect)
}
]
grid.setFirePosition(id, parentID, list)
}
lifetime = lifetime - 10
if (lifetime <= 0) {
grid.removeFirePosition(id)
this.cleanBeforeExit
in(1000)[killMe]
}
}
/*
* Clean every task
*/
def cleanBeforeExit() {
move.cancel(true)
exited = true
destroyed = true
}
/*
* Kill itself when Exit signal invoked from parent
*/
on Exit [!exited && isFrom(getParentID)] {
frozen = true
this.cleanBeforeExit
emit(new Exit, Scopes.addresses(defaultSpace.getAddress(parentAgent)))
killMe
}
}