Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[core][sre][docs] Add the execute() function in the Schedules capacity.
see #421

Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed Nov 21, 2016
1 parent b4cf839 commit 1e6cf1c
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 0 deletions.
Expand Up @@ -1039,6 +1039,49 @@ describe "Built-in Capacity Reference" {
}".parseSuccessfully
}

/* For running a task once time, the following functions are
* provided:
*
* def execute(procedure : (Agent) => void) : AgentTask
* def execute(task : AgentTask,
* procedure : (Agent) => void) : AgentTask
*
*
* <p>The first function submits the given procedure (a lambda expression as defined in
* the [General Syntax Reference](GeneralSyntaxReferenceSpec.html)) to
* an executor provided by the runtime platform. The execution of the procedure
* will be executed once time as soon as possible.
* This function replies the agent task for controlling its execution.
*
* <p>The second function behaves in a similar way as the first, except that it
* accepts an agent task as parameter. This task will attach to the given
* procedure. The replied task is the same as the task given as parameter.
*
* @filter(.*)
*/
fact "Launching a Task for a single run"{
"GeneralSyntaxReferenceSpec.html" should beAccessibleFrom this
//
" package io.sarl.docs.reference.bic
import io.sarl.core.Logging
import io.sarl.core.Schedules
import io.sarl.core.AgentTask
import io.sarl.lang.core.Agent
agent A {
uses Schedules, Logging
def myaction {
var t1 : AgentTask
var t2 : AgentTask
t1 = execute [ a : Agent |
println(a)
]
t1 = t2.execute [ a : Agent |
println(a)
]
}
}".parseSuccessfully
}

/* For running a task in a given delay, the following functions are
* provided:
*
Expand Down
Expand Up @@ -2187,6 +2187,46 @@ describe "Creating a SARL Run-time Environment for the tinyMAS platform"{
''')
}

/* It is possible to execute a task only one time by calling the `execute` function.
* In the tinyMAs implementation, the `execute` function schedule the task for the
* next simulation step.
*
* @filter(.* = '''|'''|.parseSuccessfully.*)
*/
fact "Executed an agent task once" {
'''
def execute(task : AgentTask = null, procedure : (io.sarl.lang.core.Agent) => void) : AgentTask {
return in(
task,
(owner as TMSarlAgent).getSimulationStepDuration(TimeUnit::MILLISECONDS) as long,
procedure)
}
'''.parseSuccessfully(
'''
package io.sarl.docs.tutorials.tinyMASSRE
import java.util.UUID
import java.util.Collection
import java.util.ArrayList
import java.util.Map
import java.util.TreeMap
import java.util.concurrent.TimeUnit
import io.sarl.lang.core.Agent
import io.sarl.core.AgentTask
import io.sarl.core.Schedules
class Task extends AgentTask {
}
interface TMSarlAgent {
def getSimulationStepDuration(u : TimeUnit) : double
}
abstract class SchedulesSkill implements Schedules {
def getOwner : Agent { null }
''',
// TEXT
'''
}
''')
}

/* It is possible to schedule periodic tasks by calling the `every` function.
* The definition of this function is similar to the definition of
* the `in` function, except that the `period` field of the `Task` is set
Expand Down
16 changes: 16 additions & 0 deletions eclipse-sarl/plugins/io.sarl.core/src/io/sarl/core/bic.sarl
Expand Up @@ -419,6 +419,22 @@ capacity Schedules {
* @since 0.5
*/
def atFixedDelay(task : AgentTask = null, delay : long, procedure : (Agent) => void ) : AgentTask

/**
* Schedule a single-execution task.
*
* <p>This function is the easy to use version and efficient implementation of the code
* {@code in(0) [statements]}.
*
* <p>The given procedure takes one parameter: the agent associated to the task. It is name <code>it</code> by default.
*
* @param task the task to associate to the procedure. If <code>null</code> a new task is created.
* @param procedure the procedure to launch. The parameter of the procedure is the agent.
* @return the given task.
* @since 0.5
*/
def execute(task : AgentTask = null, procedure : (Agent) => void ) : AgentTask

}


Expand Down
Expand Up @@ -232,6 +232,15 @@ public AgentTask execute(Procedure1<? super Agent> procedure) {
return execute(Schedules.$DEFAULT_VALUE$EXECUTE_0, procedure);
}

@Override
public synchronized AgentTask execute(AgentTask task, Procedure1<? super Agent> procedure) {
final AgentTask rtask = task == null ? task(null) : task;
rtask.setProcedure(procedure);
final Future<?> future = this.executorService.submit(new AgentRunnableTask(rtask, false));
this.futures.put(rtask.getName(), future);
return rtask;
}

/**
* Implementation of an agent task.
*
Expand Down
Expand Up @@ -368,6 +368,31 @@ public void atFixedDelayAgentTaskLongProcedure1_zeroDelay() {
assertEquals("io.janusproject.kernel.bic.SchedulesSkill$AgentInfiniteLoopTask", runnable.getClass().getName());
}

@Test
public void executeProcedure1() {
Procedure1 procedure = Mockito.mock(Procedure1.class);
AgentTask task = this.skill.execute(procedure);
assertNotNull(task);
assertSame(procedure, task.getProcedure());
ArgumentCaptor<Runnable> argument1 = ArgumentCaptor.forClass(Runnable.class);
Mockito.verify(this.executorService, new Times(1)).submit(argument1.capture());
assertNotNull(argument1.getValue());
}

@Test
public void executeAgentTaskLongProcedure1() {
AgentTask task = Mockito.mock(AgentTask.class);
Mockito.when(task.getName()).thenReturn("thetask"); //$NON-NLS-1$
Procedure1 procedure = Mockito.mock(Procedure1.class);
AgentTask t = this.skill.execute(task, procedure);
assertSame(task, t);
ArgumentCaptor<Procedure1> argument0 = ArgumentCaptor.forClass(Procedure1.class);
Mockito.verify(task, new Times(1)).setProcedure(argument0.capture());
assertSame(procedure, argument0.getValue());
ArgumentCaptor<Runnable> argument1 = ArgumentCaptor.forClass(Runnable.class);
Mockito.verify(this.executorService, new Times(1)).submit(argument1.capture());
assertNotNull(argument1.getValue());
}

}

Expand Down Expand Up @@ -511,6 +536,12 @@ protected boolean runAgentTest() {
}

}

@Test
public void execute() throws Exception {
runJanus(SchedulesRunTestAgent4.class, false);
assertEquals(1, getNumberOfResults());
assertEquals(Boolean.TRUE, getResult(Boolean.class, 0));
}

/**
Expand Down

0 comments on commit 1e6cf1c

Please sign in to comment.