Question/Observation/Suggestion Re: User Data and Enums

I noticed that you can’t set enums as user data. Is this a feature that might be useful or I have I misunderstood what user data is for.



(In case it isn’t clear, say you have

[java]

public enum Team {

GOODIES,

BADDIES

}

[/java]



and then somewhere you try



[java]

aSpatial.setUserData(“Team”, Team.GOODIES);

[/java]



it doesn’t work.

User data must implement the Savable interface or a one of the following types : Integer, Float, Long, String, Boolean. The latter will be embed in an UserData object that implements Savable.



So in your case you’d better embed your enum in an object or just go something like myVar = Team.valueOf(“someString”);

Yeah, I ended up just sticking it in a control that every spatial was going to have anyway, Not a huge problem. Might change it to store an int using valueOf() or ordinal(). Just thought it might be useful since enums are essentially ints

enums aren’t ints, at least not in Java, they are much more powerful. And never use valueOf() or ordinal () as Joshua Bloch explains

@wezrule said:
enums aren't ints, at least not in Java, they are much more powerful. And never use valueOf() or ordinal () as Joshua Bloch explains


To be fair, he said "essentially ints". I agree, though, that treating them like ints is generally a bad idea.

Still, JME supports some primitives... I suppose technically it could support enums, too. Actually, I found it kind of painful that it supports Float and no Double... the whole thing could probably use a once-over, I guess.
1 Like

ok, I thought he was trying to compare them to C enums. And Yeh enums inside the userdata would be useful

I think the enum can just implement Savable, doesnt seem to be a problem. right?

You can’t create a new instance of enums so you can’t load them after they are saved(in j3o or what ever). If you just want to use them at the runtime as user data I think there will be no problem in that.

well, enums have toString and fromString alike, so it would be possible to save it somehow as String, but it would NOT be nice solution.

I am using it currently. The problem is when you have an enum>Savable map :sweat: . You can’t even save a String>Savable map or any primitive. So, I wrote the map keys as string and values each one with its index appended at the end of its name. Really ugly solution.

The problem with enums is that there is no safe way to save/load them from j3o.

If you want to support a map of enums as a user data then a) you may be abusing user data, b) you could always write a custom savable class that has the map as a parameter and then do your own save/loading. (Or if you never plan to save/load then just stub those methods out.)

JME can’t just stub those methods out.

1 Like

You absolutely can have enums in user data. I have been using this UserData object for years as an example.

public class AssetInfo implements Savable, Cloneable, java.io.Serializable
{
	String name;

public String getName()
{
	return name;
}

public void setName(String name)
{
	this.name = name;

}

@Override
public Object clone() throws CloneNotSupportedException
{
	AssetInfo info = new AssetInfo();
	info.name = name;
	info.type = type;
	return info;
}

public static enum Type
{

	OrbitalPath, Orbit, SolarSystem
	{
		public String getLabel()
		{
			return "Solar System";
		}
	},
	Planet, Star, Astroid, Fleet, Ship, Raw,

	Weapon, Shield, SpaceStation
	{
		public String getLabel()
		{
			return "Space Station";
		}
	},
	Sector, CameraNode
	{
		public String getLabel()
		{
			return "Player's Camera";
		}
	},

	ShipTemplate
	{
		public String getLabel()
		{
			return "Ship Template";
		}
	},

	UNKNOWN;

	public String getLabel()
	{
		return toString();
	}
}

private Type type = Type.UNKNOWN;

/**
 * @return the type
 */
public Type getType()
{
	return type;
}

/**
 * @param type
 *            the type to set
 */
public void setType(Type type)
{
	this.type = type;
}

public AssetInfo()
{
}

@Override
public void write(JmeExporter ex) throws IOException
{
	OutputCapsule out = ex.getCapsule(this);
	out.write(getName(), "n", null);
	out.write(getType(), "t", null);
}

@Override
public void read(JmeImporter im) throws IOException
{
	InputCapsule ic = im.getCapsule(this);
	setName(ic.readString("n", null));
	setType(ic.readEnum("t", Type.class, null));
}

}

Yes, but you can’t call spatial.setUserData(“myCoolData”, SomeEnum.Value1).

You’ve opted for the approach I mentioned in my comment:

1 Like