Custom data to ItemStacks

I have been trying last few hours to give custom data to ItemStacks without any luck. I have tried to register new key called “ClickHandler” to easily provide class to handle the item click action but when I try to offer the key to ItemStack it fails. This should be possible, right?

Code: https://gist.github.com/isokissa3/1ef2664b8cc75bac71502a650bd39418

Side note: definitely recommend using the AbstractSingleData as it will save you a lot of hassle with the data manipulators.

Anyway, the issue I see is (ClickHandler)container.get(KeyUtils.CLICK_HANDLER.getQuery()).get()

You need to use the data specfic getter - getSerializable(KeyUtils.CLICK_HANDLER.getQuery(), ClickHandler.class). Make sure that ClickHandler also implements DataSerializable and has an associated DataBuilder. Alternatively, register a DataTranslator and use getObject() instead.

Additionally, Sponge.getRegistry().getValueFactory().createValue(KeyUtils.CLICK_HANDLER, null, this.handler).asImmutable(); has the wrong order of parameters. It’s actual value first, then default second.

Moved to use AbstractSingleData and done everything you said but I’m still unable to get it working :frowning:

Code: https://gist.github.com/isokissa3/4aa3d042179ee48180c39b724bd35306

return new MemoryDataContainer().set(DataQueries.CLICKHANDLER_CLASS, this)

Yeah that isn’t going to work at all. At best you’ll end up with a string identifier for the object instance.

The point of toContainer() is to “deconstruct” a serializable into primitives (string, int, etc) and collections (List and Map). You’ll either need to save an ID for the clickhandler. If you make the handler class a CatalogType you can use the methods in DataManager to register and fetch an instance by string ID.

Optional.of(container.getSerializable(DataQueries.CLICKHANDLER_CLASS, ClickHandler.class).get());

It’s a cyclic reference - your ClickHandler builder is trying to get the ClickHandler builder. deserialize, as mentioned above, needs to construct an object from its more basic parts.

As for why it won’t apply to an ItemStack, I assume that it’s because you’re using the Key based methods (some example code would be good).

Basically, a quirk of custom data is that the Key-based methods need a datamanipulator to already exist on the holder. I assume in this case that it does not.

The point is that the class is avaible only on runtime and after the player disconnets the item is lost

Unfortunately you’ll have to figure a way to serialize the clickhandler that results in primitive and collections objects - otherwise there’s simply no way to persist the data across restarts.

I want the class is avaible on RUNTIME, I could care less if the data is lost on restart or when player disconnets

I figured it out! I need use itemData method instead of add to provide custom data. Also thanks for help @ZephireNZ