Sometimes it is useful to implement operations that trigger the asynchronous execution of other operations inside the artifact, which are typically long-term. For instance: a clock artifact can have the start operation, triggering the execution of a long-term counting operation. Such operations are typically internal, i.e. not (necessarily) part of the usage interface, and are annotated with @INTERNAL_OPERATION. To trigger the execution of an internal operation the execInternalOp primitive is provided.

In the following example, an agent creates a clock and uses it.

MAS example06_clock {

  environment:
  c4jason.CartagoEnvironment

  agents:
  clock_user agentArchClass c4jason.CAgentArch;

  classpath: "../../../lib/cartago.jar";"../../../lib/c4jason.jar";
}

The clock artifact has two usage interface operations - start and stop - and an internal operation count, triggered by start:

public class Clock extends Artifact {

  boolean counting;
  final static long TICK_TIME = 100;

  void init(){
    counting = false;
  }

  @OPERATION void start(){
    if (!counting){
      counting = true;
      execInternalOp("count");
    } else {
      failed("already_counting");
    }
  }

  @OPERATION void stop(){
    counting = false;
  }

  @INTERNAL_OPERATION void count(){
    while (counting){
      signal("tick");
      await_time(TICK_TIME);
    }
  }
}

Highlights:

The agent starts a clock, then reacts to ticks generated by it for a certain number of times, and finally stopping it.

!test_clock.

+!test_clock
  <- makeArtifact("myClock","c4jexamples.Clock",[],Id);
     focus(Id);
     +n_ticks(0);
     start;
     println("clock started.").

@plan1
+tick: n_ticks(10)
  <- stop;
     println("clock stopped.").

@plan2 [atomic]
+tick: n_ticks(N)
  <- -+n_ticks(N+1);
     println("tick perceived!").

Highlights: