final class TimeSpec[T] (number : Long, action : Long => T) {
def nanoseconds = action (number)
def microseconds = action (number * 1000L)
def miliseconds = action (number * 1000L * 1000L)
def seconds = action (number * 1000L * 1000L * 1000L)
def minutes = action (number * 1000L * 1000L * 1000L * 60L)
def hours = action (number * 1000L * 1000L * 1000L * 60L * 60L)
def days = action (number * 1000L * 1000L * 1000L * 60L * 60L * 24L)
}
final class Trigger (actor : MyActor, payload : Any) {
def in (number : Long) = new TimeSpec[Unit] (number, scheduleIn)
def every (number : Long) = new TimeSpec[Unit] (number, scheduleEvery)
private def scheduleIn (nanos : Long) = Scheduler.inNano (actor, payload, nanos)
private def scheduleEvery (nanos : Long) = Scheduler.everyNano (actor, payload, nanos)
}
final class ActorSchedule (actor : MyActor) {
def payload (payload : Any) = new Trigger (actor, payload)
}
trait MyActor ..... {
protected val schedule = new ActorSchedule (this)
....
}
В результате получил возможность писать вот такой код:
object TestActor extends MyActor {
schedule payload `Hi in 10 nanoseconds
schedule payload `HowAreYou every 5 seconds
schedule payload `Bye in 5 days
def act () = {
case `Hi => println ("Hello!")
case `HowAreYou => println ("I am fine")
case `Bye => println ("Bye-bye")
}
}
Идея в том, что schedule - это объект класса ActorSchedule. Этот класс предоставляет один метод payload имеющий один аргумент (собственно то, что будет послано актеру). В действительности "schedule payload `Hi" это вызов "schedule.payload(`Hi)". Этот вызов создаст объект класса Trigger. У класса Trigger есть два публичных метода in(Long) и every(Long). Так как эти методы не могут ничего полезного сделать до тех пор пока не будет известна единица измерения времени, то эти методы создают объекты TimeSpec передавая им в качестве параметра собственный метод, который будет вызван с количеством наносекнуд одним из методов класса TimeSpec.
Как мне кажется получился достаточно простой и удобный API без особых усилий.
Комментариев нет:
Отправить комментарий