3
votes

Is there anyway to automatically generate a companion object for every subclass of a certain class?

For example, I have a class Component[T] which has a val companion: CompType[T] where T should be the subclass. For example: class Transform extends Component[Transform].

Is there any way at all to have the companion objects for each subclass to be generated - petty though it seems - to save typing out the object definition for every kind of Component I make?

EDIT:

The end goal of all this is an entity-system. Each companion object has a unique integer (that it gets from an inherited trait) that can be used to look up a component of that specific type from an array of components. So for example, if I want to add a Transform component to an entity, I would call:

addComponent(entity, Transform, new Transform(params))

The new Transform object would then be placed in the array of components representing the entity at the index provided by the Transform companion object. But since the companion objects get their indices from the trait they inherit, there is no typed-out difference between any of them apart from their names. Hence why it would be nice to have them generated.

Sorry for not being more specific to begin with. If this is still confusing, it may well be that I'm just doing this the complete wrong way! Feel free to tell me that if you think so.

2
What would these companion object contain? What do you need them for?Paul Butcher
Sorry I really should have mentioned that. I wanted to keep the question relatively short. I'll edit and add more detail.Mistodon

2 Answers

4
votes

I don't think that there's any way to automatically generate companion objects in Scala as it currently stands. The upcoming macro type support might help you eventually, but that's still in development.

If I understand you correctly, the companion object only exists to provide a per-class unique integer? In which case, perhaps something like this would work?

scala> object UniqueNumberProvider {
     |   val numbers = new collection.mutable.HashMap[Class[_], Int]
     |   def numberForClass(clazz: Class[_]) = numbers.get(clazz) match {
     |     case Some(n) => n
     |     case None => numbers.update(clazz, numbers.size + 1); numbers.size
     |   }
     | }
defined module UniqueNumberProvider

scala> UniqueNumberProvider.numberForClass(classOf[String])
res7: Int = 1

scala> UniqueNumberProvider.numberForClass(classOf[String])
res8: Int = 1

scala> UniqueNumberProvider.numberForClass(classOf[Int])
res9: Int = 2
-1
votes

You can do it using macro in Scala 2.10. You can look for usage at http://docs.scala-lang.org/overviews/macros/overview.html