Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

Capability system flaw


N247S
 Share

Recommended Posts

Hey,

 

Im trying create capabilities dynamically using the new capability system, though I came accros a litle problem.

For the system to work properly I need an instance of the capability which is created after calling:

CapabilityManager.INSTANCE.register();

The thing is that I provide a base structure for the actual Capability itself. meaning the registered Class is always an subInstance of my base structure.

And because of that there is no way to get the instance, since the @CapabilityInject annotation does not support the use of superclasses.

 

So for example if I have an interface called "ICapBase" which people should implement in order to use my system.

If someone implements this interface and register it, there is no way for me to get the capability unless I hardcode that into my system.

because the following doesn't work!

@CapabilityInject(ICapBase.class)
Public static void onInject(Capability<? extends ICapBase> cap)
{}

 

Before I go to Forge's github and make a possible fix, I want to make sure I dont forget something which would solve this problem.

If there isn't any there are 2 fixes:

1. modify the current system so the above code would work.

2. simply return the capability from the #register method (from which I dont understand why that hasn't been done in the first place).

 

anyway, Im looking foreward to your opinion about this.

N247S

Projects:

Discontinued:

- N2ConfigAPI

- Meachanical Crafting Table

 

Latest:

- CollectionUtils

 

Coöperations:

- InGameConfigManager

Link to comment
Share on other sites

I defenitly dont wanna make my own Capability instances. thats whats forge should do for me. though you can use them to get new default instances,

get the IStorage singelton etc. and first and foremost, they are used as identifier in the ICapabilityProvider (getCapability & hasCapbility). So it would help a lot if you can get them without hardcoding an annotation, like I described, via a annotated method or as a return value from the register method.

 

I could go for my own identification/defaultInstance/storage system, though why should I if those mechanics are already there... only unreachable atm..

 

(just to make sure, I register capabilities dynamically, I dont use a general or a hardcoded one!)

Projects:

Discontinued:

- N2ConfigAPI

- Meachanical Crafting Table

 

Latest:

- CollectionUtils

 

Coöperations:

- InGameConfigManager

Link to comment
Share on other sites

Forge doesn't make capability instances, you do that. That's not a flaw in the system, that's simply how it works.

Forge doesn't (and doesn't need to) know about all possible implementations of a capability interface. That's how OOP works, the implementation is hidden.

 

What is your issue with this? I don't get it.

Link to comment
Share on other sites

Erhm.. Im pretty sure Forge is creating an Capability instance in the CapabilityManager#register method, and populating/calling every @CapabilitInject annotated field/method. although its pretty much checking if the 3 passed arguments are not null, and passing those through to the Capability constructor.

 

besides I know how the Capability CLASS(:P) works, the problem is that I need the instance for the ICapabilityProvider/ICapabilitySerializable for nbt writing/reading (and preferably for the 2 checking methods).

 

It all works fine, though the flaw is, that there is no way to get those singleton Capability instances without FailProne reflection or hardcoding a @CapabilityInject a field/method(which I cannot use because of the problem described in the first post).

 

SO just to make it simple. I need an the singelton instance of the Capability stored within the CapabilityManager preferably without reflection.

Is there a way to do so? if not, Ill use reflection for now.

 

thanks for the replies!

Projects:

Discontinued:

- N2ConfigAPI

- Meachanical Crafting Table

 

Latest:

- CollectionUtils

 

Coöperations:

- InGameConfigManager

Link to comment
Share on other sites

Erhm.. Im pretty sure Forge is creating an Capability instance in the CapabilityManager#register method, and populating/calling every @CapabilitInject annotated field/method. although its pretty much checking if the 3 passed arguments are not null, and passing those through to the Capability constructor.

Oh you are talking about the actual
Capability

object. Yes, that is true.

besides I know how the Capability CLASS(:P) works, the problem is that I need the instance for the ICapabilityProvider/ICapabilitySerializable for nbt writing/reading (and preferably for the 2 checking methods).

