Skip to content

Commit

Permalink
[docs] New spawning API.
Browse files Browse the repository at this point in the history
see #481
see #76

Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed Dec 16, 2016
1 parent d110883 commit 76ff282
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 101 deletions.
Expand Up @@ -83,7 +83,7 @@ describe "Run SARL Agent from a Java Program" {
* you could use the `Kernel` instance provided by Janus.
* This instance is replied by the `startJanus` function of the `Boot` class.
*
* <p>The `Kernel` type provides the `spawn` function, which permits launching
* <p>The `Kernel` type provides the `spawn` functions, which permit launching
* an agent programmatically.
*
* <p>The previous example could be updated for launching two agents of the same type.
Expand All @@ -95,8 +95,8 @@ describe "Run SARL Agent from a Java Program" {
* <p>The second parameter of the `spawn` function is the list of parameters to
* pass with the `Initialize` event to the launched agent.
*
* <p>Note that the first agent is launched by the `startJanus` function, and the
* second agent is launched by the `spawn` function.
* <important>that the first agent is launched by the `startJanus` function, and the
* second agent is launched by the `spawn` function.</important>
*
* @filter(.* = '''|'''|.parse.*)
*/
Expand Down
112 changes: 65 additions & 47 deletions docs/io.sarl.docs.suite/src/test/java/io/sarl/docs/reference/BIC.spec
Expand Up @@ -659,44 +659,6 @@ describe "Built-in Capacity Reference" {
}".parseSuccessfully
}

/* Many time, it is useful for agent to create a new agent
* into the default context. The following function is provided for this
* task:
*
* def spawn(agentType : Class<? extends Agent>, params : Object[]) : UUID
*
*
* <p>This action creates an instance of the given agent type, and launches the agent
* into the default context. The parameters are passed to the spawned agent inside
* the `Initialize` event: the `parameters` field.
*
* <p>This action fires two events:
*
* * `AgentSpawned` in the default space of the default context. The source of the event is this spawner.
* * `Initialize` in spawned agent.
*
* @filter(.*)
*/
fact "Spawning an Agent"{
" package io.sarl.docs.reference.bic
import io.sarl.core.DefaultContextInteractions
import io.sarl.lang.core.Agent
import java.util.UUID
agent A {
uses DefaultContextInteractions
def myaction {
var aid : UUID
var type : Class<? extends Agent>
var p1 : Object
var p2 : Object
type = typeof(A)
p1 = new Object
p2 = new Object
aid = spawn(type, #[p1, p2])
}
}".parseSuccessfully
}

/* The core mechanism for information exchanges among agents is
* [event-based](EventReferenceSpec.html).
* For sending an event in the default space of the default context,
Expand Down Expand Up @@ -921,17 +883,70 @@ describe "Built-in Capacity Reference" {
}".parseSuccessfully
}

/* Many time, it is useful for an agent to create a new agent
* into a given context. The following function is provided for this
/* Many time, it is useful for agent to create a new agent
* into the default context. The following functions are provided for this
* task:
*
* def spawn(agentType : Class<? extends Agent>, parameters : Object*) : UUID
*
* def spawn(nbAgents: int, agentType : Class<? extends Agent>, parameters : Object*) : Collection<UUID>
*
* <p>This action creates one to {@code nbAgents} instance(s) of the given agent type, and launches the agent(s)
* into the default context.
* The first `spawn` function above is spawning a single agent and replies the identifier of the spawned agent.
* The second `spawn` function is spawning the given number of agents and replies the identifiers of the
* spawned agents.
* The {@code parameters} are passed to the spawned agent inside
* the `Initialize` event: the `parameters` field.
*
* <p>This action fires two events:
*
* * `AgentSpawned` in the default space of the default context. The source of the event is this spawner.
* * `Initialize` in spawned agent.
*
* @filter(.*)
*/
fact "Spawning in the default context" {
" package io.sarl.docs.reference.bic
import io.sarl.core.Lifecycle
import io.sarl.lang.core.Agent
import java.util.UUID
import java.util.Collection
agent A {
uses Lifecycle
def myaction {
var aid : UUID
var listaid : Collection<UUID>
var type : Class<? extends Agent>
var p1 : Object
var p2 : Object
type = typeof(A)
p1 = new Object
p2 = new Object
aid = spawn(type, p1, p2)
listaid = spawn(5, type, p1, p2)
}
}".parseSuccessfully
}

/* When one or more agents should be spawned into a specific agent context, the two following functions
* could be used for launching the agents:
*
* def spawnInContext(agentType : Class<? extends Agent>,
* context : AgentContext,
* params : Object[]) : UUID
* parameters : Object*) : UUID
*
* def spawnInContext(nbAgents : int,
* agentType : Class<? extends Agent>,
* context : AgentContext,
* parameters : Object*) : UUID
*
* <p>This action creates an instance of the given agent type, and launches the agent
* into the given context. The parameters are passed to the spawned agent inside
* <p>This action creates one to {@code nbAgents} instance(s) of the given agent type, and launches the agent(s)
* into the given {@code context}.
* The first `spawn` function is spawning a single agent and replies the identifier of the spawned agent.
* The second `spawn` function is spawning the given number of agents and replies the identifiers of the
* spawned agents.
* The {@code parameters} are passed to the spawned agent inside
* the `Initialize` event: the `parameters` field.
*
* <p>This action fires two events:
Expand All @@ -941,24 +956,27 @@ describe "Built-in Capacity Reference" {
*
* @filter(.*)
*/
fact "Spawning an Agent"{
fact "Spawning in a specific context"{
" package io.sarl.docs.reference.bic
import io.sarl.core.Lifecycle
import io.sarl.lang.core.AgentContext
import io.sarl.lang.core.Agent
import java.util.UUID
import java.util.Collection
agent A {
uses Lifecycle
def myaction {
var c : AgentContext
var aid : UUID
var listaid : Collection<UUID>
var type : Class<? extends Agent>
var p1 : Object
var p2 : Object
type = typeof(A)
p1 = new Object
p2 = new Object
aid = spawnInContext(type, c, #[p1, p2])
aid = spawnInContext(type, c, p1, p2)
listaid = spawnInContext(5, type, c, p1, p2)
}
}".parseSuccessfully
}
Expand All @@ -970,7 +988,7 @@ describe "Built-in Capacity Reference" {
* def spawnInContextWithID(agentType : Class<? extends Agent>,
* agentId : UUID,
* context : AgentContext,
* params : Object[]) : UUID
* parameters : Object[]) : UUID
*
*
* <p>This action creates an instance of the given agent type, with
Expand All @@ -986,7 +1004,7 @@ describe "Built-in Capacity Reference" {
*
* @filter(.*)
*/
fact "Spawning an Agent with a specific identifier"{
fact "Spawning with a specific agent identifier"{
" package io.sarl.docs.reference.bic
import io.sarl.core.Lifecycle
import io.sarl.lang.core.AgentContext
Expand Down
Expand Up @@ -1239,17 +1239,16 @@ describe "Creating a SARL Run-time Environment for the tinyMAS platform"{
describe "Definition of the Lifecycle skill" {
/* Consider the agent execution mechanism in the tinyMAS platform:
* inside an infinite loop, each agent is run. This algorithmical
* inside an infinite loop, each agent is run. This algorithmic
* principle may be described by the following algorithm:
*
* ```
* while (true) {
* for(a : whitePages.allAgents) {
* a.live
* }
* refreshKernelState
* }
* ```
* while (true) {
* for(a : whitePages.allAgents) {
* a.live
* }
* refreshKernelState
* }
*
* The tinyMAS platform is designed for updating the kernel state
* after all the agent have been ran.
* Consequently, the tinyMAS platform does not support the creation
Expand All @@ -1258,10 +1257,10 @@ describe "Creating a SARL Run-time Environment for the tinyMAS platform"{
* spawned agent must be delayed until the `refreshKernelState` is invoked.
*
* <p>This particular design of the tinyMAS platform is at the opposite of
* the standard spawning principle in SARL: in SARL the agents are spawn
* the standard spawning principle in SARL: the agents are spawned
* when the spawning function is called.
*
* <p>For solving this issue, we need to implement a buffer of spawned
* <p>For fixing this issue, we need to implement a buffer of spawned
* agents, that will be filled by the SARL spawning functions, and consumed
* by the `refreshKernelState` function.
*
Expand Down Expand Up @@ -1306,6 +1305,7 @@ describe "Creating a SARL Run-time Environment for the tinyMAS platform"{
'''.parseSuccessfully(
'''
package io.sarl.docs.tutorials.tinyMASSRE
import java.util.Collection
import java.util.UUID
import java.util.List
import java.util.ArrayList
Expand Down Expand Up @@ -1348,6 +1348,28 @@ describe "Creating a SARL Run-time Environment for the tinyMAS platform"{
'''
class LifecycleSkill extends Skill implements Lifecycle {
def spawn(
agentClass : Class<? extends io.sarl.lang.core.Agent>,
params : Object*)
: UUID {
return defaultSpace.spawn(agentClass, null, params)
}
def spawn(
nbAgents : int,
agentClass : Class<? extends io.sarl.lang.core.Agent>,
params : Object*)
: Collection<UUID> {
var list = newArrayList
for (i : 1..nbAgents) {
var id = defaultSpace.spawn(agentClass, null, params)
if (id !== null) {
list += id
}
}
return list
}
def spawnInContext(
agentClass : Class<? extends io.sarl.lang.core.Agent>,
context : AgentContext,
Expand All @@ -1359,6 +1381,24 @@ describe "Creating a SARL Run-time Environment for the tinyMAS platform"{
return null
}
def spawnInContext(
nbAgents : int,
agentClass : Class<? extends io.sarl.lang.core.Agent>,
context : AgentContext,
params : Object*)
: Collection<UUID> {
var list = newArrayList
if (context.ID == defaultSpace.agentContext.ID) {
for (i : 1..nbAgents) {
var id = defaultSpace.spawn(agentClass, null, params)
if (id !== null) {
list += id
}
}
}
return list
}
def spawnInContextWithID(
agentClass : Class<? extends io.sarl.lang.core.Agent>,
agentID : UUID,
Expand All @@ -1380,6 +1420,7 @@ describe "Creating a SARL Run-time Environment for the tinyMAS platform"{
'''.parseSuccessfully(
'''
package io.sarl.docs.tutorials.tinyMASSRE
import java.util.Collection
import java.util.UUID
import io.sarl.core.Lifecycle
import io.sarl.lang.core.AgentContext
Expand Down Expand Up @@ -1481,8 +1522,7 @@ describe "Creating a SARL Run-time Environment for the tinyMAS platform"{
}

/* The `DefaultContextInteractions` capacity enables the agent to have
* interaction in the default space, and to spawn agents in the default
* context.
* interaction in the default space.
*/
describe "Definition of the DefaultContextInteractions skill" {

Expand Down Expand Up @@ -1636,36 +1676,6 @@ describe "Creating a SARL Run-time Environment for the tinyMAS platform"{
typeof(DefaultContextInteractions) should haveDeprecatedMethod "receive(java.util.UUID,io.sarl.lang.core.Event)"
}

/* Spawning an agent in the default context could be done by calling the `spawn` function of
* the `DefaultContextInteractions` capacity.
* This function delegates its behavior to the `spawn` function that is already defined
* in the tinyMAS-SARL default space class.
*
* @filter(.* = '''|'''|.parseSuccessfully.*)
*/
fact "Spawning agents in the default context" {
'''
def spawn(agentType : Class<? extends io.sarl.lang.core.Agent>, params : Object*) : UUID {
(defaultSpace as TMDefaultSpace).spawn(agentType, null, params)
}
'''.parseSuccessfully(
'''
package io.sarl.docs.tutorials.tinyMASSRE
import java.util.UUID
import io.sarl.lang.core.EventSpace
import io.sarl.core.DefaultContextInteractions
interface TMDefaultSpace extends EventSpace {
def spawn(agentType : Class<? extends io.sarl.lang.core.Agent>, agentID : UUID, params : Object*) : UUID
}
abstract class DefaultContextInteractionsSkill implements DefaultContextInteractions {
def getDefaultSpace : EventSpace { null }
''',
// TEXT
'''
}
''')
}

}

/* The `Behaviors` capacity enables the agent to have
Expand Down
Expand Up @@ -636,20 +636,20 @@ describe "Agent Communication with the Ping Pong Agents"{
*/
describe "Method 2: Execute all the agents in a single instance of Janus" {

/* The boot agent uses the `DefaultContextInteractions`
/* The boot agent uses the `Lifecycle`
* capacity for launching agents in the default context.
* This capacity provides the function `spawn(Class<? extends Agent>)`
* for launching an agent of the given type.
* When the boot agent has launched the two expected agents,
* it is killing itself. This is done with the `killMe`
* function, which is provided by the `Lifecycle` capacity.
* function, which is provided by the `Lifecycle` capacity too.
*
* @filter(.* = '''|'''|.parseSuccessfully.*)
*/
fact "Defining the Boot agent" {
'''
agent BootAgent {
uses DefaultContextInteractions, Lifecycle
uses Lifecycle
on Initialize {
spawn( PongAgent )
spawn( PingAgent )
Expand All @@ -658,7 +658,6 @@ describe "Agent Communication with the Ping Pong Agents"{
}
'''.parseSuccessfully(
"package io.sarl.docs.tutorials.pingpong
import io.sarl.core.DefaultContextInteractions
import io.sarl.core.Initialize
import io.sarl.core.Lifecycle
agent PongAgent { }
Expand Down

0 comments on commit 76ff282

Please sign in to comment.