Skip to content

The ArrowRegistry (Beyond Registration)

Parker Hawke edited this page Sep 28, 2018 · 2 revisions

The ArrowRegistry (Beyond Registration)

The ArrowRegistry is the most powerful features in AlchemicalArrows 3, though it's used primarily for internal registration, handling of in-world entities and mapping them to their alchemical representations. While it may be an internal registration class, it is available for use and provides some useful methods with regards to the registration and manipulation of existing arrows.

Retrieving an Instance

Yes, the ArrowRegistry does have static methods to register, unregister and retrieve AlchemicalArrow implementations, but there are also a bunch of non-static methods related to the interaction of in-world arrows. Because they are not static, an instance of the registry is required. No, this registry is not a singleton, but the AlchemicalArrows class does have a method to retrieve an instance of it!

public class MyPlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        AlchemicalArrows alchemicalArrows = AlchemicalArrows.getInstance();
        ArrowRegistry registry = alchemicalArrows.getArrowRegistry();
    }

}

From there, you have an instance of the registry. If you plan on using this object more than once in various different places, it's recommended that the instance is held in a field in your main class.

Interacting with AlchemicalArrowEntities

Below are some of the methods available in the ArrowRegistry to interact with the AlchemicalArrowEntity instances in the world.

public void addAlchemicalArrow(AlchemicalArrowEntity)

public AlchemicalArrowEntity getAlchemicalArrow(Arrow)
public AlchemicalArrowEntity getAlchemicalArrow(UUID)
public Collection<AlchemicalArrowEntity> getAlchemicalArrows()

public boolean isAlchemicalArrow(Arrow)
public boolean isAlchemicalArrow(UUID)
public void clearAlchemicalArrows()

// Discussed later
public void removeAlchemicalArrow(AlchemicalArrowEntity)
public void removeAlchemicalArrowEntity(Arrow)
public void removeAlchemicalArrowEntity(UUID)
public int getArrowsToPurge()
public void purgeArrows()

Most of these methods are rather self-explanatory, but methods worth noting are those in the second and third section (the fourth as well, but these will be covered shortly). With these methods, instances of AlchemicalArrowEntity may be retrieved such that an Arrow or UUID is provided. Additionally, you may get an immutable collection of all entities currently in the world. Lastly, some simple checks to determine whether an arrow is alchemical or not and the clearing of the registry. It is discouraged to clear the registry during runtime, but if absolutely necessary, the method is available.

Arrow Removal and Purging

You will have noticed that 5 methods all relating to the removal of arrows were separated from the other methods in the ArrowRegistry. The reasoning for this is because arrow removal had to be handled particularly in order to avoid concurrency issues. When you call one of the #removeAlchemicalArrow(...) methods, the arrow is not removed from the world instantaneously as expected. It is instead flagged as invalid and awaits to be purged before removal.

Internally, AlchemicalArrows iterates over every single registered arrow in the world in order to execute its #tick() method to update the arrows. If the arrows were removed directly from the registry, a ConcurrentModificationException would be thrown causing the plugin to malfunction. Instead, they are flagged for removal if invalid and purged internally after iteration has completed. If you wish to invoke purgeArrows() yourself to remove arrows from the world, know that it comes with the risk of throwing a ConcurrentModificationException. Avoid purge methods at all costs. It will be invoked internally by the AlchemicalArrows 3 update task.