Dart DocumentationdartemisDelayedEntityProcessingSystem

DelayedEntityProcessingSystem abstract class

The purpose of this class is to allow systems to execute at varying intervals.

An example system would be an ExpirationSystem, that deletes entities after a certain lifetime. Instead of running a system that decrements a timeLeft value for each entity, you can simply use this system to execute in a future at a time of the shortest lived entity, and then reset the system to run at a time in a future at a time of the shortest lived entity, etc.

Another example system would be an AnimationSystem. You know when you have to animate a certain entity, e.g. in 300 milliseconds. So you can set the system to run in 300 ms. to perform the animation.

This will save CPU cycles in some scenarios.

Implementation notes: In order to start the system you need to override the inserted(Entity e) method, look up the delay time from that entity and offer it to the system by using the offerDelay(num delay) method. Also, when processing the entities you must also call offerDelay(num delay) for all valid entities.

abstract class DelayedEntityProcessingSystem extends EntitySystem {
 num _delay;
 bool _running;
 num _acc;

 DelayedEntityProcessingSystem(Aspect aspect) : super(aspect);

 /**
  * Check if the system is counting down towards processing.
  */
 bool get running => _running;

 /**
  * Return the delay until this entity should be processed.
  */
 num getRemainingDelay(Entity e);

 /**
  * Process a entity this system is interested in. Substract the accumulatedDelta
  * from the entities defined delay.
  */
 void processDelta(Entity e, num accumulatedDelta);

 void processExpired(Entity e);

 void processEntities(ReadOnlyBag<Entity> entities) {
   entities.forEach((entity) {
     processDelta(entity, _acc);
     num remaining = getRemainingDelay(entity);
     if(remaining <= 0) {
       processExpired(entity);
     } else {
       offerDelay(remaining);
     }
   });
   stop();
 }

 void inserted(Entity e) {
   num delay = getRemainingDelay(e);
   if(delay > 0) {
     offerDelay(delay);
   }
 }

 bool checkProcessing() {
   if(_running) {
     _acc += world.delta;

     if(_acc >= _delay) {
       return true;
     }
   }
   return false;
 }

 /**
  * Start processing of entities after a certain amount of delta time.
  *
  * Cancels current delayed run and starts a new one.
  */
 void restart(num delay) {
   this._delay = delay;
   this._acc = 0;
   _running = true;
 }

 /**
  * Restarts the system only if the delay offered is shorter than the
  * time that the system is currently scheduled to execute at.
  *
  * If the system is already stopped (not running) then the offered
  * delay will be used to restart the system with no matter its value.
  *
  * If the system is already counting down, and the offered delay is
  * larger than the time remaining, the system will ignore it. If the
  * offered delay is shorter than the time remaining, the system will
  * restart itself to run at the offered delay.
  */
 void offerDelay(num delay) {
   if(!_running || delay < getRemainingTimeUntilProcessing()) {
     restart(delay);
   }
 }

 /**
  * Get the initial delay that the system was ordered to process entities after.
  */
 num getInitialTimeDelay() => _delay;

 /**
  * Get the time until the system is scheduled to run at.
  * Returns zero (0) if the system is not running.
  * Use isRunning() before checking this value.
  */
 num getRemainingTimeUntilProcessing() {
   if(_running) {
     return _delay-_acc;
   }
   return 0;
 }

 /**
  * Stops the system from running, aborts current countdown.
  * Call offerDelay or restart to run it again.
  */
 void stop() {
   this._running = false;
   this._acc = 0;
 }

}

Extends

EntitySystem > DelayedEntityProcessingSystem

Constructors

new DelayedEntityProcessingSystem(Aspect aspect) #

DelayedEntityProcessingSystem(Aspect aspect) : super(aspect);

Properties

final passive #

inherited from EntitySystem
get passive => _passive;

final bool running #

Check if the system is counting down towards processing.

bool get running => _running;

World world #

inherited from EntitySystem
World world

