Skip to content

Commit

Permalink
[all] Add Time capacity.
Browse files Browse the repository at this point in the history
see #407

Signed-off-by: Stéphane Galland <galland@arakhne.org>
  • Loading branch information
gallandarakhneorg committed Sep 12, 2016
1 parent bf9c7b3 commit 42bd194
Show file tree
Hide file tree
Showing 8 changed files with 424 additions and 18 deletions.
Expand Up @@ -1335,6 +1335,43 @@ describe "Built-in Capacity Reference" {

}

/* The built-in capacity `Time` provides tools for obtaining the current time
* from the run-time platform.
*
* Time definition is application-dependent and platform-dependent. In other words,
* the time values replied by this capacity depends on the run-time environment:
* it may be the operating system time, or a simulator time.
*/
describe "Time" {

/* For obtaining the current time, the `getTime` function is provides by the `Time`
* capacity:
*
* def getTime(timeUnit : TimeUnit = null) : double
*
*
* <p>The timeUnit parameter will enable you to specify the unit of the replied
* value (hours, seconds, milliseconds, etc.). If it is not provided,
* the values will be expressed in seconds.
*
* @filter(.*)
*/
fact "Get the current time" {
" package io.sarl.docs.reference.bic
import io.sarl.core.Logging
import java.util.concurrent.TimeUnit
agent A {
uses Time
def myaction {
var ct = getTime;
var ct2 = getTime(null)
var ct3 = getTime(TimeUnit::HOURS)
}
}".parseSuccessfully
}

}

/* Details on the use of the built-in capacities may be found in the references of
* the major behavior-based concepts of SARL:
*
Expand Down
29 changes: 28 additions & 1 deletion eclipse-sarl/plugins/io.sarl.core/src/io/sarl/core/bic.sarl
Expand Up @@ -20,6 +20,9 @@
*/
package io.sarl.core

import java.util.UUID
import java.util.concurrent.TimeUnit

import io.sarl.core.AgentTask
import io.sarl.lang.core.EventSpace
import io.sarl.lang.core.Address
Expand All @@ -33,7 +36,6 @@ import io.sarl.lang.core.Space
import io.sarl.lang.core.SpaceID
import io.sarl.lang.util.SynchronizedCollection
import io.sarl.lang.util.SynchronizedSet
import java.util.UUID

capacity ExternalContextAccess {
/**
Expand Down Expand Up @@ -616,3 +618,28 @@ capacity Logging {
def setLogLevel(level : int)

}

/**
* Gives access to the time in the agent application.
* Time management is application-dependent. This capacity does not make any assumption
* on neither time evolution nor time refresh rate.
*/
capacity Time {

/** Replies the current time.
*
* @param timeUnit if present, specifies the time unit of the value to reply. By default is it seconds.
*/
def getTime(timeUnit : TimeUnit = null) : double

/** Replies the scaling factor between the agent time and the operating system time.
* <p>Consider time in the agent application. It may evolves at a different rate than
* the operating system time. The value that is replied by this function permits to
* determine the proportionally between the agent application time and the operating system time.
* A typical equation for representing this relation is: os time = OSTimeFactor * agent time.
*
* @return the factor between agent time and operating system time.
*/
def getOSTimeFactor : double

}
Expand Up @@ -21,6 +21,8 @@

package io.sarl.lang.scoping.batch;

import java.util.concurrent.TimeUnit;

import com.google.common.annotations.GwtCompatible;
import org.eclipse.xtext.xbase.lib.Inline;
import org.eclipse.xtext.xbase.lib.Pure;
Expand Down Expand Up @@ -113,6 +115,69 @@ public static long weeks(Integer weeks) {
return weeks.longValue() * TimeExtensionsConstants.MILLIS_IN_WEEK;
}

/** Convert the gien amount of time in the given source unit, to the given target unit.
* In opposite to {@link TimeUnit#convert(long, TimeUnit)}, this function works on
* double floating-point values.
*
* @param time the amount of time.
* @param source the source unit. Never <code>null</code>.
* @param target the target unit. Never <code>null</code>.
* @return the amount of time in the target unit.
*/
@Pure
@SuppressWarnings("checkstyle:cyclomaticcomplexity")
public static double convertFromTo(double time, TimeUnit source, TimeUnit target) {
assert source != null;
assert target != null;
if (source == target) {
return time;
}
final double millis;
switch (source) {
case DAYS:
millis = time * TimeExtensionsConstants.MILLIS_IN_DAY;
break;
case HOURS:
millis = time * TimeExtensionsConstants.MILLIS_IN_HOUR;
break;
case MINUTES:
millis = time * TimeExtensionsConstants.MILLIS_IN_MINUTE;
break;
case SECONDS:
millis = time * TimeExtensionsConstants.MILLIS_IN_SECOND;
break;
case MILLISECONDS:
millis = time;
break;
case NANOSECONDS:
millis = time * TimeExtensionsConstants.MILLIS_IN_NANOSECOND;
break;
case MICROSECONDS:
millis = time * TimeExtensionsConstants.MILLIS_IN_MICROSECOND;
break;
default:
throw new IllegalArgumentException();
}
switch (target) {
case DAYS:
return millis / TimeExtensionsConstants.MILLIS_IN_DAY;
case HOURS:
return millis / TimeExtensionsConstants.MILLIS_IN_HOUR;
case MINUTES:
return millis / TimeExtensionsConstants.MILLIS_IN_MINUTE;
case SECONDS:
return millis / TimeExtensionsConstants.MILLIS_IN_SECOND;
case MILLISECONDS:
return millis;
case NANOSECONDS:
return millis / TimeExtensionsConstants.MILLIS_IN_NANOSECOND;
case MICROSECONDS:
return millis / TimeExtensionsConstants.MILLIS_IN_MICROSECOND;
default:
throw new IllegalArgumentException();
}
}

/**
* Constants for the SARL time extensions.
*
Expand Down Expand Up @@ -144,6 +209,14 @@ public final class TimeExtensionsConstants {
*/
public static final long MILLIS_IN_WEEK = 7 * MILLIS_IN_DAY;

/** Number of millis in a microsecond.
*/
public static final double MILLIS_IN_MICROSECOND = 10e-6;

/** Number of millis in a nanosecond.
*/
public static final double MILLIS_IN_NANOSECOND = 10e-9;

private TimeExtensionsConstants() {
//
}
Expand Down
Expand Up @@ -38,6 +38,7 @@
import io.sarl.core.Lifecycle;
import io.sarl.core.Logging;
import io.sarl.core.Schedules;
import io.sarl.core.Time;
import io.sarl.lang.core.Address;
import io.sarl.lang.core.Agent;
import io.sarl.lang.core.BuiltinCapacitiesProvider;
Expand Down Expand Up @@ -65,7 +66,7 @@ public class StandardBuiltinCapacitiesProvider implements BuiltinCapacitiesProvi
InternalEventBusSkill.class, MicroKernelSkill.class, InnerContextSkill.class,
BehaviorsSkill.class, LifecycleSkill.class,
ExternalContextAccessSkill.class, DefaultContextInteractionsSkill.class,
SchedulesSkill.class, LoggingSkill.class,
SchedulesSkill.class, LoggingSkill.class, TimeSkill.class,
};

