-
Notifications
You must be signed in to change notification settings - Fork 10
ComponentRegistry
ComponentRegistry is the parent handler of Component
. When scanning through Component, it will search existing ComponentRegistry to find which ComponentRegistry accepts it. It will only accept Component object that are instance of one of the class in a list where you provided. after accepted, the Component will be completely managed by ComponentRegistry, including constructing, onEnable, onDisable etc.
Before creating registry, you should define a class that this registry accepts. Here's some example:
In this example, it will be an expand from Service
's example. We want to add a DataChecker system for ExampleService where it verifies the data got added is valid. and for maximum flexibility, we want an easier way to add more DataCheckers. In this case the Component system will fit the case perfectly.
package io.fairyproject.examplePlugin;
import java.util.UUID;
public interface DataChecker {
boolean verify(UUID uuid, String data);
}
The acceptable class can be either abstract class or interface, BUT shouldn't be final class that cannot be extend/implemented
After defining the acceptable class, We want to register the Registry in order to accept it and made it working. To create a Registry, you will need to create an instance of io.fairyproject.container.ComponentHolder
.
There are two ways you can do it.
1. Builder Pattern
io.fairyproject.container.ComponentHolder componentHolder = ComponentHolder.builder()
.type(CLASS.class)
.onEnable(obj -> {
// On instance enabled
})
.onDisable(obj -> {
// On instance disabled
})
.build();
2. Class Pattern
io.fairyproject.container.ComponentHolder componentHolder = new ComponentHolder() {
@Override
public Class<?>[] type() {
return new Class[] { CLASS.class };
}
@Override
public void onEnable(Object obj) {
// On instance enabled
}
@Override
public void onDisable(Object obj) {
// On instance disabled
}
};
After having ComponentHolder, you can use io.fairyproject.container.ComponentRegistry.registerComponentHolder(componentHolder)
to register it.
In our example we will be using Builder Pattern.
So for our example, we want to accept DataChecker in our registry, and storing the Component instance somewhere so we can iterate through whenever a data is adding in. So here is the example code:
package io.fairyproject.examplePlugin;
import io.fairyproject.container.ComponentHolder;
import io.fairyproject.container.ComponentRegistry;
import io.fairyproject.container.PostInitialize;
import io.fairyproject.container.PreInitialize;
import io.fairyproject.container.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Service
public class ExampleService {
private Map<UUID, String> dataByUuid;
private List<DataChecker> dataCheckers; // The list of DataChecker instances we are storing
private UUID mainUuid;
// We are doing it on PRE_INIT state.
// This is very important, we will explain after
@PreInitialize
public void onPreInitialize() {
final ComponentHolder componentHolder = ComponentHolder.builder()
.type(DataChecker.class) // We accepts DataChecker here, but note that it support multiple types
.onEnable(obj -> this.dataCheckers.add((DataChecker) obj)) // Add the instance into list on Enable
.onDisable(obj -> this.dataCheckers.remove((DataChecker) obj)) // Remove the instance from list on Disable
.build();
ComponentRegistry.register(componentHolder);
}
...
Component Registry must be registered before Components initialization, otherwise when Component getting intialize it couldn't find an acceptable registry for it. That's why in the example above, we are registering in
PRE_INIT
state.
After everything above, you've done the basic setup for ComponentRegistry, now you can start creating component for your registry!
Detailed Component Explaination
package io.fairyproject.examplePlugin;
import io.fairyproject.container.Component;
import java.util.UUID;
@Component
public class ExampleDataChecker implements DataChecker {
@Override
public boolean verify(UUID uuid, String data) {
return data.equals("example");
}
}
Now we can start iterate through the components we've registered!
public void add(UUID uuid, String data) {
// Iterate through data checker list
for (DataChecker dataChecker : this.dataCheckers) {
if (!dataChecker.verify(uuid, data)) {
throw new IllegalArgumentException("Failed to pass Data Checker " + dataChecker.getClass().getSimpleName());
}
}
this.dataByUuid.put(uuid, data);
}
And after all of these, when we try to do ExampleService.add(uuid, "example")
, if you received IllegalArgumentException, that means it registered successfully!
- UHC's Scenarios
- AntiCheat's Checks
- and even more similar structures!