Methods

void added(Entity e) #

inherited from EntitySystem
void added(Entity e) => _check(e);

void begin() #

inherited from EntitySystem

Called before processing of entities begins.

void begin() {}

void changed(Entity e) #

inherited from EntitySystem
void changed(Entity e) => _check(e);

bool checkProcessing() #

Returns true if the system should be processed, false if not.

docs inherited from EntitySystem
bool checkProcessing() {
 if(_running) {
   _acc += world.delta;

   if(_acc >= _delay) {
     return true;
   }
 }
 return false;
}

void deleted(Entity e) #

inherited from EntitySystem
void deleted(Entity e) {
 if (_contains(e)) {
   _removeFromSystem(e);
 }
}

void disabled(Entity e) #

inherited from EntitySystem
void disabled(Entity e) {
 if (_contains(e)) {
   _removeFromSystem(e);
 }
}

void enabled(Entity e) #

inherited from EntitySystem
void enabled(Entity e) => _check(e);

void end() #

inherited from EntitySystem

Called after the processing of entities ends.

void end() {}

num getInitialTimeDelay() #

Get the initial delay that the system was ordered to process entities after.

num getInitialTimeDelay() => _delay;

abstract num getRemainingDelay(Entity e) #

Return the delay until this entity should be processed.

num getRemainingTimeUntilProcessing() #

Get the time until the system is scheduled to run at. Returns zero (0) if the system is not running. Use isRunning() before checking this value.

num getRemainingTimeUntilProcessing() {
 if(_running) {
   return _delay-_acc;
 }
 return 0;
}

void initialize() #

inherited from EntitySystem

Override to implement code that gets executed when systems are initialized.

void initialize() {}

void inserted(Entity e) #

Called if the system has received an entity it is interested in, e.g. created or a component was added to it.

docs inherited from EntitySystem
void inserted(Entity e) {
 num delay = getRemainingDelay(e);
 if(delay > 0) {
   offerDelay(delay);
 }
}

void offerDelay(num delay) #

Restarts the system only if the delay offered is shorter than the time that the system is currently scheduled to execute at.

If the system is already stopped (not running) then the offered delay will be used to restart the system with no matter its value.

If the system is already counting down, and the offered delay is larger than the time remaining, the system will ignore it. If the offered delay is shorter than the time remaining, the system will restart itself to run at the offered delay.

void offerDelay(num delay) {
 if(!_running || delay < getRemainingTimeUntilProcessing()) {
   restart(delay);
 }
}

void process() #

inherited from EntitySystem

This is the only method that is supposed to be called from outside the library,

void process() {
 if(checkProcessing()) {
   begin();
   processEntities(_actives.readOnly);
   end();
 }
}

abstract void processDelta(Entity e, num accumulatedDelta) #

Process a entity this system is interested in. Substract the accumulatedDelta from the entities defined delay.

void processEntities(ReadOnlyBag<Entity> entities) #

Any implementing entity system must implement this method and the logic to process the given entities of the system.

docs inherited from EntitySystem
void processEntities(ReadOnlyBag<Entity> entities) {
 entities.forEach((entity) {
   processDelta(entity, _acc);
   num remaining = getRemainingDelay(entity);
   if(remaining <= 0) {
     processExpired(entity);
   } else {
     offerDelay(remaining);
   }
 });
 stop();
}

abstract void processExpired(Entity e) #

void removed(Entity entity) #

inherited from EntitySystem

Called if an entity was removed from this system, e.g. deleted or had one of it's components removed.

void removed(Entity entity) {}

void restart(num delay) #

Start processing of entities after a certain amount of delta time.

Cancels current delayed run and starts a new one.

void restart(num delay) {
 this._delay = delay;
 this._acc = 0;
 _running = true;
}

void stop() #

Stops the system from running, aborts current countdown. Call offerDelay or restart to run it again.

void stop() {
 this._running = false;
 this._acc = 0;
}