Cardinal Components API

Cardinal Components API

28M Downloads

Wiki is missing example for ComponentFactory

Ayutac opened this issue ยท 3 comments

commented

I'm still trying to create a barebone component thingy. The wiki says this for registering
excerpt
Now the XFactoryRegistry part is clear, as it is explained below, but there is still the XIntComponent::new part which doesn't make a lot of sense. From my own example, which currently looks like this
excerpt
I get that a fitting component factory is required, but I do not see in the wiki anywhere how one is supposed to look like. If I replace ComponentFactory by PassedTimeCounter::new (with PassedTimeCounter being my implementation of CounterComponent) it doesn't work, IDE says "no instance(s) of type variable(s) exist so that TimeCollectorBlockEntity conforms to PassedTimeCounter". Only thing I can find on Cardinal Components Block site is "Component factories are registered per block entity class, thereby attaching components to all instances of that class and of its subclasses." which tells me nothing about how to do it concretely.

I suppose I am to create an implementation of ComponentFactory, more specifically ComponentFactory<TimeCollectorBlockEntity, CounterComponent>. This only has one method, so I suppose I just write a concrete class as such

PassedTimeCounterFactory<T> implements ComponentFactory<T,CounterComponent> {
    @Override public CounterComponent createComponent(T t) {return new PassedTimeCounter();}
}

Is that correct? If not, please help. If so, please add example to the wiki, because figuring this out takes a lot of time.

commented

Good suggestion, finally added it

commented

Hi, thanks for the detailed issue! Sorry for not answering earlier, I tend to be more reactive on Discord. The ComponentFactory can take many forms, one of which being a concrete class, the others being:

registry.registerFor(TimeCollectorBlockEntity.class, TIME_PASSED, new ComponentFactory<>() {
    @Override public CounterComponent createComponent(TimeCollectorBlockEntity be) {return new PassedTimeCounter();}
});
registry.registerFor(TimeCollectorBlockEntity.class, TIME_PASSED, be -> new PassedTimeCounter());
registry.registerFor(TimeCollectorBlockEntity.class, TIME_PASSED, PassedTimeCounter::new);

They are basically equivalent, but method references require that the constructor have the same signature as the interface, which is why it doesn't work in your case. So basically, you can keep the concrete implementation if you so wish, but I recommend using a lambda expression as it is way shorter to write.

commented

I figured out how to omit the fabric classes with lambda expressions in the mean time. My problem was/is that the wiki didn't contain the examples you just gave. I suggest you add them to this page under point 2