Package com.l2client.component

Source Code of com.l2client.component.ComponentSystem

package com.l2client.component;

import java.util.ArrayList;
import java.util.logging.Logger;

import com.jme3.system.NanoTimer;

/**
* Abstract class of a component system basic functionality.
* A component system has knowledge of components which it should updat, and only of those.
* Components are added by the addComponentForUpdate and removed by removeComponentForUpdate,
* this can be done in your own Entity factories or Entity creation code.
* <br>
* To integrate a system implement the onUpdateOf method with your specific component update
* functionality (for example calculate a new position of a mover component) and add a call to
* Yoursystem.update() to your general update loop
* <br>
* A ComponenSystem has a budget specified. During update the components are updated round robin
* until the budget is used up or the first one has been reached again (all been once updated).
* <br>
* Different systems could have different budgets defined.
* <br>
* For a general storage system for components have a look at @see EntityManager
* <br>
* Here is an example on how an entity could be initialized
* <br>
* <pre>
     Entity ent = Singleton.get().getEntityManager().createEntity(e.getObjectId());
    SimplePositionComponent pos = new SimplePositionComponent();
    L2JComponent l2j = new L2JComponent();
    VisualComponent vis = new VisualComponent();
    EnvironmentComponent env = new EnvironmentComponent();
   
    //done here extra as in update values will be left untouched
    pos.startPos.set(e.getX(), e.getY(), e.getZ());
    pos.currentPos.set(pos.startPos);
    pos.goalPos.set(pos.currentPos);
    pos.walkSpeed = e.getWalkSpeed();
    pos.runSpeed = e.getRunSpeed();
    pos.running = e.isRunning();
    pos.heading = e.getHeading();
    pos.targetHeading = pos.heading;
   
    updateComponents(e, ent, pos, l2j, env, vis);
   
    Singleton.get().getEntityManager().addComponent(ent.getId(), env);
    Singleton.get().getEntityManager().addComponent(ent.getId(), l2j);
    Singleton.get().getEntityManager().addComponent(ent.getId(), pos);   
    Singleton.get().getEntityManager().addComponent(ent.getId(), vis);

   
   
    Singleton.get().getPosSystem().addComponentForUpdate(pos);
    JmeUpdateSystem.get().addComponentForUpdate(pos);
    Singleton.get().getAnimSystem().addComponentForUpdate(env);
    </pre>
*/
//TODO check components not having had enough processing time get an extra dt during update (store last tpf for that system if not all ways processed)
public abstract class ComponentSystem {
 
  protected static Logger log = Logger.getLogger(ComponentSystem.class.getName());
 
  /**
   * List of registered components, could be of different type
   */
  protected ArrayList<Component> components = new ArrayList<Component>();

  /**
   * Maximum time in seconds to use for a system as a budget
   */
  public float timeBudget = 0.05f;
 
  /**
   * Implement here your component processing
   * @param c    A component to be updated
   * @param tpf  the delta time since the last call in seconds
   */
  public abstract void onUpdateOf(Component c, float tpf);
 
  /**
   * internal count of next component to be processed
   */
  private int nextComponent=0;
 
  /**
   * the so far used budget in the update loop
   */
  private float usedBudget =0f;
 
  /**
   * Calls onUpdateOf on registered components as often as the budget time allows it until the budgeted time
   * is used up, or all components have been processed in onUpdateOf. During the next update the remaining components are processed
   * @param tpf  delta time since the last update
   */
  public void update(float tpf){
    usedBudget = 0f;
    Component c = null;
    Component started = null;
    NanoTimer timer = new NanoTimer();
    do{
      c = getComponent();
      if(c != null) {
        if(started != null){
          if(c!=started){
            onUpdateOf(c, tpf);
          } else {
            log.finest(this.getClass()+" used budget up to:"+usedBudget+" of "+timeBudget);         
            return;
          }
        } else {
          started = c;
          onUpdateOf(c, tpf);
        }
      }
      else
        return;
      usedBudget = timer.getTimeInSeconds();
      log.finest(this.getClass()+" used time budget:"+usedBudget);
    } while( usedBudget <timeBudget);
    log.severe(this.getClass()+" used complete budget:"+usedBudget+" of "+timeBudget);
  }
 
  /**
   * fetch the next component to be processed going round robin
   * @return null or the next component
   */
  private Component getComponent(){
    synchronized (components) {
      int size = components.size();
      if(nextComponent>=size)
        nextComponent = 0;
      if(size <=0)
        return null;
      else {
        return components.get(nextComponent++);
      }
    }
   
  }

  /**
   * add a component to be updated by this system
   * @param c  the component to be used in updates
   */
  public void addComponentForUpdate(Component c){
    synchronized (components) {
      if(components.contains(c)){
System.out.println("Component already added "+c);
//        return;
      }
      components.add(c);
    }
  }
 
  /**
   * remove a component to be removed from this system
   * FIXME check this is working correctly, what if we delete one which is currently updated, better queue for removal.
   * @param c  the component to be removed
   */
  public void removeComponentForUpdate(Component c){
    synchronized (components) {
      components.remove(c);
    }
  }
 
  void dumpComponents(){
    synchronized (components) {
      System.out.println("DUMP start");
      for(Component c: components){
        System.out.println("DUMP of "+c);
      }
     
    }
  }
}
TOP

Related Classes of com.l2client.component.ComponentSystem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.