Posted September 23, 201510 yr I add a public boolean field to PotionEffect via ASM and I wanted to know how can I access that field while writing my code. Do I need reflection? WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons
September 23, 201510 yr Author Both solutions sound good. when you say reflection you mean that unreflected getter/setter thing you taught me using MethodHandle and invokeExact, right? WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons
September 23, 201510 yr no need to do that. if u make the clas implement ur interface via asm u can just cast to it and call the getter and setter. should be performance saving
September 23, 201510 yr Author This is what I did, according to the teachings of diesieben07 /* in my actual code, the methods here span 3 classes that contain other methods and stuff, I simplified the code for clarity * (hopefully) putting all relevant methods to this use case together here and changing the names of some identifiers for * readability. Because of that, something may have broke, because I'm doing theses edits directly in the textArea of this reply. */ private final static MethodHandle myFieldGetter = createGetterForField(PotionEffect.class, "gw_myField", "gw_myField"); private final static MethodHandle myFieldSetter = createSetterForField(PotionEffect.class, "gw_myField", "gw_myField"); public static MethodHandle createGetterForField(Class c, String forgeFieldName, String srgFieldName) { String fieldName = isDeobfEnvironment() ? forgeFieldName: srgFieldName; Field field = null; try { field = c.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { // TODO this is unlikely to happen; } catch (SecurityException e) { // TODO this is unlikely to happen; } field.setAccessible(true); try { return MethodHandles.publicLookup().unreflectGetter(field); } catch (IllegalAccessException e) { return null; } public static MethodHandle createSetterForField(Class c, String forgeFieldName, String srgFieldName) { Field field = null; String fieldName = FMLHelper.isDeobfEnvironment() ? forgeFieldName: srgFieldName; try { field = c.getDeclaredField(fieldName); } catch (NoSuchFieldException e) { } catch (SecurityException e) { } field.setAccessible(true); try { return MethodHandles.publicLookup().unreflectSetter(field); } catch (IllegalAccessException e) { return null; } } public static void setMyField(PotionEffect instance, boolean value) throws Throwable { myFieldSetter.invokeExact((PotionEffect)instance, value); } public static boolean getMyField(PotionEffect instance) throws Throwable { return (boolean) myFieldGetter.invokeExact((PotionEffect)instance); } public static boolean isDeobfEnvironment() { return (Boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment"); } WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons
September 23, 201510 yr Author Yes, I agree, that's a very good point. I usually end up ignoring a few when coding. In my real code I log those marked as "TODO" in this example. I just didn't want to clutter the solution with anything non essential. I was going to write something similar to your advice in the TODO comment, but I chose that short comment instead for simplicity. WIP mods: easyautomation, easyenergy, easyelectronics, easymoney, easytrasportation, easysecurity, easymultiverse, easyfactions, easymagick, easyalchemy, easyseasons
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.