Instead of directly setting position and orientation we've now
added a "transforms" property. This property contains zero or many
transformations. The result of these is what drives changes to an
entity's position and orientation.
By cleanly separate disrete transformations we can more easily undo
or alter them. This allows us to do things where the position or
orientation of an entity is affected by other properties, or other
entities.
The client protocol is intact. Changes to position and orientation is
still sent the same way, by specifying "pos" and "orientation". However,
these values will now not be written directly to corresponding values on
the entity. Instead they will first be written to the "transforms" property,
with the final values being a result of combining all data in the property.
In some cases you want to store property data for each instance. Often
you'll use member data on the entities themselves for this. But in some
cases you don't want to bloat the entity class with data for seldomly
used properties.
In these cases you can instead use the PropertyInstanceState class, and
keep a static instance of this per property.
This is a rather big change for the protocol, but by now there shouldn't
be any clients left that can't handle this.
Basically, since the client already has the type and knows the default
properties from that, there's no need to resend them for each entity.
This should decrease the amount of data needed to be sent from the
server.
Note that there might be some lingering issues with the AI code; that
has to be investigated further.
Previously we only allows one delegate per operation. The one that was
installed first was called; all subsequent were ignored. This doesn't
work well with how we're moving to putting more and more functionality
in properties though, so we'll have to allow for multiple delegates per
operation.
I'm not entirely happy of how this currently works. We now just call all
of the delegates, in stochastic order. If any delegate blocks the
operation it doesn't prevent other delegates from getting it too.
But perhaps that's the only way to do it without adding additional
complexity.
Collision detection should fully be handled by the domain, as should
sight checking.
The plan is to let the domain keep a separate structure of all collision
geometry, optimized in something like a quad or oct tree. Since the vast
majority of geometry is static, in the sense that it very seldom moves,
the Domain should keep a flat representation of all geometry, with
precomputer meshes for fast lookup.
Similarily it should keep a separate structure, or structures, for sight
checks.
And it should of course also use Bullet for collision detection.
The relay mechanism, through the new internal Relay operation, allows
one external client to relay an operation to another external client,
and get the response back.
This can currently only be used by Creator clients. It's main use is for
mind introspection.
All IG code should use the interface of LocatedEntity when dealing
with any entity, rather than sometimes requiring Entity. Add virtual
functions to the interface where required, and modify all other interfaces
to stop them using Entity. This makes the code way cleaner, and much better
de-coupled.
In the case where the property is already in defaults, it is cheaper to
use copy to avoid the lookup overhead of PropertyManager, and it is
already necessary to check the defaults to determine whether install()
is called.
The Link reference provided is the object allowing direct communication
back to the external source of the operation. This allows us to handle
things more cleanly in some cases.
The C++ object representing this object may persist for a while as we
need it later for broadcasting ops from it as it was destroyed. Ops
in the queue from it will also hold a reference. The Python object should
be deleted right away though, as nothing else should hold a reference, and
things with weak references should find out immediately that it is gone.
* common/Identified.cpp, common/Identified.h:
Flatten down the base classes into one called Router.
* client/CharacterClient.cpp, client/CreatorClient.cpp,
rulesets/BaseMind.cpp, rulesets/Character.cpp,
rulesets/Creator.cpp, rulesets/Entity.cpp,
rulesets/LocatedEntity.cpp, rulesets/MemEntity.cpp,
rulesets/Plant.cpp, rulesets/Stackable.cpp,
rulesets/Thing.cpp, rulesets/World.cpp,
server/Account.cpp, server/Admin.cpp,
server/Connection.cpp, server/ExternalMind.cpp,
server/Lobby.cpp, server/Master.cpp,
server/Peer.cpp, server/Player.cpp,
server/ServerRouting.cpp, server/SlaveClientConnection.cpp,
server/TrustedConnection.cpp, tests/LocatedEntitytest.cpp,
tests/ThingupdatePropertiestest.cpp: Update all the operation
routing classes to use the modified base class correctly.