What?

If you are providing a capability you know all about it. You have written the implementation, you ensure the storage.

It all works fine, though the flaw is, that there is no way to get those singleton Capability instances without FailProne reflection or hardcoding a @CapabilityInject a field/method(which I cannot use because of the problem described in the first post).

Like I said, your users would not register a capability. There is the capability with your base interface and then users can provide their implementation. If there is a sub-interface that anyone needs to know about, then they can register that as a separate capability and everyone who knows about it can use @CapabilityInject.

SO just to make it simple. I need an the singelton instance of the Capability stored within the CapabilityManager preferably without reflection.

Is there a way to do so? if not, Ill use reflection for now.

@CapabilityInject (technically that also uses reflection, but that doesn't count).
Link to comment
Share on other sites

Alright, so I assume that there is no 'normal' way to get the Capability object instance wihtout hardcoding stuff, too bad. Anyway Im going to rely on reflection. And just like the Capability injection does, I'll try to work around doing that during performance sensitive operations.

 

Thanks for your help!

Hope they add a simple getter for this in the future

 

Btw, just to make sure, the net.minecraftforge.* part of the Forge library doesn't use deobfuscated names right?

 

N247S

Projects:

Discontinued:

- N2ConfigAPI

- Meachanical Crafting Table

 

Latest:

- CollectionUtils

 

Coöperations:

- InGameConfigManager

Link to comment
Share on other sites

Alright, so I assume that there is no 'normal' way to get the Capability object instance wihtout hardcoding stuff, too bad. Anyway Im going to rely on reflection. And just like the Capability injection does, I'll try to work around doing that during performance sensitive operations.

I still have not grasped why.
Btw, just to make sure, the net.minecraftforge.* part of the Forge library doesn't use deobfuscated names right?
You mean obfuscated. No, forge code itself does not get obfuscated, unless of course it is calling Minecraft code. It behaves like your mod code does.
Link to comment
Share on other sites

You're doing it wrong this is designed for the API provider to expose an interface. Simple as that.

Sub-interfaces are separate capabilities. Deal with it. If the provider wants to support both your capability and some sub-cap of it they can simply do:

if (CAP == PARENT_CAP || CAP == CHILD_CAP) return (T)MyCap;

Whatever the hell you're doing {you still haven't explained why your consumers are creating sub-caps} is wrong, you should stop doing it. The flaw is not in the cap system it's in your understanding.

And you need to stop just "fuck it i'll hack the system because i dont know what im doing and cant explain/understand why the system was designed as it is"

 

Ya, looking at your 'MCIndicators' mod on github your concept is completely wrong, you're trying to wrap the capability system into something it isn't for.

What you WANT is to make a IIndicatorList that gathers all the 'indecators' instead of having people go through the capability system.

 

 

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Patreon: http://www.patreon.com/lexmanos
Paypal: http://paypal.me/LexManos

BitCoin: 1Q8rWvUNMM2T1ZfDaFeeYQyVXtYoeT6tTn

Link to comment
Share on other sites

@LexManos , I am suprised you looked the MCIndicators up. and yea, its a total mess wich I already have redesigned but not pushed yet.

The main problem is that generics involvement is giving problems when registering a universal capability object.(because of the Class<T> parameter)

I tried to solve it by dynamically registering a capability per indicator, wich should give less problems (especially with the getDefaultInstance() thingy).

But I have tried to work that out a litle bit more, and technically it should work although it doesnt feel right to me. (pretty messy, and fail prone)

So I propably will go for a central wrapper object, and take the extra synchronizing of non changed values instead.

I hoped that I could exploit the @CapabilityInject Annotation mechanism which is a pretty cool feature in my opinion.

 

Anyway thanks for your comment!

N247S

Projects:

Discontinued:

- N2ConfigAPI

- Meachanical Crafting Table

 

Latest:

- CollectionUtils

 

Coöperations:

- InGameConfigManager

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.