Why Spatial.setUserData requires a Savable?

Spatial.setUserData() allows us to add own custom data to a Spatial. I find this useful for example when resolving collisions, as I need to find out which of my "Entities" corresponds to a Sptial during collision resolving.



However, setUserData(String, Savable) requires a Savable… why? Aren't we supposed to use this for transient data that we wouldn't want to save?



Am I missing something?



As a workaround, I have created a fake Savable class that wraps any kind of object:



import java.io.IOException;

import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.Savable;

public class FakeSavable<E> implements Savable {

   protected E content;


   public FakeSavable() {
      super();
   }

   public FakeSavable(E content) {
      super();
      this.content = content;
   }


   /**
    * @return the content
    */
   public E getContent() {
      return content;
   }

   /**
    * @param content the content to set
    */
   public void setContent(E content) {
      this.content = content;
   }


   @Override
   public Class getClassTag() {
      return null;
   }

   @Override
   public void read(JMEImporter im) throws IOException {
      throw new IOException(this + " cannot be read as it is a fake Savable");
   }

   @Override
   public void write(JMEExporter ex) throws IOException {
      throw new IOException(this + " cannot be saved as it is a fake Savable");
   }

}

1 Like

I guess you need it because Spatial itself implements Savable, which requires that all objects within can be saved as well. I suppose if you're using this to store transient data then using your fake savable class would work fine  :slight_smile: you should probably remove the exceptions as you wouldn't be able to export your models with BinaryExporter.

Thank you for the insight. I renamed it to TransientSavable.



(I suspect that anyway I have no way to avoid the UserData property being created with a TransientSavable that holds no object, so I will get NPE after reading anyway).