@Inject
Expand Down Expand Up @@ -93,6 +94,7 @@ public Map<Class<? extends Capacity>, Skill> getBuiltinCapacities(Agent agent) {
this.contextRepository.getContext(agent.getParentID()));
final SchedulesSkill scheduleSkill = new SchedulesSkill(agent);
final LoggingSkill loggingSkill = new LoggingSkill(agent);
final TimeSkill timeSkill = new TimeSkill(agent);

this.injector.injectMembers(eventBusSkill);
this.injector.injectMembers(innerContextSkill);
Expand All @@ -102,6 +104,7 @@ public Map<Class<? extends Capacity>, Skill> getBuiltinCapacities(Agent agent) {
this.injector.injectMembers(interactionSkill);
this.injector.injectMembers(scheduleSkill);
this.injector.injectMembers(loggingSkill);
this.injector.injectMembers(timeSkill);

final MicroKernelSkill microKernelSkill = new MicroKernelSkill(agent, k);

Expand All @@ -116,6 +119,7 @@ public Map<Class<? extends Capacity>, Skill> getBuiltinCapacities(Agent agent) {
result.put(DefaultContextInteractions.class, interactionSkill);
result.put(Schedules.class, scheduleSkill);
result.put(Logging.class, loggingSkill);
result.put(Time.class, timeSkill);

this.spawnService.addSpawnServiceListener(agent.getID(),
new AgentLifeCycleSupport(agent.getID(), this.spawnService, eventBusSkill));
Expand All @@ -130,6 +134,7 @@ public Map<Class<? extends Capacity>, Skill> getBuiltinCapacities(Agent agent) {
assert result.get(Schedules.class) != null;
assert result.get(MicroKernelCapacity.class) != null;
assert result.get(Logging.class) != null;
assert result.get(Time.class) != null;

return result;
}
Expand Down
@@ -0,0 +1,77 @@
/*
* $Id$
*
* SARL is an general-purpose agent programming language.
* More details on http://www.sarl.io
*
* Copyright (C) 2014-2016 the original authors or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.janusproject.kernel.bic;

import java.util.concurrent.TimeUnit;

import org.eclipse.xtext.xbase.lib.Inline;

import io.sarl.core.Time;
import io.sarl.lang.core.Agent;
import io.sarl.lang.scoping.batch.SARLTimeExtensions;

/**
* Janus implementation of SARL's {@link Time} built-in capacity.
*
* @author $Author: sgalland$
* @version $FullVersion$
* @mavengroupid $GroupId$
* @mavenartifactid $ArtifactId$
*/
public class TimeSkill extends BuiltinSkill implements Time {

private static int installationOrder = -1;

/**
* @param agent - owner of this skill.
*/
TimeSkill(Agent agent) {
super(agent);
}

@Override
public int getInstallationOrder() {
if (installationOrder < 0) {
installationOrder = installationOrder(this);
}
return installationOrder;
}

@Override
public double getTime(TimeUnit timeUnit) {
final double currentTime = System.currentTimeMillis();
final TimeUnit tu = (timeUnit == null) ? TimeUnit.SECONDS : timeUnit;
return SARLTimeExtensions.convertFromTo(currentTime, TimeUnit.MILLISECONDS, tu);
}

@Override
@Inline(value = "getTime(null)")
public double getTime() {
return getTime(null);
}

@Override
public double getOSTimeFactor() {
return 1;
}

}

0 comments on commit 42bd194

Please sign in to comment.