All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.artemis.link.EntityLinkManager Maven / Gradle / Ivy

There is a newer version: 2.3.0
Show newest version
package com.artemis.link;

import com.artemis.*;
import com.artemis.annotations.SkipWire;
import com.artemis.utils.Bag;
import com.artemis.utils.reflect.ClassReflection;
import com.artemis.utils.reflect.Field;
import com.artemis.utils.reflect.ReflectionException;


import static com.artemis.Aspect.all;

/**
 * 

Maintains relationships between entities.

* *

This system is optional and must be manually registered with * the world instance.

* * @see com.artemis.annotations.EntityId * */ @SkipWire public class EntityLinkManager extends BaseEntitySystem { final Bag linkSites = new Bag(); final Bag decoratedLinkSites = new Bag(); private final boolean requireListener; private final boolean fireEventsOnRegistration; /** * @param processSitesEvenIfNoListener * If true, only act on fields with an attached {@link LinkListener}. * @param fireEventsOnRegistration * If true, */ public EntityLinkManager(boolean processSitesEvenIfNoListener, boolean fireEventsOnRegistration) { super(all()); this.requireListener = !processSitesEvenIfNoListener; this.fireEventsOnRegistration = fireEventsOnRegistration; } /** * Processes all fields, even if they don't have a {@link LinkListener}. * LinkListener events will be fired when the listener is registered. */ public EntityLinkManager() { this(true, true); } @Override protected void initialize() { LinkCreateListener listener = new LinkCreateListener(this); world.getComponentManager().getTypeFactory().register(listener); } @Override protected void processSystem() { if (requireListener) { process(decoratedLinkSites); } else { process(linkSites); } } private void process(Bag sites) { for (LinkSite ls : sites) { ls.process(); } } /** *

Injects and associates the listener with the component. This method * is only recommended if only a single field references entities, or if all entity * fields are of the same type.

* *

Each ComponentType::Field pair can only have one {@link LinkListener}

* * @param component component type associated with listener * @param listener link listener */ public void register(Class component, LinkListener listener) { register(component, null, listener); } /** *

Injects and associates the listener with a specific field for a given * component type.

* *

Each ComponentType::Field pair can only have one {@link LinkListener}

* * @param component component type associated with listener * @param field target field for listener * @param listener link listener */ public void register(Class component, String field, LinkListener listener) { world.inject(listener); try { Field f = (field != null) ? ClassReflection.getDeclaredField(component, field) : null; ComponentType ct = world.getComponentManager().getTypeFactory().getTypeFor(component); for (LinkSite site : linkSites) { if (ct.equals(site.type) && (f == null || site.field.equals(f))) { site.listener = listener; if (!decoratedLinkSites.contains(site)) decoratedLinkSites.add(site); if (fireEventsOnRegistration) site.inserted(site.subscription.getEntities()); } } } catch (ReflectionException e) { throw new RuntimeException(e); } } private static class LinkCreateListener implements ComponentTypeFactory.ComponentTypeListener { private final EntityLinkManager elm; private final LinkFactory linkFactory; public LinkCreateListener(EntityLinkManager elm) { this.elm = elm; this.linkFactory = new LinkFactory(elm.getWorld()); } @Override public void initialize(Bag types) { for (int i = 0, s = types.size(); s > i; i++) { onCreated(types.get(i)); } } @Override public void onCreated(ComponentType type) { Bag links = linkFactory.create(type); if (links.isEmpty()) return; for (int i = 0, s = links.size(); s > i; i++) { elm.linkSites.add(links.get(i)); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy