[Java reflection question] Playing with a general inventory class

I’m experimenting with an inventory class. One of the key components is a hashmap with Class objects as keys.



Below a simple example, working on something called a SlotGroup. What they do is not important. SlotGroups are supposed to be unique for each inventory, however, so there can not be more then one of SlotGroup_N etc.



[java]

public class Inventory {



protected HashMap<Class<? extends SlotGroup>, SlotGroup> slotGroups;



public InventoryObj() {

slotGroups = new HashMap<Class<? extends SlotGroup>, SlotGroup>();

}



public <T extends SlotGroup> T getSlotGroup(Class<T> clazz) {

return clazz.cast(slotGroups.get(clazz));

}



public <T extends SlotGroup> void addSlotGroup(Class<T> clazz) {

if (!slotGroups.containsKey(clazz)) {

try {

slotGroups.put(clazz, clazz.newInstance());

} catch (InstantiationException ex) {

Logger.getLogger(InventoryObj.class.getName()).log(Level.SEVERE, null, ex);

} catch (IllegalAccessException ex) {

Logger.getLogger(InventoryObj.class.getName()).log(Level.SEVERE, null, ex);

}

}

}

}

[/java]



Just curious if someone is using a similar approach for something and have input.

So kinda like diablo ? fixed slots for like helm, weapon ect? I assume?



Well in my system every slot is the same basic object, however i can set a itemclass as a restrictor. After that only items of that class are allowed.

(Items have a abstract method get Type that must return one from the Enum.)



This way i can circumvent reflection logic in the inventory.

Yeah, not sure why the slot groups need to be n subclasses and can’t just be one class with a shared strategy object (like an enum or something). And in that case, you’d pass the strategy object to the addSlotGroup instead of the class.

An EnumMap might work well here. There is a potential complication though. For example a lot of inventory systems allow two different rings to be worn - so inventory type Ring can be worn twice…

In my games it will work kind of like diablo I guess, but this is not really a character inventory, just a general way of grouping things. Could be used for any kind of stuff. The way i plan on using it is to “group groups” of game items. Since there are vehicles and towers and stuff in my game, a basic “paperdoll” isn’t enough. I need to make custom inventories.



The groups aren’t equipment slots, like in Diablo, but more of a way to group equipment slots by their functionality, and not based on if they’re weapons or w/e. A cannon for example has a spatial that needs to be attached, and there needs to be a node and a transformation etc. It is placed in a group of NodeBackedSlot slots. A turret with one cannon on it, for example, would have one slotgroup, with one slot in it for a cannon.



The equipment slots themselves will work somewhat like you describe tho, checking if the item is a “cannon” or w/e, before allowing things to be placed in them.



Is using reflection like this such a big deal? The newInstance() happens only when new inventories are made (when new objects with inventories are made, basically), and it’s safe. Seen this used by programs, thought I’d give it a try.

The newInstance() happens only when new inventories are made (when new objects with inventories are made, basically), and it’s safe. Seen this used by programs, thought I’d give it a try.


I've no idea if this helps, but posting anyways ^_^, something i've used before:

[java]public enum MonkeyControl {

LOOK_AT(LookAtControl.class),
SET_TO_CAM(MainCharacterControl.class),
BOB_CONTROL(BobControl.class);

private Class<? extends BaseControl> clazz;

MonkeyControl(Class<? extends BaseControl> control) {
clazz = control;
}

public <T extends BaseControl> T createControl() {
try {
return (T) clazz.newInstance();
} catch (Exception ex) {
ex.printStackTrace();
}

return null;
}

public Class<? extends BaseControl> getClazz() {
return clazz;
}
}[/java]
@androlo said:
In my games it will work kind of like diablo I guess, but this is not really a character inventory, just a general way of grouping things. Could be used for any kind of stuff. The way i plan on using it is to "group groups" of game items. Since there are vehicles and towers and stuff in my game, a basic "paperdoll" isn't enough. I need to make custom inventories.

The groups aren't equipment slots, like in Diablo, but more of a way to group equipment slots by their functionality, and not based on if they're weapons or w/e. A cannon for example has a spatial that needs to be attached, and there needs to be a node and a transformation etc. It is placed in a group of NodeBackedSlot slots. A turret with one cannon on it, for example, would have one slotgroup, with one slot in it for a cannon.

The equipment slots themselves will work somewhat like you describe tho, checking if the item is a "cannon" or w/e, before allowing things to be placed in them.

Is using reflection like this such a big deal? The newInstance() happens only when new inventories are made (when new objects with inventories are made, basically), and it's safe. Seen this used by programs, thought I'd give it a try.


It's not bad. It's just weird in this case. The caller must know the class so why can't is just pass the instance of it instead of you doing reflection?

Have a look at how eve online does their fittings, it sounds like a similar concept.

@pspeed

Ah, it is very clear what you mean now, thank you.



@zarch too, and others.



I wanna be a bit more specific, now that this thread is still going etc.



The problem now is basically this - I want to create an inventory by dividing inventory slots into groups, and make the inventory object into a collection of those groups. Each group contains a collection of a type of slot, and some other data. Like those ring slots you mention zarch would be one group, and it would contain two slots that only allows rings in them.



This would be less efficient then hard-setting the inventory slots I suppose, but that would require a crapload of inventory permutations etc. This will add the possibility to make tiny inventories when needed, as well as larger ones. And they could be completely tailor made.



I guess making each group an object with a strategy that can be replaced is the best way to go. Maybe just make the inventory an arraylist of those objects then, and put a member into the group class that identifies it as holder of certain types of slots. Or use a hashmap and put that identifyer into enums to use as keys. Doesn’t really matter as even tho the amount of actual slots may add up to a lot, the number of different groups will still be insignificant (like 10-15 different items perhaps).



What y’all think?



Btw, the entire idea behind the reflection stuff was to avoid having to use flags like this, but instead identify each group by its type. Just didn’t think it through.

@zarch

Ok good tip, thanks.