For the match on Option[Entity] below, a third case is required to be exhaustive. Why ?
entitiesMap is a var containing an immutable Map[UUID,Entity]. It is accessed and updated within a single Akka Actor to avoid threading issues. Here is an excerpt of the receive function:
class WorldActor extends Actor {
var world: World = null
override def receive = {
case WorldSet(w) =>
world = w
// get that state and apply it to its entity
case s: State if (world != null) =>
val uuid = new UUID(s.getUuid().getL1(), s.getUuid().getL2())
world.entitiesMap.get(uuid) match {
case Some(ent) =>
// Update entity's state
ent.setEntityState(s)
case None =>
Log.error("World doesn't contain entity uuid: " + uuid)
case other =>
Log.error("Received unknown message: " + other)
}
case AddEntity(ent) if (world != null && ent != null) =>
if (!world.entitiesMap.contains(ent.uuid))
world.entitiesMap += ent.uuid -> ent
case RemoveEntity(ent) if (world != null && ent != null) =>
if (world.entitiesMap.contains(ent.uuid))
world.entitiesMap -= ent.uuid
case other => // ignore
}
}
class World {
// Entity container
var entitiesMap = Map[UUID,Entity]()
}
From time to time, the above code reports:
Received unknown message: None
Why doesn't the case None pattern just above catch it ?
EDIT
I found the bug occurs when message State comes just before message AddEntity, that is, when entitiesMap doesn't yet contain the Entity refered to by message State.
01:52 ERROR: [State] Received unknown message: None
uuid: 1b234d30-92ae-11e3-aa12-7071bcb09717
Thread: 152
01:52 ERROR: [State] Received unknown message: None
uuid: 1b234d30-92ae-11e3-aa12-7071bcb09717
Thread: 32
01:52 INFO: [AddEntity] 1b234d30-92ae-11e3-aa12-7071bcb09717: Cube@2f9c3beb
Thread: 152
Could this be a threading problem after all ? Within an Actor ?
EDIT 2
Following the suggestion of a poster below, I have logged the class names, class loaders reference and class file paths for both other and None. They're all the same.
EDIT 3
other == None is false
other.eq(None) is false
other.equals(None) is false
other.hashCode == None.hashCode
System.identityHashCode(other) != System.identityHashCode(None)