Use milliseconds for all time.

And remove "seconds" in favour of always using "stamp".
This commit is contained in:
Erik Ogenvik 2024-01-03 16:33:07 +01:00
parent 2e537a2fef
commit e598eee88d
133 changed files with 2032 additions and 2340 deletions

View file

@ -9,6 +9,7 @@ def release_mouse (event):
gdb.write("GDB/SDL2: Releasing mouse\n")
try:
gdb.execute("call SDL_SetRelativeMouseMode(0)")
gdb.write("GDB/SDL2: Released mouse\n")
except gdb.error:
pass

View file

@ -174,8 +174,6 @@ to the builder, and the PropertyFactories to the CorePropertyManager. Then
both those can be made independant of server. It could also handle all the
really core types being added to Inheritance.
Is PyCreator/PyCharacter still needed in the client side? It seems to have
been abandoned before being fully introduced.
Add Arithmetic functionality to all scripts. Cos you know.
Add the concept of the Property script in general and use it to replace the
@ -190,8 +188,6 @@ Make it possible to forget
Use "name" as the property that is supposed to get an operation
EntityBuilder shouldn't need a permenent reference to the world.
Allow long cut and cross cut with saws. Long cut is along grain, bisecting by longest dimension. cross cut is across both grains
Sort out a better way to handle materials. We shouldn't have a base class
@ -219,10 +215,6 @@ entities which can create further persistent entities.
Frontends, backends, routers based architecture
Use 64bit milliseconds everywhere. Merge SECONDS and STAMP into a single
attribute. Get rid of FUTURE_SECONDS in favor of things being able to set
STAMP/SECONDS in advance. Use time for STAMP instead of incrementing integer.
Character should inherit from and implement the Agent interface, which
the server code uses when talking to it. This de-couples server from most
of the rulesets directory.

View file

@ -18,7 +18,7 @@ class Chase(DynamicGoal):
def event(self, me, original_op, op):
# FIXME Now that this code is trigger goal, has this update been done?
other = me.map.update(op[0], op.get_seconds())
other = me.map.update(op[0], op.get_stamp())
if other.id == me.entity.id:
return
# target=op[0].location.copy()

View file

@ -1,40 +1,43 @@
<atlas>
<map>
<map name="attributes">
<map name="geometry">
<map name="default">
<string name="path">dural/items/tools/spade/model/spade.mesh</string>
<string name="type">box</string>
</map>
</map>
<map name="present">
<string name="default">dural/items/tools/spade/spade.modeldef</string>
</map>
<map name="density">
<float name="default">2000</float>
</map>
<map name="cooldown">
<float name="default">5</float>
</map>
<map name="usages">
<map name="default">
<map name="dig">
<string name="name">Dig</string>
<map name="params">
<map name="targets">
<string name="type">entity_location</string>
<string name="constraint">entity instance_of types.game_entity &amp;&amp; actor can_reach entity_location with tool</string>
</map>
</map>
<string name="handler">world.objects.tools.GenericTool.use</string>
<string name="constraint">get_entity(actor.attached_hand_primary) = tool</string>
<string name="description">Dig with shovel.</string>
</map>
</map>
</map>
</map>
<string name="id">shovel</string>
<string name="objtype">class</string>
<string name="parent">thing</string>
</map>
<map>
<map name="attributes">
<map name="geometry">
<map name="default">
<string name="path">dural/items/tools/spade/model/spade.mesh</string>
<string name="type">box</string>
</map>
</map>
<map name="present">
<string name="default">dural/items/tools/spade/spade.modeldef</string>
</map>
<map name="density">
<float name="default">2000</float>
</map>
<map name="cooldown">
<float name="default">5</float>
</map>
<map name="usages">
<map name="default">
<map name="dig">
<string name="name">Dig</string>
<map name="params">
<map name="targets">
<string name="type">entity_location</string>
<string name="constraint">describe("Target needs to be in game.", entity instance_of
types.game_entity) &amp;&amp; describe("Can't reach.", actor can_reach
entity_location with tool)
</string>
</map>
</map>
<string name="handler">world.objects.tools.GenericTool.use</string>
<string name="constraint">get_entity(actor.attached_hand_primary) = tool</string>
<string name="description">Dig with shovel.</string>
</map>
</map>
</map>
</map>
<string name="id">shovel</string>
<string name="objtype">class</string>
<string name="parent">thing</string>
</map>
</atlas>

View file

@ -30,16 +30,18 @@ class Operation:
pass
def get_from(self):
pass
def get_future_milliseconds(self):
pass
def get_future_seconds(self):
pass
def get_name(self):
pass
def get_refno(self):
pass
def get_seconds(self):
pass
def get_serialno(self):
pass
def get_stamp(self):
pass
def get_to(self):
pass
def is_default_serialno(self):
@ -50,6 +52,8 @@ class Operation:
def set_from(self, string):
"""Sets from which entity the operation is from."""
pass
def set_future_milliseconds(self):
pass
def set_future_seconds(self):
pass
def set_name(self):
@ -57,11 +61,11 @@ class Operation:
def set_refno(self, long):
"""Sets the reference number."""
pass
def set_seconds(self):
pass
def set_serialno(self, long):
"""Sets the serial number."""
pass
def set_stamp(self):
pass
def set_to(self, string):
"""Sets to which entity the operation is directed."""
pass

View file

@ -26,6 +26,7 @@
#include <Atlas/Objects/Anonymous.h>
#include <Atlas/Objects/Operation.h>
#include <Atlas/Objects/Entity.h>
#include <iostream>
@ -97,12 +98,11 @@ void BaseClient::externalOperation(const Operation& op, Link& link) {
/// @param password Password of the new account
void BaseClient::createSystemAccount(const std::string& usernameSuffix) {
Anonymous player_ent;
Atlas::Objects::Entity::SystemAccount player_ent;
m_username = create_session_username() + usernameSuffix;
player_ent->setAttr("username", m_username);
m_password = fmt::format("{}{}", ::rand(), ::rand());
player_ent->setAttr("password", m_password);
player_ent->setParent("sys");
Create createAccountOp;
createAccountOp->setArgs1(player_ent);

View file

@ -42,8 +42,8 @@ using Atlas::Objects::Root;
using Atlas::Objects::Entity::Anonymous;
using Atlas::Objects::Operation::RootOperation;
long PossessionClient::operations_in = 0;
long PossessionClient::operations_out = 0;
size_t PossessionClient::operations_in = 0;
size_t PossessionClient::operations_out = 0;
PossessionClient::PossessionClient(CommSocket& commSocket,
MindKit& mindFactory,
@ -87,7 +87,7 @@ void PossessionClient::operationFromEntity(const Operation& op, Ref<BaseMind> lo
OpVector res;
//Adjust the time of the operation to fit with the server's time
op->setSeconds(op->getSeconds() - m_serverLocalTimeDiff);
op->setStamp(op->getStamp() - m_serverLocalTimeDiff.count());
processOperation(op, res);
operations_out += res.size();
send(res);
@ -97,23 +97,23 @@ void PossessionClient::operationFromEntity(const Operation& op, Ref<BaseMind> lo
void PossessionClient::operation(const Operation& op, OpVector& res) {
rmt_ScopedCPUSample(operation, 0)
operations_in++;
if (!op->isDefaultSeconds()) {
if (!op->isDefaultStamp()) {
//Store the difference between server time and local time, so we can properly adjust the time of any locally scheduled ops when they are dispatched.
m_serverLocalTimeDiff = std::chrono::duration_cast<std::chrono::duration<float>>(getTime()).count() - op->getSeconds();
m_serverLocalTimeDiff = std::chrono::duration_cast<std::chrono::milliseconds>(getTime()) - std::chrono::milliseconds(op->getStamp());
}
processOperation(op, res);
operations_out += res.size();
}
void PossessionClient::resolveDispatchTimeForOp(Atlas::Objects::Operation::RootOperationData& op) {
if (!op.isDefaultFutureSeconds()) {
if (!op.isDefaultFutureMilliseconds()) {
auto timeNow = std::chrono::steady_clock::now() - m_startTime;
auto timeAsSeconds = std::chrono::duration_cast<std::chrono::duration<float>>(timeNow).count();
double t = timeAsSeconds + op.getFutureSeconds();
op.setSeconds(t);
op.removeAttrFlag(Atlas::Objects::Operation::FUTURE_SECONDS_FLAG);
} else if (op.isDefaultSeconds()) {
op.setSeconds(std::chrono::duration_cast<std::chrono::duration<float>>(getTime()).count());
auto timeAsMilliseSeconds = std::chrono::duration_cast<std::chrono::milliseconds>(timeNow);
auto t = timeAsMilliseSeconds + std::chrono::milliseconds(op.getFutureMilliseconds());
op.setStamp(t.count());
op.removeAttrFlag(Atlas::Objects::Operation::FUTURE_MILLISECONDS_FLAG);
} else if (op.isDefaultStamp()) {
op.setStamp(std::chrono::duration_cast<std::chrono::milliseconds>(getTime()).count());
}
}

View file

@ -48,8 +48,8 @@ public:
void processResponses(const OpVector& incomingRes, OpVector& outgoingRes);
static long operations_in;
static long operations_out;
static size_t operations_in;
static size_t operations_out;
protected:
@ -86,7 +86,7 @@ protected:
* This is needed when scheduling operations locally. When they are later dispatched
* their "seconds" needs to match the time it would be on the server.
*/
double m_serverLocalTimeDiff;
std::chrono::milliseconds m_serverLocalTimeDiff;
};

View file

@ -291,8 +291,8 @@ int main(int argc, char** argv) {
monitors.watch("accounts", PossessionAccount::account_count);
monitors.watch("minds", PossessionAccount::mind_count);
monitors.watch("operations_in", PossessionClient::operations_in);
monitors.watch("operations_out", PossessionClient::operations_out);
monitors.watch("operations_in", (long&) PossessionClient::operations_in);
monitors.watch("operations_out", (long&) PossessionClient::operations_out);
//Reload the script factory when scripts changes.

View file

@ -61,10 +61,9 @@ void BaseClient::send(const Operation& op) {
/// @param name User name of the new account
/// @param password Password of the new account
Root BaseClient::createSystemAccount() {
Anonymous player_ent;
Atlas::Objects::Entity::SystemAccount player_ent;
player_ent->setAttr("username", create_session_username());
player_ent->setAttr("password", fmt::format("{}{}", ::rand(), ::rand()));
player_ent->setParent("sys");
Create createAccountOp;
createAccountOp->setArgs1(player_ent);

View file

@ -120,5 +120,5 @@ Ref<LocatedEntity> CharacterClient::sendLook(const Operation& op) {
} else {
std::cout << "Seen: " << sight_id << std::endl;
}
return m_map.updateAdd(seen, res->getSeconds());
return m_map.updateAdd(seen, std::chrono::milliseconds(res->getStamp()));
}

View file

@ -41,7 +41,7 @@ CreatorClient::CreatorClient(RouterId mindId,
}
LocatedEntity* CreatorClient::handleMakeResponse(const RootOperation& op,
double create_time) {
std::chrono::milliseconds create_time) {
if (op->getArgs().empty()) {
std::cerr << "Arg of reply to make has no args"
<< std::endl;
@ -103,9 +103,9 @@ Ref<LocatedEntity> CreatorClient::make(const RootEntity& entity) {
<< std::endl;
return nullptr;
}
return handleMakeResponse(arg, res->getSeconds());
return handleMakeResponse(arg, std::chrono::milliseconds(res->getStamp()));
} else if (res->getClassNo() == Atlas::Objects::Operation::INFO_NO) {
return handleMakeResponse(res, res->getSeconds());
return handleMakeResponse(res, std::chrono::milliseconds(res->getStamp()));
} else {
std::cerr << "Reply to make isn't sight or info"
<< std::endl;

View file

@ -34,7 +34,7 @@ public:
TypeStore& typeStore);
LocatedEntity* handleMakeResponse(const Atlas::Objects::Operation::RootOperation&,
double);
std::chrono::milliseconds);
Ref<LocatedEntity> make(const Atlas::Objects::Entity::RootEntity&);

View file

@ -272,6 +272,7 @@ void installStandardObjects(TypeStore& i) {
i.addChild(atlasObjDefinition<Atlas::Objects::Entity::AdminData>());
i.addChild(atlasObjDefinition<Atlas::Objects::Entity::GameData>());
i.addChild(atlasObjDefinition<Atlas::Objects::Entity::GameEntityData>());
i.addChild(atlasObjDefinition<Atlas::Objects::Entity::SystemAccountData>());
//We should now have just as many types registered as there are standard types in Atlas.
auto typeCount = i.getTypeCount();

View file

@ -61,7 +61,7 @@ struct OpQueEntry {
OpQueEntry(Operation op_, Ref<T> from_, long sequence_)
: op(std::move(op_)),
from(std::move(from_)),
time_for_dispatch(std::chrono::milliseconds(static_cast<std::int64_t>(op->getSeconds() * 1000))),
time_for_dispatch(std::chrono::milliseconds(op->getStamp())),
sequence(sequence_) {
}

View file

@ -118,7 +118,7 @@ template<typename T>
OpQueEntry<T>::OpQueEntry(Operation o, T& f, long sequence_) :
op(std::move(o)),
from(&f),
time_for_dispatch(std::chrono::milliseconds(static_cast<std::int64_t>(op->getSeconds() * 1000))),
time_for_dispatch(std::chrono::milliseconds(op->getStamp())),
sequence(sequence_) {
}
@ -126,7 +126,7 @@ template<typename T>
OpQueEntry<T>::OpQueEntry(const OpQueEntry& o) :
op(o.op),
from(o.from),
time_for_dispatch(std::chrono::milliseconds(static_cast<std::int64_t>(op->getSeconds() * 1000))),
time_for_dispatch(std::chrono::milliseconds(op->getStamp())),
sequence(o.sequence) {
}
@ -134,7 +134,7 @@ template<typename T>
OpQueEntry<T>::OpQueEntry(OpQueEntry&& o) noexcept
: op(std::move(o.op)),
from(std::move(o.from)),
time_for_dispatch(std::chrono::milliseconds(static_cast<std::int64_t>(op->getSeconds() * 1000))),
time_for_dispatch(std::chrono::milliseconds(op->getStamp())),
sequence(std::move(o.sequence)) {
}
@ -162,7 +162,7 @@ void OperationsDispatcher<T>::clearQueues() {
template<typename T>
void OperationsDispatcher<T>::addOperationToQueue(Operation op, Ref<T> ent) {
assert(op.isValid());
assert(!op->isDefaultSeconds());
assert(!op->isDefaultStamp());
//Check the sequence number of the first op at start.
long topSequenceNr = 0;

View file

@ -104,6 +104,12 @@ static const int EXPECTED_LAYERS_PER_TILE = 1;
using namespace boost::multi_index;
namespace {
double to_seconds(std::chrono::milliseconds duration) {
return std::chrono::duration_cast<std::chrono::duration<float>>(duration).count();
}
}
/**
* @brief A Most Recently Used list implemented using boost::multi_index.
*
@ -453,7 +459,7 @@ void Awareness::removeEntity(const MemEntity& observer, const MemEntity& entity)
}
}
bool Awareness::processEntityUpdate(EntityEntry& entityEntry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, double timestamp)
bool Awareness::processEntityUpdate(EntityEntry& entityEntry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, std::chrono::milliseconds timestamp)
{
bool hasNewPosition = false;
bool hasNewBbox = false;
@ -606,7 +612,7 @@ bool Awareness::avoidObstacles(long avatarEntityId,
const WFMath::Point<2>& position,
const WFMath::Vector<2>& desiredVelocity,
WFMath::Vector<2>& newVelocity,
double currentTimestamp,
std::chrono::milliseconds currentTimestamp,
const WFMath::Point<2>* nextWayPoint) const
{
struct EntityCollisionEntry
@ -644,7 +650,7 @@ bool Awareness::avoidObstacles(long avatarEntityId,
// Update location
auto pos = entry->pos.data;
if (entry->velocity.data.isValid()) {
double time_diff = currentTimestamp - entry->velocity.timestamp;
auto time_diff = to_seconds(currentTimestamp - entry->velocity.timestamp);
pos += (entry->velocity.data * time_diff);
}
@ -898,7 +904,7 @@ int Awareness::findPath(const WFMath::Point<3>& start, const WFMath::Point<3>& e
return nVertCount - 1;
}
bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, double currentServerTimestamp) const
bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, std::chrono::milliseconds currentServerTimestamp) const
{
auto entityI = mObservedEntities.find(entityId);
if (entityI != mObservedEntities.end()) {
@ -906,14 +912,14 @@ bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, double cur
pos = entityEntry->pos.data;
auto& velocity = entityEntry->velocity.data;
if (velocity.isValid() && velocity != WFMath::Vector<3>::ZERO()) {
pos += (velocity * (currentServerTimestamp - entityEntry->pos.timestamp));
pos += (velocity * to_seconds(currentServerTimestamp - entityEntry->pos.timestamp));
}
return true;
}
return false;
}
WFMath::Point<3> Awareness::projectPosition(long entityId, double currentServerTimestamp) const
WFMath::Point<3> Awareness::projectPosition(long entityId, std::chrono::milliseconds currentServerTimestamp) const
{
auto entityI = mObservedEntities.find(entityId);
if (entityI != mObservedEntities.end()) {
@ -921,7 +927,7 @@ WFMath::Point<3> Awareness::projectPosition(long entityId, double currentServerT
auto pos = entityEntry->pos.data;
auto& velocity = entityEntry->velocity.data;
if (velocity.isValid() && velocity != WFMath::Vector<3>::ZERO()) {
pos += (velocity * (currentServerTimestamp - entityEntry->pos.timestamp));
pos += (velocity * to_seconds(currentServerTimestamp - entityEntry->pos.timestamp));
}
return pos;
}

View file

@ -102,7 +102,7 @@ template<typename T>
struct TimestampedProperty
{
T data;
double timestamp = -1.0;
std::chrono::milliseconds timestamp = std::chrono::milliseconds {-1};
};
struct EntityEntry
@ -247,7 +247,7 @@ class Awareness
const WFMath::Point<2>& position,
const WFMath::Vector<2>& desiredVelocity,
WFMath::Vector<2>& newVelocity,
double currentTimestamp,
std::chrono::milliseconds currentTimestamp,
const WFMath::Point<2>* nextWayPoint) const;
/**
@ -342,9 +342,9 @@ class Awareness
* @param currentServerTimestamp The current server time stamp, to calculate new positions for moving entities.
* @return True if entity could be found.
*/
bool projectPosition(long entityId, WFMath::Point<3>& pos, double currentServerTimestamp) const;
bool projectPosition(long entityId, WFMath::Point<3>& pos, std::chrono::milliseconds currentServerTimestamp) const;
WFMath::Point<3> projectPosition(long entityId, double currentServerTimestamp) const;
WFMath::Point<3> projectPosition(long entityId, std::chrono::milliseconds currentServerTimestamp) const;
const std::unordered_map<long, std::unique_ptr<EntityEntry>>& getObservedEntities() const;
@ -507,7 +507,7 @@ class Awareness
* @param timestamp
* @return True if any position or size changed.
*/
bool processEntityUpdate(EntityEntry& entry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, double timestamp);
bool processEntityUpdate(EntityEntry& entry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, std::chrono::milliseconds timestamp);
/**
* @brief Rebuild the tile at the specific index.

View file

@ -35,47 +35,44 @@
static const bool debug_flag = true;
Steering::Steering(MemEntity& avatar) :
mAwareness(nullptr),
mAvatar(avatar),
mSteeringDestination{},
mCurrentPathIndex(0),
mSteeringEnabled(false),
mUpdateNeeded(false),
mPadding(16),
mMaxSpeed(5),
mDesiredSpeed(0.5),
mExpectingServerMovement(false),
mPathResult(0),
mAvatarHorizRadius(0)
{
auto speedGroundProp = avatar.getPropertyType<double>("speed_ground");
if (speedGroundProp) {
mMaxSpeed = speedGroundProp->data();
}
mAwareness(nullptr),
mAvatar(avatar),
mSteeringDestination{},
mCurrentPathIndex(0),
mSteeringEnabled(false),
mUpdateNeeded(false),
mPadding(16),
mMaxSpeed(5),
mDesiredSpeed(0.5),
mExpectingServerMovement(false),
mPathResult(0),
mAvatarHorizRadius(0) {
auto speedGroundProp = avatar.getPropertyType<double>("speed_ground");
if (speedGroundProp) {
mMaxSpeed = speedGroundProp->data();
}
auto bbox = ScaleProperty::scaledBbox(mAvatar);
if (bbox.isValid()) {
mAvatarHorizRadius = std::sqrt(boxSquareHorizontalBoundingRadius(bbox));
} else {
spdlog::warn("Created Steering with avatar without any bounding box. This is unusual.");
}
auto bbox = ScaleProperty::scaledBbox(mAvatar);
if (bbox.isValid()) {
mAvatarHorizRadius = std::sqrt(boxSquareHorizontalBoundingRadius(bbox));
} else {
spdlog::warn("Created Steering with avatar without any bounding box. This is unusual.");
}
}
void Steering::setAwareness(Awareness* awareness)
{
mAwareness = awareness;
mTileListenerConnection.disconnect();
if (mAwareness) {
mTileListenerConnection = mAwareness->EventTileUpdated.connect(sigc::mem_fun(*this, &Steering::Awareness_TileUpdated));
//setAwarenessArea();
}
void Steering::setAwareness(Awareness* awareness) {
mAwareness = awareness;
mTileListenerConnection.disconnect();
if (mAwareness) {
mTileListenerConnection = mAwareness->EventTileUpdated.connect(sigc::mem_fun(*this, &Steering::Awareness_TileUpdated));
//setAwarenessArea();
}
}
int Steering::queryDestination(const EntityLocation& destination, double currentServerTimestamp)
{
int Steering::queryDestination(const EntityLocation& destination, std::chrono::milliseconds currentServerTimestamp) {
// if (mAwareness) {
//
// auto currentAvatarPos = getCurrentAvatarPosition(currentServerTimestamp);
@ -118,16 +115,15 @@ int Steering::queryDestination(const EntityLocation& destination, double current
//// mAvatarPositionLastUpdate = currentAvatarPos;
//// }
// }
return -10;
return -10;
}
void Steering::setDestination(SteeringDestination destination, double currentServerTimestamp)
{
if (destination.location.m_pos != mSteeringDestination.location.m_pos || destination.location.m_parent != mSteeringDestination.location.m_parent) {
mSteeringDestination = std::move(destination);
mUpdateNeeded = true;
}
setAwarenessArea(currentServerTimestamp);
void Steering::setDestination(SteeringDestination destination, std::chrono::milliseconds currentServerTimestamp) {
if (destination.location.m_pos != mSteeringDestination.location.m_pos || destination.location.m_parent != mSteeringDestination.location.m_parent) {
mSteeringDestination = std::move(destination);
mUpdateNeeded = true;
}
setAwarenessArea(currentServerTimestamp);
// mSteeringDestination = std::move(destination);
//
// if (mAwareness) {
@ -164,356 +160,334 @@ void Steering::setDestination(SteeringDestination destination, double currentSer
}
void Steering::setAwarenessArea(double currentServerTimestamp)
{
if (mAwareness) {
auto resolvedPosition = resolvePosition(currentServerTimestamp, mSteeringDestination.location);
void Steering::setAwarenessArea(std::chrono::milliseconds currentServerTimestamp) {
if (mAwareness) {
auto resolvedPosition = resolvePosition(currentServerTimestamp, mSteeringDestination.location);
// resolvePosition()
if (resolvedPosition.position.isValid()) {
WFMath::Point<2> destination2d(resolvedPosition.position.x(), resolvedPosition.position.z());
auto pos = PositionProperty::extractPosition(mAvatar);
WFMath::Point<2> entityPosition2d(pos.x(), pos.z());
if (resolvedPosition.position.isValid()) {
WFMath::Point<2> destination2d(resolvedPosition.position.x(), resolvedPosition.position.z());
auto pos = PositionProperty::extractPosition(mAvatar);
WFMath::Point<2> entityPosition2d(pos.x(), pos.z());
WFMath::Vector<2> direction(destination2d - entityPosition2d);
auto theta = std::atan2(direction.y(), direction.x()); // rotation about Y
WFMath::RotMatrix<2> rm;
rm.rotation(theta);
WFMath::Vector<2> direction(destination2d - entityPosition2d);
auto theta = std::atan2(direction.y(), direction.x()); // rotation about Y
WFMath::RotMatrix<2> rm;
rm.rotation(theta);
WFMath::Point<2> start = entityPosition2d;
start -= WFMath::Vector<2>(mPadding, mPadding);
WFMath::Point<2> start = entityPosition2d;
start -= WFMath::Vector<2>(mPadding, mPadding);
WFMath::Vector<2> size(direction.mag() + (mPadding * 2), mPadding * 2);
WFMath::Vector<2> size(direction.mag() + (mPadding * 2), mPadding * 2);
WFMath::RotBox<2> area;
area.size() = size;
area.corner0() = start;
area.orientation() = WFMath::RotMatrix<2>().identity();
area.rotatePoint(rm, entityPosition2d);
WFMath::RotBox<2> area;
area.size() = size;
area.corner0() = start;
area.orientation() = WFMath::RotMatrix<2>().identity();
area.rotatePoint(rm, entityPosition2d);
mAwareness->setAwarenessArea(mAvatar.getId(), area, WFMath::Segment<2>(entityPosition2d, destination2d));
}
}
mAwareness->setAwarenessArea(mAvatar.getId(), area, WFMath::Segment<2>(entityPosition2d, destination2d));
}
}
}
size_t Steering::unawareAreaCount() const
{
if (mAwareness) {
return mAwareness->unawareTilesInArea(mAvatar.getId());
}
return 0;
size_t Steering::unawareAreaCount() const {
if (mAwareness) {
return mAwareness->unawareTilesInArea(mAvatar.getId());
}
return 0;
}
void Steering::setDesiredSpeed(float desiredSpeed)
{
mDesiredSpeed = desiredSpeed;
void Steering::setDesiredSpeed(float desiredSpeed) {
mDesiredSpeed = desiredSpeed;
}
int Steering::getPathResult() const
{
return mPathResult;
int Steering::getPathResult() const {
return mPathResult;
}
int Steering::updatePath(double currentTimestamp, const WFMath::Point<3>& currentAvatarPosition)
{
rmt_ScopedCPUSample(Steering_updatePath, 0)
mPath.clear();
mCurrentPathIndex = 0;
if (!mAwareness) {
mPathResult = -7;
return mPathResult;
}
auto resolvedPosition = resolvePosition(currentTimestamp, mSteeringDestination.location);
if (!resolvedPosition.position.isValid()) {
mPathResult = -8;
return mPathResult;
}
mPathResult = mAwareness->findPath(currentAvatarPosition, resolvedPosition.position, mSteeringDestination.distance, mPath);
if (mPathResult == -1) {
mAwareness->markTilesAsDirty(WFMath::AxisBox<2>(
{currentAvatarPosition.x() - 5, currentAvatarPosition.z() - 5},
{currentAvatarPosition.x() + 5, currentAvatarPosition.z() + 5}));
} else if (mPathResult == -2) {
mAwareness->markTilesAsDirty(WFMath::AxisBox<2>(
{resolvedPosition.position.x() - 5, resolvedPosition.position.z() - 5},
{resolvedPosition.position.x() + 5, resolvedPosition.position.z() + 5}));
}
//cy_debug_print("Updating path, size of new path: " << result << ". Pos: " << currentAvatarPosition);
EventPathUpdated();
mUpdateNeeded = false;
return mPathResult;
int Steering::updatePath(std::chrono::milliseconds currentTimestamp, const WFMath::Point<3>& currentAvatarPosition) {
rmt_ScopedCPUSample(Steering_updatePath, 0)
mPath.clear();
mCurrentPathIndex = 0;
if (!mAwareness) {
mPathResult = -7;
return mPathResult;
}
auto resolvedPosition = resolvePosition(currentTimestamp, mSteeringDestination.location);
if (!resolvedPosition.position.isValid()) {
mPathResult = -8;
return mPathResult;
}
mPathResult = mAwareness->findPath(currentAvatarPosition, resolvedPosition.position, (float) mSteeringDestination.distance, mPath);
if (mPathResult == -1) {
mAwareness->markTilesAsDirty(WFMath::AxisBox<2>(
{currentAvatarPosition.x() - 5, currentAvatarPosition.z() - 5},
{currentAvatarPosition.x() + 5, currentAvatarPosition.z() + 5}));
} else if (mPathResult == -2) {
mAwareness->markTilesAsDirty(WFMath::AxisBox<2>(
{resolvedPosition.position.x() - 5, resolvedPosition.position.z() - 5},
{resolvedPosition.position.x() + 5, resolvedPosition.position.z() + 5}));
}
//cy_debug_print("Updating path, size of new path: " << result << ". Pos: " << currentAvatarPosition);
EventPathUpdated();
mUpdateNeeded = false;
return mPathResult;
}
int Steering::updatePath(double currentTimestamp)
{
if (!mAwareness) {
return -1;
}
auto currentEntityPos = mAwareness->projectPosition(mAvatar.getIntId(), currentTimestamp);
int Steering::updatePath(std::chrono::milliseconds currentTimestamp) {
if (!mAwareness) {
return -1;
}
auto currentEntityPos = mAwareness->projectPosition(mAvatar.getIntId(), currentTimestamp);
return updatePath(currentTimestamp, currentEntityPos);
return updatePath(currentTimestamp, currentEntityPos);
}
void Steering::requestUpdate()
{
mUpdateNeeded = true;
void Steering::requestUpdate() {
mUpdateNeeded = true;
}
void Steering::startSteering()
{
mSteeringEnabled = true;
mExpectingServerMovement = false;
void Steering::startSteering() {
mSteeringEnabled = true;
mExpectingServerMovement = false;
}
void Steering::stopSteering()
{
if (!mSteeringEnabled) {
return;
}
mSteeringEnabled = false;
mExpectingServerMovement = false;
mLastSentVelocity = WFMath::Vector<2>();
void Steering::stopSteering() {
if (!mSteeringEnabled) {
return;
}
mSteeringEnabled = false;
mExpectingServerMovement = false;
mLastSentVelocity = WFMath::Vector<2>();
//reset path
mPath.clear();
mCurrentPathIndex = 0;
mPathResult = 0;
EventPathUpdated();
//reset path
mPath.clear();
mCurrentPathIndex = 0;
mPathResult = 0;
EventPathUpdated();
}
bool Steering::isEnabled() const
{
return mSteeringEnabled;
bool Steering::isEnabled() const {
return mSteeringEnabled;
}
const std::vector<WFMath::Point<3>>& Steering::getPath() const
{
return mPath;
const std::vector<WFMath::Point<3>>& Steering::getPath() const {
return mPath;
}
size_t Steering::getCurrentPathIndex() const
{
return mCurrentPathIndex;
size_t Steering::getCurrentPathIndex() const {
return mCurrentPathIndex;
}
WFMath::Point<3> Steering::getCurrentAvatarPosition(double currentTimestamp) const
{
return mAwareness ? mAwareness->projectPosition(mAvatar.getIntId(), currentTimestamp) : WFMath::Point<3>{};
WFMath::Point<3> Steering::getCurrentAvatarPosition(std::chrono::milliseconds currentTimestamp) const {
return mAwareness ? mAwareness->projectPosition(mAvatar.getIntId(), currentTimestamp) : WFMath::Point<3>{};
}
WFMath::Vector<3> Steering::directionTo(double currentTimestamp, const EntityLocation& location) const
{
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
auto resolvedDestination = resolvePosition(currentTimestamp, location);
WFMath::Vector<3> Steering::directionTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const {
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
auto resolvedDestination = resolvePosition(currentTimestamp, location);
if (!currentEntityPos.isValid() || !resolvedDestination.position.isValid()) {
return {};
}
if (!currentEntityPos.isValid() || !resolvedDestination.position.isValid()) {
return {};
}
return (resolvedDestination.position - currentEntityPos);
return (resolvedDestination.position - currentEntityPos);
}
std::optional<double> Steering::distanceTo(double currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const
{
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
auto resolvedDestination = resolvePosition(currentTimestamp, location);
std::optional<double> Steering::distanceTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const {
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
auto resolvedDestination = resolvePosition(currentTimestamp, location);
if (!currentEntityPos.isValid() || !resolvedDestination.position.isValid()) {
return {};
}
if (!currentEntityPos.isValid() || !resolvedDestination.position.isValid()) {
return {};
}
auto distance = WFMath::Distance(WFMath::Point<2>(currentEntityPos.x(), currentEntityPos.z()), WFMath::Point<2>(resolvedDestination.position.x(), resolvedDestination.position.z()));
if (fromSelf == MeasureType::EDGE) {
distance -= mAvatarHorizRadius;
}
if (toDestination == MeasureType::EDGE) {
distance -= resolvedDestination.radius;
auto distance = WFMath::Distance(WFMath::Point<2>(currentEntityPos.x(), currentEntityPos.z()), WFMath::Point<2>(resolvedDestination.position.x(), resolvedDestination.position.z()));
if (fromSelf == MeasureType::EDGE) {
distance -= mAvatarHorizRadius;
}
if (toDestination == MeasureType::EDGE) {
distance -= resolvedDestination.radius;
// if (resolvedDestination.location) {
// auto& bbox = resolvedDestination.location->bBox();
// if (bbox.isValid()) {
// distance -= std::sqrt(boxSquareHorizontalBoundingRadius(bbox));
// }
// }
}
return std::max(0.0, distance);
}
return std::max(0.0, distance);
}
Steering::ResolvedPosition Steering::resolvePosition(double currentTimestamp, const EntityLocation& location) const
{
if (!mAwareness) {
return {};
}
//If there's no parent at all we're operating within the same space as the avatar.
if (!location.m_parent) {
return {location.m_pos, 0};
}
//If the parent is the same we're just operating on position data without any volume.
if (location.m_parent == mAvatar.m_parent) {
//Just ignore any extra position supplied.
return {location.pos(), 0};
}
//If the supplied destination doesn't belong to the current domain, walk upwards until we find the entity that does.
//This entity will then determine the position.
auto entity = location.m_parent;
Steering::ResolvedPosition Steering::resolvePosition(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const {
if (!mAwareness) {
return {};
}
//If there's no parent at all we're operating within the same space as the avatar.
if (!location.m_parent) {
return {location.m_pos, 0};
}
//If the parent is the same we're just operating on position data without any volume.
if (location.m_parent == mAvatar.m_parent) {
//Just ignore any extra position supplied.
return {location.pos(), 0};
}
//If the supplied destination doesn't belong to the current domain, walk upwards until we find the entity that does.
//This entity will then determine the position.
auto entity = location.m_parent;
while (entity->m_parent && entity->m_parent != mAvatar.m_parent) {
entity = entity->m_parent;
}
while (entity->m_parent && entity->m_parent != mAvatar.m_parent) {
entity = entity->m_parent;
}
//Could not find the parent domain entity
if (!entity) {
return {};
}
//Could not find the parent domain entity
if (!entity) {
return {};
}
double distance = 0;
auto I = mAwareness->getObservedEntities().find(entity->getIntId());
if (I != mAwareness->getObservedEntities().end()) {
if (I->second->scaledBbox.isValid()) {
distance = std::sqrt(boxSquareHorizontalBoundingRadius(I->second->scaledBbox));
}
}
double distance = 0;
auto I = mAwareness->getObservedEntities().find(entity->getIntId());
if (I != mAwareness->getObservedEntities().end()) {
if (I->second->scaledBbox.isValid()) {
distance = std::sqrt(boxSquareHorizontalBoundingRadius(I->second->scaledBbox));
}
}
return {mAwareness->projectPosition(entity->getIntId(), currentTimestamp), distance};
return {mAwareness->projectPosition(entity->getIntId(), currentTimestamp), distance};
}
bool Steering::isAtDestination(double currentTimestamp, const SteeringDestination& destination) const
{
auto distance = distanceTo(currentTimestamp, destination.location, destination.measureFromAvatar, destination.measureToDestination);
if (distance) {
return *distance <= destination.distance;
}
return false;
bool Steering::isAtDestination(std::chrono::milliseconds currentTimestamp, const SteeringDestination& destination) const {
auto distance = distanceTo(currentTimestamp, destination.location, destination.measureFromAvatar, destination.measureToDestination);
if (distance) {
return *distance <= destination.distance;
}
return false;
}
bool Steering::isAtCurrentDestination(double currentTimestamp) const
{
return isAtDestination(currentTimestamp, mSteeringDestination);
bool Steering::isAtCurrentDestination(std::chrono::milliseconds currentTimestamp) const {
return isAtDestination(currentTimestamp, mSteeringDestination);
}
SteeringResult Steering::update(double currentTimestamp)
{
rmt_ScopedCPUSample(Steering_update, 0)
SteeringResult result{};
if (!mSteeringEnabled) {
auto propelProperty = mAvatar.getPropertyClass<Vector3Property>("_propel");
if (propelProperty && propelProperty->data().isValid() && propelProperty->data() != WFMath::Vector<3>::ZERO()) {
result.direction = WFMath::Vector<3>::ZERO();
}
} else if (mAwareness) {
SteeringResult Steering::update(std::chrono::milliseconds currentTimestamp) {
rmt_ScopedCPUSample(Steering_update, 0)
SteeringResult result{};
if (!mSteeringEnabled) {
auto propelProperty = mAvatar.getPropertyClass<Vector3Property>("_propel");
if (propelProperty && propelProperty->data().isValid() && propelProperty->data() != WFMath::Vector<3>::ZERO()) {
result.direction = WFMath::Vector<3>::ZERO();
}
} else if (mAwareness) {
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
auto currentEntityPos = getCurrentAvatarPosition(currentTimestamp);
if (mUpdateNeeded) {
updatePath(currentTimestamp, currentEntityPos);
}
if (!mPath.empty()) {
//First check if we've arrived at our actual destination.
if (isAtCurrentDestination(currentTimestamp)) {
//We've arrived at our destination. If we're moving we should stop.
if (mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
result.direction = WFMath::Vector<3>::ZERO();
mLastSentVelocity = WFMath::Vector<2>::ZERO();
mExpectingServerMovement = true;
}
stopSteering();
} else {
//We should send a move op if we're either not moving, or we've reached a waypoint, or we need to divert a lot.
const WFMath::Point<2> entityPosition(currentEntityPos.x(), currentEntityPos.z());
if (mUpdateNeeded) {
updatePath(currentTimestamp, currentEntityPos);
}
if (!mPath.empty()) {
//First check if we've arrived at our actual destination.
if (isAtCurrentDestination(currentTimestamp)) {
//We've arrived at our destination. If we're moving we should stop.
if (mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
result.direction = WFMath::Vector<3>::ZERO();
mLastSentVelocity = WFMath::Vector<2>::ZERO();
mExpectingServerMovement = true;
}
stopSteering();
} else {
//We should send a move op if we're either not moving, or we've reached a waypoint, or we need to divert a lot.
const WFMath::Point<2> entityPosition(currentEntityPos.x(), currentEntityPos.z());
WFMath::Point<2> nextWaypoint(mPath[mCurrentPathIndex].x(), mPath[mCurrentPathIndex].z());
while (WFMath::Distance(nextWaypoint, entityPosition) < mAvatarHorizRadius && mCurrentPathIndex < mPath.size() - 1) {
mCurrentPathIndex++;
nextWaypoint = WFMath::Point<2>(mPath[mCurrentPathIndex].x(), mPath[mCurrentPathIndex].z());
}
WFMath::Point<2> nextWaypoint(mPath[mCurrentPathIndex].x(), mPath[mCurrentPathIndex].z());
while (WFMath::Distance(nextWaypoint, entityPosition) < mAvatarHorizRadius && mCurrentPathIndex < mPath.size() - 1) {
mCurrentPathIndex++;
nextWaypoint = WFMath::Point<2>(mPath[mCurrentPathIndex].x(), mPath[mCurrentPathIndex].z());
}
WFMath::Vector<2> distance = nextWaypoint - entityPosition;
WFMath::Vector<2> velocityNorm = distance; //The velocity, normalized
velocityNorm = velocityNorm.normalize() * mDesiredSpeed;
WFMath::Point<2> destination;
WFMath::Vector<2> distance = nextWaypoint - entityPosition;
WFMath::Vector<2> velocityNorm = distance; //The velocity, normalized, as meter per second
velocityNorm = velocityNorm.normalize() * mDesiredSpeed;
WFMath::Point<2> destination;
result.timeToNextWaypoint = distance.mag() / velocityNorm.mag();
result.timeToNextWaypoint = std::chrono::milliseconds((std::int64_t) ((distance.mag() / velocityNorm.mag()) * 1000));
if (mCurrentPathIndex == mPath.size() - 1) {
//if the next waypoint is the destination we should send a "move to position" update to the server, to make sure that we stop when we've arrived.
//otherwise, if there's too much lag, we might end up overshooting our destination and will have to double back
destination = nextWaypoint;
}
if (mCurrentPathIndex == mPath.size() - 1) {
//if the next waypoint is the destination we should send a "move to position" update to the server, to make sure that we stop when we've arrived.
//otherwise, if there's too much lag, we might end up overshooting our destination and will have to double back
destination = nextWaypoint;
}
//Check if we need to divert in order to avoid colliding.
WFMath::Vector<2> newVelocity; //The new velocity after avoiding, not normalized.
bool shouldSend = false;
bool avoiding = mAwareness->avoidObstacles(mAvatar.getIntId(), entityPosition, velocityNorm * mMaxSpeed, newVelocity, currentTimestamp, &nextWaypoint);
if (avoiding) {
//spdlog::info("Avoiding.");
velocityNorm = newVelocity / mMaxSpeed;
//Check if we need to divert in order to avoid colliding.
WFMath::Vector<2> newVelocity; //The new velocity after avoiding, not normalized.
bool shouldSend = false;
bool avoiding = mAwareness->avoidObstacles(mAvatar.getIntId(), entityPosition, velocityNorm * mMaxSpeed, newVelocity, currentTimestamp, &nextWaypoint);
if (avoiding) {
//spdlog::info("Avoiding.");
velocityNorm = newVelocity / mMaxSpeed;
//Schedule a new steering op very soon
result.timeToNextWaypoint = std::min(*result.timeToNextWaypoint, 0.1);
mUpdateNeeded = true;
shouldSend = true;
}
//Schedule a new steering op very soon
result.timeToNextWaypoint = std::min(*result.timeToNextWaypoint, std::chrono::milliseconds(100));
mUpdateNeeded = true;
shouldSend = true;
}
if (velocityNorm.isValid()) {
if (mLastSentVelocity.isValid()) {
auto velocityProp = mAvatar.getPropertyClassFixed<VelocityProperty>();
//If the entity has stopped, and we're not waiting for confirmation to a movement request we've made, we need to start moving.
if (velocityProp && velocityProp->data() == WFMath::Vector<3>::ZERO() && !mExpectingServerMovement) {
shouldSend = true;
} else {
auto currentTheta = std::atan2(mLastSentVelocity.y(), mLastSentVelocity.x());
auto newTheta = std::atan2(velocityNorm.y(), velocityNorm.x());
if (velocityNorm.isValid()) {
if (mLastSentVelocity.isValid()) {
auto velocityProp = mAvatar.getPropertyClassFixed<VelocityProperty>();
//If the entity has stopped, and we're not waiting for confirmation to a movement request we've made, we need to start moving.
if (velocityProp && velocityProp->data() == WFMath::Vector<3>::ZERO() && !mExpectingServerMovement) {
shouldSend = true;
} else {
auto currentTheta = std::atan2(mLastSentVelocity.y(), mLastSentVelocity.x());
auto newTheta = std::atan2(velocityNorm.y(), velocityNorm.x());
//If we divert too much from where we need to go we must adjust.
if (std::abs(currentTheta - newTheta) > WFMath::numeric_constants<double>::pi() / 20) {
shouldSend = true;
}
}
} else {
//If we've never sent a movement update before we should do that now.
shouldSend = true;
}
}
if (shouldSend) {
//If we're moving to a certain destination and aren't avoiding anything we should tell the server to move to the destination.
if (destination.isValid() && !avoiding) {
auto posProp = mAvatar.getPropertyClassFixed<PositionProperty>();
auto y = posProp ? posProp->data().y() : 0.0;
result.destination = WFMath::Point<3>(destination.x(), y, destination.y());
}
result.direction = WFMath::Vector<3>(velocityNorm.x(), 0, velocityNorm.y());
mLastSentVelocity = velocityNorm;
mExpectingServerMovement = true;
}
}
} else {
//We are steering, but the path is empty, which means we can't find any path. If we're moving we should stop movement.
//But we won't stop steering; perhaps we'll find a path later.
if (mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
result.direction = WFMath::Vector<3>::ZERO();
mLastSentVelocity = WFMath::Vector<2>::ZERO();
mExpectingServerMovement = true;
}
}
}
return result;
//If we divert too much from where we need to go we must adjust.
if (std::abs(currentTheta - newTheta) > WFMath::numeric_constants<double>::pi() / 20) {
shouldSend = true;
}
}
} else {
//If we've never sent a movement update before we should do that now.
shouldSend = true;
}
}
if (shouldSend) {
//If we're moving to a certain destination and aren't avoiding anything we should tell the server to move to the destination.
if (destination.isValid() && !avoiding) {
auto posProp = mAvatar.getPropertyClassFixed<PositionProperty>();
auto y = posProp ? posProp->data().y() : 0.0;
result.destination = WFMath::Point<3>(destination.x(), y, destination.y());
}
result.direction = WFMath::Vector<3>(velocityNorm.x(), 0, velocityNorm.y());
mLastSentVelocity = velocityNorm;
mExpectingServerMovement = true;
}
}
} else {
//We are steering, but the path is empty, which means we can't find any path. If we're moving we should stop movement.
//But we won't stop steering; perhaps we'll find a path later.
if (mLastSentVelocity != WFMath::Vector<2>::ZERO()) {
result.direction = WFMath::Vector<3>::ZERO();
mLastSentVelocity = WFMath::Vector<2>::ZERO();
mExpectingServerMovement = true;
}
}
}
return result;
}
void Steering::Awareness_TileUpdated(int tx, int ty)
{
mUpdateNeeded = true;
void Steering::Awareness_TileUpdated(int tx, int ty) {
mUpdateNeeded = true;
}
bool Steering::getIsExpectingServerMovement() const
{
return mExpectingServerMovement;
bool Steering::getIsExpectingServerMovement() const {
return mExpectingServerMovement;
}
void Steering::setIsExpectingServerMovement(bool expected)
{
mExpectingServerMovement = expected;
void Steering::setIsExpectingServerMovement(bool expected) {
mExpectingServerMovement = expected;
}

View file

@ -61,7 +61,7 @@ struct SteeringResult
* Time until the next waypoint is reached.
* This is used for scheduling the next update tick.
*/
std::optional<double> timeToNextWaypoint;
std::optional<std::chrono::milliseconds > timeToNextWaypoint;
};
@ -155,22 +155,22 @@ class Steering : public virtual sigc::trackable
void setAwareness(Awareness* awareness);
int queryDestination(const EntityLocation& destination, double currentServerTimestamp);
int queryDestination(const EntityLocation& destination, std::chrono::milliseconds currentServerTimestamp);
void setDestination(SteeringDestination destination, double currentServerTimestamp);
void setDestination(SteeringDestination destination, std::chrono::milliseconds currentServerTimestamp);
/**
* @brief Updates the path.
* @param currentAvatarPosition The current position of the avatar entity.
* @return If >= 0, a path was found. If <0 and >= -3 we couldn't find a path currently because we don't have all data yet. If <= -4 we couldn't find a path.
*/
int updatePath(double currentTimestamp, const WFMath::Point<3>& currentAvatarPosition);
int updatePath(std::chrono::milliseconds currentTimestamp, const WFMath::Point<3>& currentAvatarPosition);
/**
* @brief Updates the path.
* @return If >= 0, a path was found. If <0 and >= -3 we couldn't find a path currently because we don't have all data yet. If <= -4 we couldn't find a path.
*/
int updatePath(double currentTimestamp);
int updatePath(std::chrono::milliseconds currentTimestamp);
/**
* @brief Requests an update of the path.
@ -229,23 +229,23 @@ class Steering : public virtual sigc::trackable
*
* Call this often when steering is enabled.
*/
SteeringResult update(double currentTimestamp);
SteeringResult update(std::chrono::milliseconds currentTimestamp);
WFMath::Point<3> getCurrentAvatarPosition(double currentTimestamp) const;
WFMath::Point<3> getCurrentAvatarPosition(std::chrono::milliseconds currentTimestamp) const;
size_t unawareAreaCount() const;
int getPathResult() const;
bool isAtDestination(double currentTimestamp, const SteeringDestination& destination) const;
bool isAtDestination(std::chrono::milliseconds currentTimestamp, const SteeringDestination& destination) const;
bool isAtCurrentDestination(double currentTimestamp) const;
bool isAtCurrentDestination(std::chrono::milliseconds currentTimestamp) const;
std::optional<double> distanceTo(double currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const;
std::optional<double> distanceTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const;
WFMath::Vector<3> directionTo(double currentTimestamp, const EntityLocation& location) const;
WFMath::Vector<3> directionTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const;
Steering::ResolvedPosition resolvePosition(double currentTimestamp, const EntityLocation& location) const;
Steering::ResolvedPosition resolvePosition(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const;
/**
* @brief Emitted when the path has been updated.
@ -332,7 +332,7 @@ class Steering : public virtual sigc::trackable
*
* mPadding determines the width of the corridor.
*/
void setAwarenessArea(double currentServerTimestamp);
void setAwarenessArea(std::chrono::milliseconds currentServerTimestamp);
/**
* @brief Listen to tiles being updated, and request updates.
@ -347,17 +347,17 @@ class Steering : public virtual sigc::trackable
*/
void moveInDirection(const WFMath::Vector<2>& direction);
/**
* @brief Tells the server to move towards a certain point.
*
* The server will make sure to stop at the specified point, unless we collide with something.
* This should therefore be used to reach our final destination.
*
* @param point The point to move towards.
*/
/**
* @brief Tells the server to move towards a certain point.
*
* The server will make sure to stop at the specified point, unless we collide with something.
* This should therefore be used to reach our final destination.
*
* @param point The point to move towards.
*/
void moveToPoint(const WFMath::Point<3>& point);
void updatePosition(double currentServerTimestamp, long entityId, WFMath::Point<3>& pos) const;
void updatePosition(std::chrono::milliseconds currentServerTimestamp, long entityId, WFMath::Point<3>& pos) const;
};

View file

@ -64,7 +64,7 @@ AwareMind::~AwareMind() {
}
}
double AwareMind::getCurrentServerTime() const {
std::chrono::milliseconds AwareMind::getCurrentServerTime() const {
return mServerTime;
}

View file

@ -56,7 +56,7 @@ public:
const std::shared_ptr<Awareness>& getAwareness() const;
double getCurrentServerTime() const;
std::chrono::milliseconds getCurrentServerTime() const;
protected:

View file

@ -101,7 +101,7 @@ void BaseMind::sightSetOperation(const Operation& op, OpVector& res) {
spdlog::error("Got sight(set) of non-entity");
return;
}
m_map.updateAdd(ent, op->getSeconds());
m_map.updateAdd(ent, std::chrono::milliseconds(op->getStamp()));
}
void BaseMind::SoundOperation(const Operation& op, OpVector& res) {
@ -130,8 +130,8 @@ void BaseMind::SightOperation(const Operation& op, OpVector& res) {
cy_debug_print("BaseMind::SightOperation(Sight)")
// Deliver argument to sight things
if (!isAwake()) { return; }
if (op->isDefaultSeconds()) {
spdlog::error("Sight operation had no seconds set, ignoring it.");
if (op->isDefaultStamp()) {
spdlog::error("Sight operation had no stamp set, ignoring it.");
return;
}
@ -147,10 +147,10 @@ void BaseMind::SightOperation(const Operation& op, OpVector& res) {
std::string event_name("sight_");
event_name += op2->getParent();
//Check that the argument had seconds set; if not the timestamp of the updates will be wrong.
if (!op2->hasAttrFlag(Atlas::Objects::Operation::SECONDS_FLAG)) {
//Check that the argument had stamp set; if not the timestamp of the updates will be wrong.
if (!op2->hasAttrFlag(Atlas::Objects::STAMP_FLAG)) {
//Copy from wrapping op to fix this.
op2->setSeconds(op->getSeconds());
op2->setStamp(op->getStamp());
}
if (!m_script || m_script->operation(event_name, op2, res) != OPERATION_BLOCKED) {
@ -163,7 +163,7 @@ void BaseMind::SightOperation(const Operation& op, OpVector& res) {
return;
}
cy_debug_print(" arg is an entity!")
auto me = m_map.updateAdd(ent, op->getSeconds());
auto me = m_map.updateAdd(ent, std::chrono::milliseconds(op->getStamp()));
if (me) {
me->setVisible();
}
@ -224,7 +224,7 @@ void BaseMind::AppearanceOperation(const Operation& op, OpVector& res) {
} else {
spdlog::error("BaseMind: Appearance op does not have stamp");
}
entity->update(op->getSeconds());
entity->update(std::chrono::milliseconds(op->getStamp()));
entity->setVisible();
}
}
@ -383,13 +383,13 @@ void BaseMind::addPropertyScriptCallback(std::string propertyName, std::string s
}
void BaseMind::updateServerTimeFromOperation(const Atlas::Objects::Operation::RootOperationData& op) {
//It's ok if the server sends an op without 'seconds' set.
if (!op.isDefaultSeconds()) {
//It's ok if the server sends an op without 'stamp' set.
if (!op.isDefaultStamp()) {
//Alert if there's a too large difference in time.
if (op.getSeconds() - mServerTime < -30) {
spdlog::warn("Operation '{}' has seconds set ({}) earlier than already recorded seconds ({}).", op.getParent(), op.getSeconds(), mServerTime);
if (std::chrono::milliseconds(op.getStamp()) - mServerTime < std::chrono::seconds(-30)) {
spdlog::warn("Operation '{}' has stamp set ({}) earlier than already recorded stamp ({}).", op.getParent(), op.getStamp(), mServerTime.count());
}
mServerTime = op.getSeconds();
mServerTime = std::chrono::milliseconds(op.getStamp());
}
}
@ -496,7 +496,7 @@ void BaseMind::processTick(OpVector& res) {
//Start by scheduling the next tick op.
Atlas::Objects::Operation::Tick tick;
//Do one tick every 10ms. (to be revisited)
tick->setFutureSeconds(0.01);
tick->setFutureMilliseconds(10);
tick->setTo(getId());
tick->setFrom(getId());
res.emplace_back(std::move(tick));

View file

@ -48,7 +48,7 @@ protected:
/// \brief Memory map of world entities this mind knows about
MemMap m_map;
/// \brief World time as far as this mind is aware
double mServerTime;
std::chrono::milliseconds mServerTime;
std::map<std::string, std::vector<Operation>> m_pendingEntitiesOperations;
std::deque<Operation> m_pendingOperations;

View file

@ -18,6 +18,8 @@
#include <rules/BBoxProperty.h>
#include <rules/ScaleProperty.h>
#include <utility>
#include "MemEntity.h"
#include "rules/SolidProperty.h"
#include "common/TypeNode.h"
@ -26,8 +28,8 @@
static const bool debug_flag = false;
MemEntity::MemEntity(RouterId id) :
LocatedEntity(id),
m_lastSeen(0.),
LocatedEntity(std::move(id)),
m_lastSeen(0),
m_lastUpdated(0) {
}

View file

@ -29,7 +29,7 @@
/// be cleaned up.
class MemEntity : public LocatedEntity {
protected:
double m_lastSeen;
std::chrono::milliseconds m_lastSeen;
std::unique_ptr<PropertyBase> createProperty(const std::string& propertyName) const override;
@ -46,11 +46,11 @@ public:
}
}
const double& lastSeen() const {
std::chrono::milliseconds lastSeen() const {
return m_lastSeen;
}
void update(const double& d) {
void update(std::chrono::milliseconds d) {
if (d >= m_lastSeen) {
m_lastSeen = d;
}
@ -65,7 +65,7 @@ public:
// TransformData m_transform;
// MovementData m_movement;
//WFMath::AxisBox<3> m_bbox;
double m_lastUpdated;
std::chrono::milliseconds m_lastUpdated;
//Location m_location;
};

View file

@ -26,9 +26,7 @@
#include "common/id.h"
#include "common/debug.h"
#include "common/TypeNode.h"
#include "common/Inheritance.h"
#include <Atlas/Objects/Operation.h>
#include <Atlas/Objects/Anonymous.h>
#include "rules/AtlasProperties.h"
#include "rules/PhysicalProperties.h"
@ -55,7 +53,7 @@ void MemMap::addEntity(const Ref<MemEntity>& entity) {
m_checkIterator = m_entities.find(next);
}
void MemMap::readEntity(const Ref<MemEntity>& entity, const RootEntity& ent, double timestamp)
void MemMap::readEntity(const Ref<MemEntity>& entity, const RootEntity& ent, std::chrono::milliseconds timestamp)
// Read the contents of an Atlas message into an entity
{
entity->m_lastUpdated = timestamp;
@ -129,7 +127,7 @@ void MemMap::applyTypePropertiesToEntity(const Ref<MemEntity>& entity) {
}
}
void MemMap::updateEntity(const Ref<MemEntity>& entity, const RootEntity& ent, double timestamp)
void MemMap::updateEntity(const Ref<MemEntity>& entity, const RootEntity& ent, std::chrono::milliseconds timestamp)
// Update contents of entity an Atlas message.
{
assert(entity != nullptr);
@ -148,8 +146,8 @@ void MemMap::updateEntity(const Ref<MemEntity>& entity, const RootEntity& ent, d
}
Ref<MemEntity> MemMap::newEntity(RouterId id,
const RootEntity& ent, double timestamp)
Ref<MemEntity> MemMap::newEntity(const RouterId& id,
const RootEntity& ent, std::chrono::milliseconds timestamp)
// Create a new entity from an Atlas message.
{
assert(m_entities.find(id.m_intId) == m_entities.end());
@ -190,7 +188,7 @@ void MemMap::sendLook(OpVector& res) {
}
}
Ref<MemEntity> MemMap::addId(RouterId id)
Ref<MemEntity> MemMap::addId(const RouterId& id)
// Queue the ID of an entity we are interested in
{
assert(!id.m_id.empty());
@ -297,7 +295,7 @@ void MemMap::addContents(const RootEntity& ent)
}
}
Ref<MemEntity> MemMap::updateAdd(const RootEntity& ent, const double& d)
Ref<MemEntity> MemMap::updateAdd(const RootEntity& ent, std::chrono::milliseconds d)
// Update an entity in our memory, from an Atlas message
// The mind code relies on this function never sending a Sight to
// be sure that seeing something created does not imply that the created
@ -394,7 +392,7 @@ EntityVector MemMap::findByType(const std::string& what)
EntityVector MemMap::findByLocation(const EntityLocation& loc,
WFMath::CoordType radius,
const std::string& what) {
const std::string& what) const {
//TODO: move to awareness
EntityVector res;
auto place = loc.m_parent;
@ -438,14 +436,14 @@ EntityVector MemMap::findByLocation(const EntityLocation& loc,
return res;
}
void MemMap::check(const double& time) {
void MemMap::check(std::chrono::milliseconds time) {
//Check if the entity hasn't been seen the last 600 seconds, and if so removes it.
if (m_checkIterator == m_entities.end()) {
m_checkIterator = m_entities.begin();
} else {
auto me = m_checkIterator->second;
assert(me);
if (me->getType() && !me->isVisible() && (time - me->lastSeen()) > 600 &&
if (me->getType() && !me->isVisible() && (time - me->lastSeen()) > std::chrono::seconds(600) &&
(me->m_contains == nullptr || me->m_contains->empty())) {
m_checkIterator = m_entities.erase(m_checkIterator);

View file

@ -83,18 +83,18 @@ protected:
std::deque<Operation> m_typeResolverOps;
void readEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, double timestamp);
void readEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp);
void updateEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, double timestamp);
void updateEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp);
Ref<MemEntity> newEntity(RouterId,
const Atlas::Objects::Entity::RootEntity&, double timestamp);
Ref<MemEntity> newEntity(const RouterId&,
const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp);
void addContents(const Atlas::Objects::Entity::RootEntity&);
Ref<MemEntity> addId(RouterId id);
Ref<MemEntity> addId(const RouterId& id);
void applyTypePropertiesToEntity(const Ref<MemEntity>& entity);
static void applyTypePropertiesToEntity(const Ref<MemEntity>& entity);
public:
@ -124,7 +124,7 @@ public:
Ref<MemEntity> getAdd(const std::string& id);
Ref<MemEntity> updateAdd(const Atlas::Objects::Entity::RootEntity&, const double&);
Ref<MemEntity> updateAdd(const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds);
///\brief Add an entity-related memory or update it if it already exists
///@param id - the id of entity to which we relate the memory
@ -152,9 +152,9 @@ public:
EntityVector findByLocation(const EntityLocation& where,
WFMath::CoordType radius,
const std::string& what);
const std::string& what) const;
void check(const double&);
void check(std::chrono::milliseconds t);
void flush();

View file

@ -108,14 +108,14 @@ Py::Object CyPy_MemMap::find_by_type(const Py::Tuple& args) {
Py::Object CyPy_MemMap::updateAdd(const Py::Tuple& args) {
args.verify_length(2);
double time = verifyNumeric(args[1]);
std::chrono::milliseconds time(verifyLong(args[1]));
if (args[0].isDict()) {
auto element = CyPy_Element::dictAsElement(Py::Dict(args[0]));
try {
Root obj = m_value->getTypeStore().getFactories().createObject(element);
RootEntity ent = Atlas::Objects::smart_dynamic_cast<RootEntity>(obj);
auto ent = Atlas::Objects::smart_dynamic_cast<RootEntity>(obj);
if (!ent.isValid()) {
throw Py::TypeError("arg is a Message that does not represent an entity");
}

View file

@ -99,8 +99,9 @@ void CyPy_Operation::init_type() {
PYCXX_ADD_VARARGS_METHOD(set_refno, setRefno, PYCXX_SIG_DOC("set_refno(long)", "Sets the reference number."));
PYCXX_ADD_VARARGS_METHOD(set_from, setFrom, PYCXX_SIG_DOC("set_from(string)", "Sets from which entity the operation is from."));
PYCXX_ADD_VARARGS_METHOD(set_to, setTo, PYCXX_SIG_DOC("set_to(string)", "Sets to which entity the operation is directed."));
PYCXX_ADD_VARARGS_METHOD(set_seconds, setSeconds, "");
PYCXX_ADD_VARARGS_METHOD(set_stamp, setStamp, "");
PYCXX_ADD_VARARGS_METHOD(set_future_seconds, setFutureSeconds, "");
PYCXX_ADD_VARARGS_METHOD(set_future_milliseconds, setFutureMilliseconds, "");
PYCXX_ADD_VARARGS_METHOD(set_name, setName, "");
PYCXX_ADD_VARARGS_METHOD(set_args, setArgs, PYCXX_SIG_DOC("set_args(sequence)", "Sets the argument list. The supplied sequence could be any of Operation|ElementMap|RootEntity|Python Dict."));
PYCXX_ADD_NOARGS_METHOD(get_serialno, getSerialno, "");
@ -108,8 +109,9 @@ void CyPy_Operation::init_type() {
PYCXX_ADD_NOARGS_METHOD(get_refno, getRefno, "");
PYCXX_ADD_NOARGS_METHOD(get_from, getFrom, "");
PYCXX_ADD_NOARGS_METHOD(get_to, getTo, "");
PYCXX_ADD_NOARGS_METHOD(get_seconds, getSeconds, "");
PYCXX_ADD_NOARGS_METHOD(get_stamp, getStamp, "");
PYCXX_ADD_NOARGS_METHOD(get_future_seconds, getFutureSeconds, "");
PYCXX_ADD_NOARGS_METHOD(get_future_milliseconds, getFutureMilliseconds, "");
PYCXX_ADD_NOARGS_METHOD(get_args, getArgs, "");
PYCXX_ADD_NOARGS_METHOD(get_name, get_name, "");
PYCXX_ADD_NOARGS_METHOD(copy, copy, "Copies the operation into a new instance.");
@ -169,15 +171,21 @@ Py::Object CyPy_Operation::setTo(const Py::Tuple& args) {
return Py::None();
}
Py::Object CyPy_Operation::setSeconds(const Py::Tuple& args) {
Py::Object CyPy_Operation::setStamp(const Py::Tuple& args) {
args.verify_length(1);
m_value->setSeconds(verifyFloat(args.front()));
m_value->setStamp(verifyLong(args.front()));
return Py::None();
}
Py::Object CyPy_Operation::setFutureSeconds(const Py::Tuple& args) {
args.verify_length(1);
m_value->setFutureSeconds(verifyFloat(args.front()));
m_value->setFutureMilliseconds(verifyNumeric(args.front()) * 1000.0);
return Py::None();
}
Py::Object CyPy_Operation::setFutureMilliseconds(const Py::Tuple& args) {
args.verify_length(1);
m_value->setFutureMilliseconds(verifyLong(args.front()));
return Py::None();
}
@ -234,12 +242,16 @@ Py::Object CyPy_Operation::getTo() {
return Py::String(m_value->getTo());
}
Py::Object CyPy_Operation::getSeconds() {
return Py::Float(m_value->getSeconds());
Py::Object CyPy_Operation::getStamp() {
return Py::Long(m_value->getStamp());
}
Py::Object CyPy_Operation::getFutureSeconds() {
return Py::Float(m_value->getFutureSeconds());
return Py::Float(m_value->getFutureMilliseconds() / 1000.0);
}
Py::Object CyPy_Operation::getFutureMilliseconds() {
return Py::Long(m_value->getFutureMilliseconds());
}
Py::Object CyPy_Operation::getName() {
@ -322,7 +334,9 @@ Py::Object CyPy_Operation::getattro(const Py::String& name) {
if (nameStr == "parent") {
return Py::String(m_value->getParent());
}
if (nameStr == "future_milliseconds") {
return getFutureMilliseconds();
}
if (nameStr == "future_seconds") {
return getFutureSeconds();
}
@ -385,7 +399,11 @@ int CyPy_Operation::setattro(const Py::String& name, const Py::Object& attr) {
}
if (nameStr == "future_seconds") {
m_value->setFutureSeconds(verifyFloat(attr));
m_value->setFutureMilliseconds(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<float>(verifyNumeric(attr))).count());
return 0;
}
if (nameStr == "future_milliseconds") {
m_value->setFutureMilliseconds(verifyLong(attr));
return 0;
}
if (nameStr == "name") {

View file

@ -71,14 +71,18 @@ protected:
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setTo);
Py::Object setSeconds(const Py::Tuple& args);
Py::Object setStamp(const Py::Tuple& args);
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setSeconds);
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setStamp);
Py::Object setFutureSeconds(const Py::Tuple& args);
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setFutureSeconds);
Py::Object setFutureMilliseconds(const Py::Tuple& args);
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setFutureMilliseconds);
Py::Object setName(const Py::Tuple& args);
PYCXX_VARARGS_METHOD_DECL(CyPy_Operation, setName);
@ -107,14 +111,18 @@ protected:
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getTo);
Py::Object getSeconds();
Py::Object getStamp();
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getSeconds);
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getStamp);
Py::Object getFutureSeconds();
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getFutureSeconds);
Py::Object getFutureMilliseconds();
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getFutureMilliseconds);
Py::Object getName();
PYCXX_NOARGS_METHOD_DECL(CyPy_Operation, getName);

View file

@ -40,7 +40,7 @@ HandlerResult ActionsProperty::TickOperation(LocatedEntity& owner, const Operati
m_tickOutstanding = {};
//Remove any actions that are at end_time.
auto now = op->getSeconds();
auto now = std::chrono::milliseconds(op->getStamp());
bool hadChanges = false;
for (auto I = m_data.begin(); I != m_data.end();) {
@ -80,7 +80,7 @@ HandlerResult ActionsProperty::operation(LocatedEntity& entity, const Operation&
}
void ActionsProperty::enqueueTickOp(const LocatedEntity& entity, OpVector& res) {
std::optional<double> nearestExpiry;
std::optional<std::chrono::milliseconds> nearestExpiry;
for (auto& entry: m_data) {
if (entry.second.endTime) {
if (!nearestExpiry || *nearestExpiry > *entry.second.endTime) {
@ -98,7 +98,7 @@ void ActionsProperty::enqueueTickOp(const LocatedEntity& entity, OpVector& res)
tick->setArgs1(std::move(anon));
tick->setTo(entity.getId());
tick->setFrom(entity.getId());
tick->setSeconds(*nearestExpiry);
tick->setStamp(nearestExpiry->count());
res.emplace_back(std::move(tick));
m_tickOutstanding = nearestExpiry;
@ -115,9 +115,9 @@ ActionsProperty* ActionsProperty::copy() const {
int ActionsProperty::get(Atlas::Message::Element& val) const {
Atlas::Message::MapType map;
for (auto& entry: m_data) {
Atlas::Message::MapType mapEntry{{"start_time", entry.second.startTime}};
Atlas::Message::MapType mapEntry{{"start_time", entry.second.startTime.count()}};
if (entry.second.endTime) {
mapEntry.emplace("end_time", *entry.second.endTime);
mapEntry.emplace("end_time", entry.second.endTime->count());
}
map.emplace(entry.first, std::move(mapEntry));

View file

@ -22,6 +22,7 @@
#include "common/Property.h"
#include "modules/Ref.h"
#include <optional>
#include <chrono>
class ActionsProperty : public PropertyBase {
public:
@ -31,8 +32,8 @@ public:
struct Action {
double startTime;
std::optional<double> endTime;
std::chrono::milliseconds startTime;
std::optional<std::chrono::milliseconds> endTime;
};
ActionsProperty();
@ -59,7 +60,7 @@ protected:
std::map<std::string, Action> m_data;
std::optional<double> m_tickOutstanding;
std::optional<std::chrono::milliseconds> m_tickOutstanding;
ActionsProperty(const ActionsProperty& rhs) = default;

View file

@ -57,7 +57,7 @@ void AdminMind::externalOperation(const Operation& op, Link& link) {
if (op->isDefaultTo()) {
cy_debug_print("AdminMind handling op normally");
ExternalMind::externalOperation(op, link);
} else if (op->getTo() == getId() && op->isDefaultFutureSeconds()) {
} else if (op->getTo() == getId() && op->isDefaultFutureMilliseconds()) {
//Send directly to the entity, bypassing any normal Thought filtering
cy_debug_print("Creator handling op ");
OpVector lres;

View file

@ -128,6 +128,10 @@ std::chrono::steady_clock::duration BaseWorld::getTime() const {
return m_timeProviderFn();
// return (std::chrono::steady_clock::now() - m_initTime);
}
std::chrono::milliseconds BaseWorld::getTimeAsMilliseconds() const {
return duration_cast<std::chrono::milliseconds>(m_timeProviderFn());
// return (std::chrono::steady_clock::now() - m_initTime);
}
float BaseWorld::getTimeAsSeconds() const {
return std::chrono::duration_cast<std::chrono::duration<float>>(getTime()).count();

View file

@ -104,6 +104,8 @@ public:
/// \brief Read only accessor for the in-game time.
std::chrono::steady_clock::duration getTime() const;
std::chrono::milliseconds getTimeAsMilliseconds() const;
float getTimeAsSeconds() const;
/// \brief Get the time the world has been running since the server started.

View file

@ -132,7 +132,7 @@ void ExternalMind::operation(const Operation& op, OpVector& res) {
} else {
//Only sent ops that inherit from "Info" to the client.
if (op->instanceOf(Atlas::Objects::Operation::INFO_NO)) {
op->setSeconds(BaseWorld::instance().getTimeAsSeconds());
op->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
m_link->send(op);
}
}
@ -222,7 +222,7 @@ void ExternalMind::RelayOperation(const Operation& op, OpVector& res) {
pruneOp->setFrom(m_entity->getId());
pruneOp->setRefno(serialNo);
//5 seconds should be more than enough.
pruneOp->setFutureSeconds(5);
pruneOp->setFutureMilliseconds(5'000);
//Set id to direct it to this mind
pruneOp->setId(getId());

View file

@ -639,9 +639,9 @@ void MindsProperty::mind2body(LocatedEntity& ent, const Operation& op, OpVector&
spdlog::error("Operation \"{}\" from mind with TO set. {}", op->getParent(), ent.describeEntity());
return;
}
if (!op->isDefaultFutureSeconds() && op->getClassNo() != Atlas::Objects::Operation::TICK_NO) {
if (!op->isDefaultFutureMilliseconds() && op->getClassNo() != Atlas::Objects::Operation::TICK_NO) {
spdlog::error("Operation \"{}\" from mind with "
"FUTURE_SECONDS set. {}", op->getParent(), ent.describeEntity());
"FUTURE_MILLISECONDS set. {}", op->getParent(), ent.describeEntity());
}
auto op_no = op->getClassNo();
switch (op_no) {

View file

@ -79,7 +79,7 @@ void ModeProperty::apply(LocatedEntity& entity) {
Atlas::Objects::Operation::Move moveOp;
moveOp->setTo(entity.getId());
moveOp->setSeconds(BaseWorld::instance().getTimeAsSeconds());
moveOp->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
moveOp->setArgs1(move_arg);
entity.sendWorld(moveOp);
}
@ -106,7 +106,7 @@ void ModeProperty::apply(LocatedEntity& entity) {
Atlas::Objects::Operation::Move moveOp;
moveOp->setTo(entity.getId());
moveOp->setSeconds(BaseWorld::instance().getTimeAsSeconds());
moveOp->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
moveOp->setArgs1(move_arg);
entity.sendWorld(moveOp);

View file

@ -57,7 +57,6 @@
#include <memory>
#include <unordered_set>
#include <chrono>
#include <optional>
#include <algorithm>
#include <fmt/format.h>
@ -76,9 +75,12 @@ using Atlas::Objects::Operation::Disappearance;
using Atlas::Objects::Operation::Move;
using Atlas::Objects::smart_dynamic_cast;
namespace {
float to_seconds(std::chrono::milliseconds duration) {
return std::chrono::duration_cast<std::chrono::duration<float>>(duration).count();
}
std::unique_ptr<btAxisSweep3> createVisibilityBroadphase(const LocatedEntity& entity, float scalingFactor) {
auto bbox = ScaleProperty::scaledBbox(entity);
if (!bbox.isValid()) {
@ -199,7 +201,7 @@ const std::array<double, 10> VISIBILITY_DISTANCE_THRESHOLDS = {10.0, 20, 30, 50,
* The amount of time between each tick, in seconds.
* The simulation will happen at 60hz, but the tick size determines how often entities are processed and operations are sent.
*/
const double TICK_SIZE = 1.0 / 15.0;
const std::chrono::milliseconds TICK_SIZE(66);
/**
* The base size of the view sphere for a perceptive entity. Everything within this radius will be visible.
@ -664,17 +666,17 @@ HandlerResult PhysicalDomain::operation(LocatedEntity& entity, const Operation&
HandlerResult PhysicalDomain::tick_handler(LocatedEntity& entity, const Operation& op, OpVector& res) {
if (!op->getArgs().empty() && !op->getArgs().front()->isDefaultName() && op->getArgs().front()->getName() == "domain") {
double timeNow = op->getSeconds();
double tickSize = TICK_SIZE;
auto timeNow = std::chrono::milliseconds(op->getStamp());
auto tickSize = TICK_SIZE;
Atlas::Message::Element elem;
if (op->copyAttr("lastTick", elem) == 0 && elem.isFloat()) {
tickSize = timeNow - elem.Float();
if (op->copyAttr("lastTick", elem) == 0 && elem.isInt()) {
tickSize = timeNow - std::chrono::milliseconds(elem.Int());
}
tick(tickSize, res);
auto tickOp = scheduleTick(entity);
tickOp->setSeconds(timeNow + TICK_SIZE);
tickOp->setAttr("lastTick", timeNow);
tickOp->setStamp((timeNow + TICK_SIZE).count());
tickOp->setAttr("lastTick", timeNow.count());
res.emplace_back(std::move(tickOp));
return OPERATION_BLOCKED;
@ -2175,7 +2177,7 @@ void PhysicalDomain::applyNewPositionForEntity(BulletEntry& entry, const WFMath:
}
void PhysicalDomain::applyDestination(double tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp) {
void PhysicalDomain::applyDestination(std::chrono::milliseconds tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp) {
bool hasDestination = destinationProp.data().isValid();
bool hasPropel = propelProp && propelProp->data().isValid() && propelProp->data() != WFMath::Vector<3>::ZERO();
@ -2203,10 +2205,11 @@ void PhysicalDomain::applyDestination(double tickSize, BulletEntry& entry, const
if (hasPropel) {
propelSpeed = propelProp->data().mag();
}
auto ticksAsSeconds = to_seconds(tickSize);
//Check if we should lower our speed to arrive within the next tick.
if (propelSpeed * speed * tickSize > distance) {
propelSpeed = speed / (distance * tickSize);
if (propelSpeed * speed * ticksAsSeconds > distance) {
propelSpeed = speed / (distance * ticksAsSeconds);
}
auto direction = btDestination - currentPos;
@ -2454,7 +2457,7 @@ void PhysicalDomain::applyTransformInternal(BulletEntry& entry,
rigidBody->activate();
}
}
processMovedEntity(entry, 0);
processMovedEntity(entry, std::chrono::milliseconds{0});
}
}
@ -2613,15 +2616,15 @@ void PhysicalDomain::sendMoveSight(BulletEntry& entry, bool posChange, bool velo
setOp->setArgs1(move_arg);
setOp->setFrom(entity.getId());
setOp->setTo(entity.getId());
double seconds = BaseWorld::instance().getTimeAsSeconds();
setOp->setSeconds(seconds);
auto now = BaseWorld::instance().getTimeAsMilliseconds();
setOp->setStamp(now.count());
for (BulletEntry* observer: entry.observingThis) {
Sight s;
s->setArgs1(setOp);
s->setTo(observer->entity.getId());
s->setFrom(entity.getId());
s->setSeconds(seconds);
s->setStamp(now.count());
entity.sendWorld(s);
}
@ -2629,7 +2632,7 @@ void PhysicalDomain::sendMoveSight(BulletEntry& entry, bool posChange, bool velo
}
}
void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, double timeSinceLastUpdate) {
void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, std::chrono::milliseconds timeSinceLastUpdate) {
auto& pos = bulletEntry.positionProperty.data();
auto& orientation = bulletEntry.orientationProperty.data();
auto& velocity = bulletEntry.velocityProperty.data();
@ -2651,7 +2654,7 @@ void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, double timeSin
posChange = true;
} else {
if (lastSentLocation.velocity.isValid()) {
auto projectedPosition = lastSentLocation.pos + (lastSentLocation.velocity * timeSinceLastUpdate);
auto projectedPosition = lastSentLocation.pos + (lastSentLocation.velocity * to_seconds(timeSinceLastUpdate));
if (WFMath::Distance(pos, projectedPosition) > 0.5) {
posChange = true;
}
@ -2746,11 +2749,12 @@ void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, double timeSin
updateTerrainMod(bulletEntry);
}
void PhysicalDomain::tick(double tickSize, OpVector& res) {
void PhysicalDomain::tick(std::chrono::milliseconds tickSize, OpVector& res) {
// CProfileManager::Reset();
// CProfileManager::Increment_Frame_Counter();
rmt_ScopedCPUSample(PhysicalDomain_tick, 0)
auto start = std::chrono::steady_clock::now();
/**
* An entry of a projectile hitting another entry.
@ -2788,6 +2792,7 @@ void PhysicalDomain::tick(double tickSize, OpVector& res) {
if (simulationSpeedProp) {
tickSize *= simulationSpeedProp->data();
}
auto tickSizeInSeconds = to_seconds(tickSize);
projectileCollisions.clear();
@ -2842,7 +2847,7 @@ void PhysicalDomain::tick(double tickSize, OpVector& res) {
//Step simulations with 60 hz.
m_dynamicsWorld->stepSimulation((float) tickSize, static_cast<int>(60 * tickSize));
m_dynamicsWorld->stepSimulation(tickSizeInSeconds, static_cast<int>(60 * tickSizeInSeconds));
auto interim = std::chrono::steady_clock::now() - start;
//CProfileManager::dumpAll();
@ -2949,20 +2954,20 @@ void PhysicalDomain::tick(double tickSize, OpVector& res) {
processDirtyTerrainAreas();
auto duration = std::chrono::steady_clock::now() - start;
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(duration).count();
auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(duration);
if (debug_flag) {
spdlog::log(microseconds > 3000 ? spdlog::level::warn : spdlog::level::info,
spdlog::log(microseconds.count() > 3000 ? spdlog::level::warn : spdlog::level::info,
"Physics took {} μs (just stepSimulation {} μs, visibility {} μs, tick size {} μs, visibility queue: {}, postTick: {} μs, moving count: {}).",
microseconds,
microseconds.count(),
std::chrono::duration_cast<std::chrono::microseconds>(interim).count(),
std::chrono::duration_cast<std::chrono::microseconds>(visDuration).count(),
static_cast<long>(tickSize * 1000000),
std::chrono::duration_cast<std::chrono::microseconds>(tickSize).count(),
m_visibilityRecalculateQueue.size(),
std::chrono::duration_cast<std::chrono::microseconds>(postDuration).count(),
movingSize
);
}
s_processTimeUs += microseconds;
s_processTimeUs += microseconds.count();
}
void PhysicalDomain::processWaterBodies() {

View file

@ -34,6 +34,7 @@
#include <array>
#include <set>
#include <unordered_set>
#include <chrono>
namespace Mercator {
class Segment;
@ -104,7 +105,7 @@ public:
HandlerResult operation(LocatedEntity& e, const Operation& op, OpVector& res) override;
void tick(double t, OpVector& res);
void tick(std::chrono::milliseconds t, OpVector& res);
std::vector<CollisionEntry> queryCollision(const WFMath::Ball<3>& sphere) const override;
@ -451,7 +452,7 @@ protected:
void sendMoveSight(BulletEntry& bulletEntry, bool posChange, bool velocityChange, bool orientationChange, bool angularChange, bool modeChanged);
void processMovedEntity(BulletEntry& bulletEntry, double timeSinceLastUpdate);
void processMovedEntity(BulletEntry& bulletEntry, std::chrono::milliseconds timeSinceLastUpdate);
void updateVisibilityOfDirtyEntities(OpVector& res);
@ -467,7 +468,7 @@ protected:
void processDirtyTerrainAreas();
void applyDestination(double tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp);
void applyDestination(std::chrono::milliseconds tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp);
void applyPropel(BulletEntry& entry, btVector3 propel);
@ -479,8 +480,9 @@ protected:
void processWaterBodies();
std::shared_ptr<btCollisionShape> createCollisionShapeForEntry(LocatedEntity& entity,
const WFMath::AxisBox<3>& bbox, float mass,
btVector3& centerOfMassOffse);
const WFMath::AxisBox<3>& bbox,
float mass,
btVector3& centerOfMassOffset);
/**
* Transform any entities that are resting on the supplied entity.

View file

@ -47,7 +47,7 @@ Task::Task(UsageInstance usageInstance, Py::Object script) :
m_rate(-1),
m_start_time(-1),
m_script(std::move(script)),
m_tick_interval(1.0),
m_tick_interval(1'000),
m_usageInstance(std::move(usageInstance)) {
}
@ -80,18 +80,18 @@ Operation Task::nextTick(const std::string& id, const Operation& op) {
tick->setArgs1(tick_arg);
tick->setTo(m_usageInstance.actor->getId());
//Default to once per second.
double futureSeconds = 1.0;
std::chrono::milliseconds futureMilliseconds{1'000};
if (m_tick_interval) {
futureSeconds = *m_tick_interval;
futureMilliseconds = *m_tick_interval;
} else if (m_duration) {
futureSeconds = *m_duration;
futureMilliseconds = *m_duration;
}
//If there's a duration, adjust the tick interval so it matches the duration end
if (m_duration) {
futureSeconds = std::min(futureSeconds, *m_duration - (op->getSeconds() - m_start_time));
futureMilliseconds = std::min(futureMilliseconds, *m_duration - (std::chrono::milliseconds(op->getStamp()) - m_start_time));
}
tick->setFutureSeconds(futureSeconds);
tick->setFutureMilliseconds(futureMilliseconds.count());
return tick;
}
@ -114,7 +114,7 @@ void Task::setAttr(const std::string& attr,
}
void Task::initTask(const std::string& id, OpVector& res) {
m_start_time = m_usageInstance.op->getSeconds();
m_start_time = std::chrono::milliseconds{m_usageInstance.op->getStamp()};
if (m_script.isNull()) {
spdlog::warn("Task script failed");
irrelevant();
@ -132,8 +132,8 @@ void Task::initTask(const std::string& id, OpVector& res) {
bool Task::tick(const std::string& id, const Operation& op, OpVector& res) {
bool hadChange = false;
if (m_duration) {
auto elapsed = (op->getSeconds() - m_start_time);
auto newProgress = std::min(1.0, elapsed / *m_duration);
auto elapsed = (std::chrono::milliseconds(op->getStamp()) - m_start_time);
auto newProgress = std::min(1.0, (double) elapsed.count() / (double) m_duration->count());
if (newProgress != m_progress) {
m_progress = newProgress;
hadChange = true;
@ -201,7 +201,7 @@ void Task::startAction(std::string actionName, OpVector& res) {
}
m_action = actionName;
auto& actionsProp = m_usageInstance.actor->requirePropertyClassFixed<ActionsProperty>();
actionsProp.addAction(*m_usageInstance.actor, res, actionName, {BaseWorld::instance().getTimeAsSeconds()});
actionsProp.addAction(*m_usageInstance.actor, res, actionName, {BaseWorld::instance().getTimeAsMilliseconds()});
}
void Task::stopAction(OpVector& res) {

View file

@ -61,7 +61,7 @@ protected:
/// \brief Rate of progress towards task completion
double m_rate;
double m_start_time;
std::chrono::milliseconds m_start_time;
/// \brief Additional task attributes
Atlas::Message::MapType m_attr;
@ -83,9 +83,9 @@ public:
static std::function<Py::Object(const std::map<std::string, std::vector<UsageParameter::UsageArg>>& args)> argsCreator;
std::optional<double> m_duration;
std::optional<std::chrono::milliseconds> m_duration;
std::optional<double> m_tick_interval;
std::optional<std::chrono::milliseconds> m_tick_interval;
UsageInstance m_usageInstance;
@ -94,9 +94,13 @@ public:
~Task() override;
void callUsageScriptFunction(const std::string& function, const std::map<std::string, std::vector<UsageParameter::UsageArg>>& args, OpVector& res);
void callUsageScriptFunction(const std::string& function,
const std::map<std::string, std::vector<UsageParameter::UsageArg>>& args,
OpVector& res);
void callScriptFunction(const std::string& function, const Py::Tuple& args, OpVector& res);
void callScriptFunction(const std::string& function,
const Py::Tuple& args,
OpVector& res);
/// \brief Flag this task as obsolete
void irrelevant();

View file

@ -55,7 +55,7 @@ int TasksProperty::get(Atlas::Message::Element& val) const {
taskMap.emplace("progress", progress);
}
if (task->m_duration) {
taskMap.emplace("rate", 1.0f / *task->m_duration);
taskMap.emplace("rate", 1.0f / std::chrono::duration_cast<std::chrono::duration<float>>(*task->m_duration).count());
}
if (!task->usages().empty()) {
ListType usagesList;

View file

@ -126,7 +126,7 @@ void Thing::MoveOperation(const Operation& op, OpVector& res) {
error(op, "Move has no argument", res, getId());
return;
}
RootEntity ent = smart_dynamic_cast<RootEntity>(args.front());
auto ent = smart_dynamic_cast<RootEntity>(args.front());
if (!ent.isValid() || ent->isDefaultId()) {
error(op, "Move op arg is malformed", res, getId());
return;
@ -354,7 +354,7 @@ void Thing::updateProperties(const Operation& op, OpVector& res) {
Set set;
set->setTo(getId());
set->setFrom(getId());
set->setSeconds(op->getSeconds());
set->setStamp(op->getStamp());
set->setArgs1(set_arg);
Sight sight;
@ -368,7 +368,7 @@ void Thing::updateProperties(const Operation& op, OpVector& res) {
Set set;
set->setTo(getId());
set->setFrom(getId());
set->setSeconds(op->getSeconds());
set->setStamp(op->getStamp());
set->setArgs1(set_arg_protected);
Sight sight;
@ -382,7 +382,7 @@ void Thing::updateProperties(const Operation& op, OpVector& res) {
Set set;
set->setTo(getId());
set->setFrom(getId());
set->setSeconds(op->getSeconds());
set->setStamp(op->getStamp());
set->setArgs1(set_arg_private);
Sight sight;
@ -606,7 +606,7 @@ void Thing::moveOurselves(const Operation& op, const RootEntity& ent, OpVector&
setAttrValue("_propel", attr_propel);
}
double current_time = BaseWorld::instance().getTimeAsSeconds();
auto current_time = BaseWorld::instance().getTimeAsMilliseconds();
//We can only move if there's a domain
Domain* domain = nullptr;
@ -616,7 +616,7 @@ void Thing::moveOurselves(const Operation& op, const RootEntity& ent, OpVector&
//Send a Sight of the Move to any current observers. Do this before we might alter location.
Operation m = op.copy();
RootEntity marg = smart_dynamic_cast<RootEntity>(m->getArgs().front());
auto marg = smart_dynamic_cast<RootEntity>(m->getArgs().front());
assert(marg.isValid());
// m_location.addToEntity(marg);
// {
@ -631,8 +631,8 @@ void Thing::moveOurselves(const Operation& op, const RootEntity& ent, OpVector&
// }
// }
if (!m->hasAttrFlag(Atlas::Objects::Operation::SECONDS_FLAG)) {
m->setSeconds(current_time);
if (!m->hasAttrFlag(Atlas::Objects::STAMP_FLAG)) {
m->setStamp(current_time.count());
}
Sight s;

View file

@ -44,7 +44,7 @@ void TransientProperty::apply(LocatedEntity& ent) {
Delete deleteOp;
deleteOp->setTo(ent.getId());
deleteOp->setFutureSeconds(m_data);
deleteOp->setFutureMilliseconds(static_cast<std::int64_t >(m_data * 1'000.0));
Anonymous entity_arg;
entity_arg->setId(ent.getId());

View file

@ -148,7 +148,7 @@ HandlerResult UsagesProperty::use_handler(LocatedEntity& e,
}
rop->setFrom(actor->getId());
rop->setTo(e.getId());
rop->setSeconds(op->getSeconds());
rop->setStamp(op->getStamp());
if (argOp->getArgs().empty()) {
actor->error(op, "Use arg op has no arguments; one expected.", res, actor->getId());

View file

@ -254,7 +254,7 @@ void World::sendRelayToEntity(const LocatedEntity& to, const Operation& op, sigc
pruneOp->setTo(getId());
pruneOp->setFrom(getId());
pruneOp->setRefno(serialNo);
pruneOp->setFutureSeconds(5);
pruneOp->setFutureMilliseconds(5'000);
sendWorld(pruneOp);
}

View file

@ -182,12 +182,14 @@ void WorldRouter::resumeWorld() {
}
void WorldRouter::resolveDispatchTimeForOp(Atlas::Objects::Operation::RootOperationData& op) {
if (!op.isDefaultFutureSeconds()) {
double t = getTimeAsSeconds() + (op.getFutureSeconds() * consts::time_multiplier);
op.setSeconds(t);
op.removeAttrFlag(Atlas::Objects::Operation::FUTURE_SECONDS_FLAG);
} else if (op.isDefaultSeconds()) {
op.setSeconds(getTimeAsSeconds());
if (!op.isDefaultFutureMilliseconds()) {
std::chrono::milliseconds future((int64_t) ((double) op.getFutureMilliseconds() * consts::time_multiplier));
auto t = getTimeAsMilliseconds() + future;
op.setStamp(t.count());
op.removeAttrFlag(Atlas::Objects::Operation::FUTURE_MILLISECONDS_FLAG);
} else if (op.isDefaultStamp()) {
op.setStamp(getTimeAsMilliseconds().count());
}
}
@ -244,13 +246,13 @@ void WorldRouter::deliverTo(const Operation& op, Ref<LocatedEntity> ent) {
//(to be resent when the world is resumed) and not process it now.
if (m_isSuspended) {
if (op->getClassNo() == Atlas::Objects::Operation::TICK_NO) {
m_suspendedQueue.push(OpQueEntry<LocatedEntity>(op, std::move(ent), m_suspendedQueue.size()));
m_suspendedQueue.emplace(op, std::move(ent), m_suspendedQueue.size());
return;
}
}
//Set the time of when this op is dispatched. That way, other components in the system can
//always use the seconds set on the op to know the current time.
op->setSeconds(std::chrono::duration_cast<std::chrono::duration<double>>(getTime()).count());
op->setStamp(getTimeAsMilliseconds().count());
OpVector res;
cy_debug_print("WorldRouter::deliverTo begin {"

View file

@ -177,8 +177,9 @@ Py::Object CyPy_Entity::start_action(const Ref<Entity>& entity, const Py::Tuple&
args.verify_length(2);
auto& actionsProp = entity->requirePropertyClassFixed<ActionsProperty>();
auto duration = verifyFloat(args[1]);
auto startTime = BaseWorld::instance().getTimeAsSeconds();
//Use seconds in the Python code
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<float>(verifyFloat(args[1])));
auto startTime = BaseWorld::instance().getTimeAsMilliseconds();
actionsProp.addAction(*entity, res, verifyString(args[0]), {startTime, startTime + duration});
return CyPy_Oplist::wrap(std::move(res));

View file

@ -173,13 +173,15 @@ Py::Object CyPy_Task::getattro(const Py::String& name) {
if (!m_value->m_duration) {
return Py::None();
}
return Py::Float(*m_value->m_duration);
//Use seconds in the Python code
return Py::Float(std::chrono::duration_cast<std::chrono::duration<float>>(*m_value->m_duration).count());
}
if (nameStr == "tick_interval") {
if (!m_value->m_tick_interval) {
return Py::None();
}
return Py::Float(*m_value->m_tick_interval);
//Use seconds in the Python code
return Py::Float(std::chrono::duration_cast<std::chrono::duration<float>>(*m_value->m_tick_interval).count());
}
if (nameStr == "name") {
return Py::String(m_value->name());
@ -249,11 +251,13 @@ int CyPy_Task::setattro(const Py::String& name, const Py::Object& attr) {
return 0;
}
if (nameStr == "duration") {
m_value->m_duration = verifyNumeric(attr);
//Use seconds in the Python code
m_value->m_duration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<float>(verifyNumeric(attr)));
return 0;
}
if (nameStr == "tick_interval") {
m_value->m_tick_interval = verifyNumeric(attr);
//Use seconds in the Python code
m_value->m_tick_interval = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<float>(verifyNumeric(attr)));
return 0;
}
if (nameStr == "name") {

View file

@ -171,7 +171,7 @@ void Account::sendUpdateToClient() {
Anonymous sight_arg;
addToEntity(sight_arg);
s->setArgs1(sight_arg);
s->setSeconds(BaseWorld::instance().getTimeAsSeconds());
s->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
m_connection->send(s);
}
}
@ -222,7 +222,7 @@ void Account::LogoutOperation(const Operation& op, OpVector& res) {
}
info->setFrom(getId());
info->setTo(getId());
info->setSeconds(BaseWorld::instance().getTimeAsSeconds());
info->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
m_connection->send(info);
return;
@ -238,7 +238,7 @@ void Account::LogoutOperation(const Operation& op, OpVector& res) {
}
info->setFrom(getId());
info->setTo(getId());
info->setSeconds(BaseWorld::instance().getTimeAsSeconds());
info->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
m_connection->send(info);
m_connection->disconnect();
}
@ -350,7 +350,7 @@ void Account::externalOperation(const Operation& op, Link& link) {
replyOp->setRefno(op->getSerialno());
}
}
replyOp->setSeconds(BaseWorld::instance().getTimeAsSeconds());
replyOp->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
}
m_connection->send(res);
}
@ -395,7 +395,7 @@ void Account::processExternalOperation(const Operation& op, OpVector& res) {
void Account::operation(const Operation& op, OpVector& res) {
if (m_connection) {
op->setSeconds(BaseWorld::instance().getTimeAsSeconds());
op->setStamp(BaseWorld::instance().getTimeAsMilliseconds().count());
m_connection->send(op);
}
}
@ -452,7 +452,7 @@ void Account::ImaginaryOperation(const Operation& op, OpVector& res) {
if (!op->isDefaultSerialno()) {
s->setRefno(op->getSerialno());
}
RootEntity arg = smart_dynamic_cast<RootEntity>(args.front());
auto arg = smart_dynamic_cast<RootEntity>(args.front());
if (!arg.isValid()) {
error(op, "Imaginary arg is malformed", res, getId());
@ -476,7 +476,7 @@ void Account::TalkOperation(const Operation& op, OpVector& res) {
return;
}
RootEntity arg = smart_dynamic_cast<RootEntity>(args.front());
auto arg = smart_dynamic_cast<RootEntity>(args.front());
if (!arg.isValid()) {
error(op, "Talk arg is malformed", res, getId());

View file

@ -17,6 +17,7 @@
#include <Atlas/Objects/Operation.h>
#include <Atlas/Objects/Entity.h>
#include "server/SystemAccount.h"
#include "Connection.h"
#include "ServerRouting.h"
@ -33,7 +34,7 @@ SystemAccount::SystemAccount(Connection* conn,
SystemAccount::~SystemAccount() = default;
const char* SystemAccount::getType() const {
return "sys";
return Atlas::Objects::Entity::SystemAccountData::default_parent;
}
bool SystemAccount::isPersisted() const {

View file

@ -44,7 +44,7 @@ std::unique_ptr<Account> TrustedConnection::newAccount(const std::string& type,
const std::string& hash,
RouterId id)
{
if (type == "sys") {
if (type == "system_account") {
return std::make_unique<SystemAccount>(this, username, hash, id);
} else if (type == "admin") {
return std::make_unique<Admin>(this, username, hash, id);

View file

@ -119,7 +119,7 @@ void Flusher::operation(const Operation& op, OpVector& res) {
res.push_back(d);
// Send a tick for a short time in the future so that
// we can look again once this entity is definitly gone.
// we can look again once this entity is definitely gone.
Tick t;
Anonymous tick_arg;
@ -127,7 +127,7 @@ void Flusher::operation(const Operation& op, OpVector& res) {
flush_context->setFromContext(t);
t->setTo(t->getFrom());
t->setFutureSeconds(0.1);
t->setStamp(100);
t->setArgs1(tick_arg);
res.push_back(t);

View file

@ -480,7 +480,7 @@ int Interactive::select(bool rewrite_prompt) {
void Interactive::updatePrompt() {
std::string designation(">");
if (m_accountType == "admin" || m_accountType == "sys") {
if (m_accountType == "admin" || m_accountType == "system_account") {
designation = "#";
} else {
designation = "$";

View file

@ -97,7 +97,7 @@ int main(int argc, char** argv) {
spdlog::debug("Attempting local connection");
if (bridge.connectLocal(localSocket) == 0) {
bridge.setup();
if (bridge.create("sys",
if (bridge.create("system_account",
create_session_username(),
fmt::format("{}{}", ::rand(), ::rand())) != 0) {
bridge.getLogin();

View file

@ -80,7 +80,7 @@ int main(int argc, char** argv) {
std::cout << "Attempting local connection" << std::endl;
if (bridge.connectLocal(localSocket) == 0) {
if (bridge.create("sys", create_session_username(), fmt::format("{}{}", ::rand(), ::rand())) != 0) {
if (bridge.create("system_account", create_session_username(), fmt::format("{}{}", ::rand(), ::rand())) != 0) {
std::cerr << "Could not create sys account." << std::endl;
return -1;
}

View file

@ -103,7 +103,7 @@ int main(int argc, char** argv) {
spdlog::debug("Attempting local connection");
if (bridge.connectLocal(localSocket) == 0) {
if (bridge.create("sys", create_session_username(),
if (bridge.create("system_account", create_session_username(),
fmt::format("{}{}", ::rand(), ::rand())) != 0) {
spdlog::error("Could not create sys account.");
return -1;

View file

@ -68,19 +68,19 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
{
Operation op;
op->setSeconds(1.0);
op->setStamp(1);
op->setRefno(1);
dispatcher.addOperationToQueue(op, entity);
}
{
Operation op;
op->setSeconds(2.0);
op->setStamp(2);
op->setRefno(2);
dispatcher.addOperationToQueue(op, entity);
}
{
Operation op;
op->setSeconds(3.0);
op->setStamp(3);
op->setRefno(3);
dispatcher.addOperationToQueue(op, entity);
}
@ -95,19 +95,19 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
//Now try with same seconds set.
{
Operation op;
op->setSeconds(1.0);
op->setStamp(1);
op->setRefno(1);
dispatcher.addOperationToQueue(op, entity);
}
{
Operation op;
op->setSeconds(1.0);
op->setStamp(1);
op->setRefno(2);
dispatcher.addOperationToQueue(op, entity);
}
{
Operation op;
op->setSeconds(1.0);
op->setStamp(1);
op->setRefno(3);
dispatcher.addOperationToQueue(op, entity);
}
@ -123,17 +123,17 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
//Now try with same seconds set.
{
Atlas::Objects::Operation::Update op;
op->setSeconds(1.0);
op->setStamp(1);
dispatcher.addOperationToQueue(op, entity);
}
{
Atlas::Objects::Operation::Appearance op;
op->setSeconds(1.0);
op->setStamp(1);
dispatcher.addOperationToQueue(op, entity);
}
{
Atlas::Objects::Operation::Update op;
op->setSeconds(1.0);
op->setStamp(1);
dispatcher.addOperationToQueue(op, entity);
}
@ -146,32 +146,32 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
{
Operation op;
op->setSeconds(2.0);
op->setStamp(2);
op->setRefno(2);
dispatcher.addOperationToQueue(op, entity);
}
{
Operation op;
op->setSeconds(3.0);
op->setStamp(3);
op->setRefno(3);
dispatcher.addOperationToQueue(op, entity);
}
{
Operation op;
op->setSeconds(1.0);
op->setStamp(1);
op->setRefno(1);
dispatcher.addOperationToQueue(op, entity);
}
{
Operation op;
op->setRefno(4);
op->setSeconds(0);
op->setStamp(0);
dispatcher.addOperationToQueue(op, entity);
}
{
Operation op;
op->setRefno(5);
op->setSeconds(0);
op->setStamp(0);
dispatcher.addOperationToQueue(op, entity);
}

View file

@ -25,6 +25,8 @@
#include "../TestBase.h"
#include "../TestWorld.h"
using namespace std::chrono_literals;
namespace WFMath {
template<int dim>
auto format_as(const WFMath::Point<dim>& f) {
@ -148,22 +150,22 @@ struct SteeringIntegration : public Cyphesis::TestBase {
//Test with both the location, as well as the entity itself.
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0, {EntityLocation(otherEntity)}).position);
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0ms, {EntityLocation(otherEntity)}).position);
//Location should be null if we only specify a point
ASSERT_EQUAL(0, steering.resolvePosition(0, {EntityLocation{otherEntity}}).radius)
ASSERT_EQUAL(0, steering.resolvePosition(0ms, {EntityLocation{otherEntity}}).radius)
//Location should be set if we specify a new Location with a parent (even if it's with an invalid position).
// ASSERT_EQUAL(otherEntity->m_location, *steering.resolvePosition(0, {EntityLocation(otherEntity)}).location);
// ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0, {otherChildEntity->m_location}).position);
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0, {EntityLocation(otherChildEntity)}).position);
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.resolvePosition(0ms, {EntityLocation(otherChildEntity)}).position);
//The resolved location of "otherChildEntity" should be it's parent's location.
//ASSERT_EQUAL(otherEntity->m_location, *steering.resolvePosition(0, {otherChildEntity->m_location}).location);
//ASSERT_EQUAL(otherEntity->m_location, *steering.resolvePosition(0, {EntityLocation(otherChildEntity)}).location);
// ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.resolvePosition(0, {avatarChildEntity->m_location}).position);
ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.resolvePosition(0, {EntityLocation(avatarChildEntity)}).position);
ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.resolvePosition(0ms, {EntityLocation(avatarChildEntity)}).position);
// ASSERT_EQUAL(avatarEntity->m_location, *steering.resolvePosition(0, {avatarChildEntity->m_location}).location);
// ASSERT_EQUAL(avatarEntity->m_location, *steering.resolvePosition(0, {EntityLocation(avatarChildEntity)}
@ -225,22 +227,22 @@ struct SteeringIntegration : public Cyphesis::TestBase {
awareness.addEntity(*avatarEntity, *otherEntity, true);
steering.startSteering();
steering.setDestination({EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE, 0}, 0);
steering.setDestination({EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE, 0}, 0ms);
//Set to ten meters per second, so it should take one second to reach the other entity.
steering.setDesiredSpeed(10);
rebuildAllTilesFn();
auto result = steering.update(0);
auto result = steering.update(0ms);
//Since it's a straight line we can move directly to destination.
ASSERT_TRUE(result.destination.isValid());
ASSERT_EQUAL(result.destination, otherEntity->requirePropertyClassFixed<PositionProperty>().data());
ASSERT_FUZZY_EQUAL(1.0, *result.timeToNextWaypoint, epsilon);
ASSERT_EQUAL(1000, result.timeToNextWaypoint->count());
ASSERT_EQUAL(WFMath::Vector<3>(10, 0, 0), result.direction);
//Set location so that the entity should arrive in one second
avatarEntity->requirePropertyClassFixed<VelocityProperty>().data() = {10, 0, 0};
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
result = steering.update(1.0);
result = steering.update(1000ms);
ASSERT_FALSE(result.destination.isValid());
ASSERT_FALSE(result.timeToNextWaypoint);
ASSERT_TRUE(result.direction.isValid());
@ -249,7 +251,7 @@ struct SteeringIntegration : public Cyphesis::TestBase {
//Add the obstacle entity and make sure that we now divert around it.
awareness.addEntity(*avatarEntity, *obstacleEntity, false);
rebuildAllTilesFn();
result = steering.update(0);
result = steering.update(0ms);
//We can't move directly to destination this time
ASSERT_FALSE(result.destination.isValid());
@ -311,37 +313,37 @@ struct SteeringIntegration : public Cyphesis::TestBase {
rebuildAllTilesFn();
ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.getCurrentAvatarPosition(0));
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.getCurrentAvatarPosition(1.0));
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_EQUAL(WFMath::Point<3>(0, 0, 0), steering.getCurrentAvatarPosition(0ms));
ASSERT_EQUAL(WFMath::Point<3>(10, 0, 0), steering.getCurrentAvatarPosition(1000ms));
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1.0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1000ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER), epsilon);
//Overshoot the target
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(3.0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(3000ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(0, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1.0, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(3.0, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(0ms, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1000ms, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(3000ms, EntityLocation(avatarChildEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
steering.setDestination(
{EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, 0.5}, 0);
{EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, 0.5}, 0ms);
rebuildAllTilesFn();
ASSERT_FALSE(steering.isAtCurrentDestination(0));
ASSERT_TRUE(steering.isAtCurrentDestination(1.0));
ASSERT_FALSE(steering.isAtCurrentDestination(0ms));
ASSERT_TRUE(steering.isAtCurrentDestination(1000ms));
//Set velocity of the other entity too
otherEntity->requirePropertyClassFixed<VelocityProperty>().data() = {10, 0, 0};
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
//This should be true, since we supplied a fixed destination
ASSERT_TRUE(steering.isAtCurrentDestination(1.0));
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1.0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_TRUE(steering.isAtCurrentDestination(1000ms));
ASSERT_FUZZY_EQUAL(0.0, *steering.distanceTo(1000ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER), epsilon);
steering.setDestination({EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, 0.5}, 0);
steering.setDestination({EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, 0.5}, 0ms);
rebuildAllTilesFn();
//This should be false since we're now tracking the other entity (and thus take velocity into account).
ASSERT_FALSE(steering.isAtCurrentDestination(1.0));
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(1.0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
ASSERT_FALSE(steering.isAtCurrentDestination(1000ms));
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(1000ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
}
@ -374,50 +376,50 @@ struct SteeringIntegration : public Cyphesis::TestBase {
awareness.addEntity(*avatarEntity, *otherEntity, false);
steering.setAwareness(&awareness);
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER), epsilon);
//Also test with setting the destination to the entity itself
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(10.0 - otherHorizontalRadius, *steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::EDGE), epsilon);
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(10.0 - otherHorizontalRadius, *steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::EDGE), epsilon);
//If we specify the destination as a point the "EDGE" measurement on the destination won't have any effect.
ASSERT_FUZZY_EQUAL(10.0 - avatarHorizontalRadius,
*steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
*steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
Steering::MeasureType::EDGE), epsilon);
//But if we specify the destination as the entity itself the "EDGE" measurement on the destination will have an effect.
ASSERT_FUZZY_EQUAL(10.0 - otherHorizontalRadius - avatarHorizontalRadius,
*steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
*steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
//Move other away
otherEntity->requirePropertyClassFixed<PositionProperty>().data() = {20, 0, 0};
otherEntity->m_lastUpdated++;
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
ASSERT_FUZZY_EQUAL(20.0, *steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::CENTER), epsilon);
//Also test with setting the destination to the entity itself
ASSERT_FUZZY_EQUAL(20.0 - otherHorizontalRadius, *steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::EDGE), epsilon);
ASSERT_FUZZY_EQUAL(20.0 - otherHorizontalRadius, *steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::CENTER, Steering::MeasureType::EDGE), epsilon);
ASSERT_FUZZY_EQUAL(20.0 - otherHorizontalRadius - avatarHorizontalRadius,
*steering.distanceTo(0, EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
*steering.distanceTo(0ms, EntityLocation(otherEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
//Move avatar closer
avatarEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
avatarEntity->m_lastUpdated++;
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_FUZZY_EQUAL(10.0, *steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER), epsilon);
//Test invalid positions
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER))
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
Steering::MeasureType::CENTER))
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{outOfWorldEntity->m_parent, outOfWorldEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
Steering::MeasureType::EDGE))
otherEntity->requirePropertyClassFixed<PositionProperty>().data() = {};
otherEntity->m_lastUpdated++;
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER));
otherEntity->requirePropertyClassFixed<PositionProperty>().data() = {20, 0, 0};
otherEntity->m_lastUpdated++;
@ -425,26 +427,29 @@ struct SteeringIntegration : public Cyphesis::TestBase {
avatarEntity->m_lastUpdated++;
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
ASSERT_FALSE(steering.distanceTo(0, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_FALSE(steering.distanceTo(0ms, EntityLocation{otherEntity->m_parent, otherEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER));
avatarEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
avatarEntity->m_lastUpdated++;
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
//The distance to the avatar child entity should be 0.
ASSERT_TRUE(steering.distanceTo(0, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
ASSERT_TRUE(steering.distanceTo(0ms, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER));
ASSERT_FUZZY_EQUAL(0,
*steering.distanceTo(0, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::CENTER,
*steering.distanceTo(0ms, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()},
Steering::MeasureType::CENTER,
Steering::MeasureType::CENTER),
epsilon);
ASSERT_FUZZY_EQUAL(0, *steering.distanceTo(0, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
Steering::MeasureType::CENTER),
ASSERT_FUZZY_EQUAL(0,
*steering.distanceTo(0ms, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
Steering::MeasureType::CENTER),
epsilon);
ASSERT_FUZZY_EQUAL(0, *steering.distanceTo(0, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
Steering::MeasureType::EDGE),
ASSERT_FUZZY_EQUAL(0,
*steering.distanceTo(0ms, EntityLocation{avatarChildEntity->m_parent, avatarChildEntity->requirePropertyClassFixed<PositionProperty>().data()}, Steering::MeasureType::EDGE,
Steering::MeasureType::EDGE),
epsilon);
ASSERT_FUZZY_EQUAL(0, *steering.distanceTo(0, EntityLocation(avatarChildEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
ASSERT_FUZZY_EQUAL(0, *steering.distanceTo(0ms, EntityLocation(avatarChildEntity), Steering::MeasureType::EDGE, Steering::MeasureType::EDGE), epsilon);
}
@ -511,52 +516,52 @@ struct SteeringIntegration : public Cyphesis::TestBase {
double desiredDistance = 0.5;
steering.setDestination({{EntityLocation(otherEntity)}, Steering::MeasureType::EDGE, Steering::MeasureType::EDGE, desiredDistance}, 0);
auto result = steering.updatePath(0);
steering.setDestination({{EntityLocation(otherEntity)}, Steering::MeasureType::EDGE, Steering::MeasureType::EDGE, desiredDistance}, 0ms);
auto result = steering.updatePath(0ms);
ASSERT_EQUAL(-1, result); //Could not find any poly since we haven't built any navmeshes.
rebuildAllTilesFn();
ASSERT_FALSE(steering.isAtCurrentDestination(0));
ASSERT_FALSE(steering.isAtCurrentDestination(0ms));
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
ASSERT_EQUAL(to2D(otherEntity->requirePropertyClassFixed<PositionProperty>().data()), to2D(steering.getPath()[0]))
ASSERT_FALSE(steering.isAtCurrentDestination(0))
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
//Move the avatar closer
avatarEntity->requirePropertyClassFixed<PositionProperty>().data().x() = 5;
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
ASSERT_EQUAL(to2D(otherEntity->requirePropertyClassFixed<PositionProperty>().data()), to2D(steering.getPath()[0]))
ASSERT_FALSE(steering.isAtCurrentDestination(0))
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
//Move the destination entity away
otherEntity->requirePropertyClassFixed<PositionProperty>().data().x() = 15;
otherEntity->m_lastUpdated++;
awareness.updateEntity(*avatarEntity, *otherEntity, nullptr);
steering.requestUpdate();
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
ASSERT_EQUAL(to2D(otherEntity->requirePropertyClassFixed<PositionProperty>().data()), to2D(steering.getPath()[0]))
ASSERT_FALSE(steering.isAtCurrentDestination(0))
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
//Move the avatar entity directly over the destination entity
avatarEntity->requirePropertyClassFixed<PositionProperty>().data() = otherEntity->requirePropertyClassFixed<PositionProperty>().data();
avatarEntity->m_lastUpdated++;
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
steering.requestUpdate();
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(0, result); //Should be no vert since we're exactly at destination
ASSERT_TRUE(steering.isAtCurrentDestination(0))
ASSERT_TRUE(steering.isAtCurrentDestination(0ms))
//Move the avatar entity adjacent to the destination, but within required distance
avatarEntity->requirePropertyClassFixed<PositionProperty>().data().x() -= 3.0;
avatarEntity->m_lastUpdated++;
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
steering.requestUpdate();
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
ASSERT_EQUAL(to2D(otherEntity->requirePropertyClassFixed<PositionProperty>().data()), to2D(steering.getPath()[0]))
ASSERT_TRUE(steering.isAtCurrentDestination(0))
ASSERT_TRUE(steering.isAtCurrentDestination(0ms))
//Move the avatar to origo, place the obstacleEntity entity besides it, and plot a path "through" the obstacleEntity entity to a position beyond it.
//The path should go around the other entity
@ -565,15 +570,15 @@ struct SteeringIntegration : public Cyphesis::TestBase {
awareness.updateEntity(*avatarEntity, *avatarEntity, nullptr);
obstacleEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
awareness.addEntity(*avatarEntity, *obstacleEntity, false);
steering.setDestination({{EntityLocation(worldEntity, {20, 0, 0})}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, desiredDistance}, 0);
steering.setDestination({{EntityLocation(worldEntity, {20, 0, 0})}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, desiredDistance}, 0ms);
rebuildAllTilesFn();
ASSERT_FALSE(steering.isAtCurrentDestination(0));
ASSERT_FALSE(steering.isAtCurrentDestination(0ms));
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(3, result); //Should be three verts since we need to divert twice
ASSERT_EQUAL(WFMath::Point<2>(20, 0), to2D(steering.getPath()[2]))
ASSERT_FALSE(steering.isAtCurrentDestination(0))
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
//Move the obstacle entity away, so that the path is straight again.
obstacleEntity->requirePropertyClassFixed<PositionProperty>().data() = {-10, 0, 0};
@ -581,10 +586,10 @@ struct SteeringIntegration : public Cyphesis::TestBase {
awareness.updateEntity(*avatarEntity, *obstacleEntity, nullptr);
rebuildAllTilesFn();
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
ASSERT_EQUAL(WFMath::Point<2>(20, 0), to2D(steering.getPath()[0]))
ASSERT_FALSE(steering.isAtCurrentDestination(0))
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
//Move it back again
obstacleEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
@ -592,27 +597,27 @@ struct SteeringIntegration : public Cyphesis::TestBase {
awareness.updateEntity(*avatarEntity, *obstacleEntity, nullptr);
rebuildAllTilesFn();
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(3, result); //Should be three verts since we need to divert twice
ASSERT_EQUAL(WFMath::Point<2>(20, 0), to2D(steering.getPath()[2]))
ASSERT_FALSE(steering.isAtCurrentDestination(0))
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
//Remove obstacle entity from awareness
awareness.removeEntity(*avatarEntity, *obstacleEntity);
rebuildAllTilesFn();
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line
ASSERT_EQUAL(WFMath::Point<2>(20, 0), to2D(steering.getPath()[0]))
ASSERT_FALSE(steering.isAtCurrentDestination(0))
ASSERT_FALSE(steering.isAtCurrentDestination(0ms))
//Add the small obstacle entity between the avatar and the destination.
// Since it can be stepped over/on it should not affect the path
smallObstacleEntity->requirePropertyClassFixed<PositionProperty>().data() = {10, 0, 0};
awareness.addEntity(*avatarEntity, *smallObstacleEntity, false);
steering.setDestination({{EntityLocation(worldEntity, {20, 0, 0})}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, desiredDistance}, 0);
steering.setDestination({{EntityLocation(worldEntity, {20, 0, 0})}, Steering::MeasureType::CENTER, Steering::MeasureType::CENTER, desiredDistance}, 0ms);
rebuildAllTilesFn();
result = steering.updatePath(0);
result = steering.updatePath(0ms);
ASSERT_EQUAL(1, result); //Should be one vert since it's a straight line

View file

@ -643,7 +643,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext>
arg1->setName("domain");
tick->setArgs1(arg1);
tick->setAttr("lastTick", 0.0f);
tick->setSeconds(2.0f); // This should trigger a visibility.
tick->setStamp(2000); // This should trigger a visibility.
domainPhysical->getDomain()->operation(*domainPhysical, tick, res);
return res;
};

View file

@ -90,12 +90,12 @@ int main()
expect_python_error("o.set_to(1)", PyExc_TypeError);
run_python_string("o.set_from('2')");
expect_python_error("o.set_from(2)", PyExc_TypeError);
run_python_string("o.set_seconds(2)");
run_python_string("o.set_seconds(2.0)");
expect_python_error("o.set_seconds('2.0')", PyExc_TypeError);
run_python_string("o.set_stamp(2)");
expect_python_error("o.set_stamp('2.0')", PyExc_TypeError);
run_python_string("o.set_future_seconds(2)");
run_python_string("o.set_future_seconds(2.0)");
expect_python_error("o.set_future_seconds('2.0')", PyExc_TypeError);
run_python_string("o.set_future_milliseconds(2)");
expect_python_error("o.set_future_milliseconds('2.0')", PyExc_TypeError);
expect_python_error("o.set_args()", PyExc_IndexError);
run_python_string("o.set_args([])");
expect_python_error("o.set_args(1)", PyExc_TypeError);
@ -109,8 +109,9 @@ int main()
run_python_string("assert type(o.get_refno()) == int");
run_python_string("assert type(o.get_to()) == str");
run_python_string("assert type(o.get_from()) == str");
run_python_string("assert type(o.get_seconds()) == float");
run_python_string("assert type(o.get_stamp()) == int");
run_python_string("assert type(o.get_future_seconds()) == float");
run_python_string("assert type(o.get_future_milliseconds()) == int");
run_python_string("assert type(o.get_args()) == list");
run_python_string("assert type(o.get_name()) == str");
run_python_string("assert len(o) == 1");

View file

@ -210,7 +210,7 @@ void BaseMindMapEntityintegration::test_MemMapreadEntity_noloc() {
data->setLoc(tlve->getId());
// Read in entity data the sets the LOC of e3 to tlve
m_mind->m_map.readEntity(e3, data, 0);
m_mind->m_map.readEntity(e3, data, std::chrono::milliseconds{0});
ASSERT_EQUAL(e3->m_parent, tlve.get())
ASSERT_TRUE(tlve->m_contains->find(e3) != tlve->m_contains->end());
@ -239,7 +239,7 @@ void BaseMindMapEntityintegration::test_MemMapreadEntity_changeloc() {
data->setLoc(tlve->getId());
// Read in entity data that changes the LOC of e3 from e2 to TLVE
m_mind->m_map.readEntity(e3, data, 0);
m_mind->m_map.readEntity(e3, data, std::chrono::milliseconds{0});
ASSERT_EQUAL(e3->m_parent, tlve.get())
ASSERT_TRUE(e2->m_contains->find(e3) == e2->m_contains->end());
@ -254,7 +254,7 @@ void BaseMindMapEntityintegration::test_MemMap_updateAdd_location_properties_hav
Atlas::Objects::Entity::Anonymous args;
location.addToEntity(args);
args->setAttr("id", "1");
m_mind->m_map.updateAdd(args, 1.0f);
m_mind->m_map.updateAdd(args, std::chrono::milliseconds{1'000});
}
auto ent = m_mind->m_map.get("1");
@ -270,7 +270,7 @@ void BaseMindMapEntityintegration::test_MemMap_updateAdd_location_properties_hav
args->setAttr("id", "1");
args->setAttr("solid", 0);
args->setAttr("simple", 0);
m_mind->m_map.updateAdd(args, 2.0f);
m_mind->m_map.updateAdd(args, std::chrono::milliseconds{2'000});
}
ent = m_mind->m_map.get("1");
@ -303,7 +303,7 @@ void BaseMindMapEntityintegration::test_MemMapcheck() {
m_mind->m_map.m_checkIterator = m_mind->m_map.m_entities.find(3);
e3->setVisible(false);
double time = e3->lastSeen() + 900;
auto time = e3->lastSeen() + std::chrono::milliseconds{900'000};
// We have set up e3 so it is due to be purged from memory.
m_mind->m_map.check(time);

View file

@ -55,7 +55,7 @@ struct TestMemMap : public MemMap {
return addId(id);
}
void _readEntity(const Ref<MemEntity>& ent, const Atlas::Objects::Entity::RootEntity& rootEntity, double timestamp) {
void _readEntity(const Ref<MemEntity>& ent, const Atlas::Objects::Entity::RootEntity& rootEntity, std::chrono::milliseconds timestamp) {
readEntity(ent, rootEntity, timestamp);
}
@ -235,7 +235,7 @@ void MemMaptest::test_readEntity() {
Ref<MemEntity> ent = new MemEntity(new_id);
ent->setType(m_sampleType);
tested._readEntity(ent, data, 0);
tested._readEntity(ent, data, std::chrono::milliseconds{0});
}
void MemMaptest::test_readEntity_type() {
@ -247,7 +247,7 @@ void MemMaptest::test_readEntity_type() {
Ref<MemEntity> ent = new MemEntity(new_id);
tested._readEntity(ent, data, 0);
tested._readEntity(ent, data, std::chrono::milliseconds{0});
ASSERT_EQUAL(ent->getType(), m_sampleType);
}
@ -261,7 +261,7 @@ void MemMaptest::test_readEntity_type_nonexist() {
Ref<MemEntity> ent = new MemEntity(new_id);
tested._readEntity(ent, data, 0);
tested._readEntity(ent, data, std::chrono::milliseconds{0});
ASSERT_NULL(ent->getType());
}

View file

@ -54,6 +54,7 @@
#include <rules/simulation/VisibilityDistanceProperty.h>
#include "../stubs/common/stubMonitors.h"
using namespace std::chrono_literals;
using Atlas::Message::Element;
using Atlas::Message::ListType;
using Atlas::Message::MapType;
@ -161,8 +162,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
void test_scaleBbox(TestContext& context) {
double tickSize = 1.0 / 15.0;
double time = 0;
std::chrono::milliseconds tickSize(1000 / 15);
std::chrono::milliseconds time(0);
OpVector res;
@ -203,7 +204,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
btCollisionWorld::ClosestRayResultCallback callback(from, to);
domain->test_getPhysicalWorld()->rayTest(from, to, callback);
domain->tick(1.0f, res);
domain->tick(1000ms, res);
ASSERT_TRUE(callback.hasHit());
ASSERT_FUZZY_EQUAL(1.0f, callback.m_hitPointWorld.y(), 0.1f);
@ -220,7 +221,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(freeEntity);
while (time < 5) {
while (time < 5000ms) {
time += tickSize;
domain->tick(tickSize, res);
}
@ -234,7 +235,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->test_childEntityPropertyApplied("bbox", bBoxProperty, plantedEntity.getIntId());
domain->tick(1.0f, res);
domain->tick(1000ms, res);
callback = btCollisionWorld::ClosestRayResultCallback(from, to);
domain->test_getPhysicalWorld()->rayTest(from, to, callback);
@ -249,8 +250,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(freeEntity);
time = 0;
while (time < 5) {
time = 0ms;
while (time < 5000ms) {
time += tickSize;
domain->tick(tickSize, res);
}
@ -288,7 +289,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(planted1);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_EQUAL(rootEntity.getIntId(), *planted1.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
@ -301,7 +302,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(planted2);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_EQUAL(planted1.getIntId(), *planted2.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
ASSERT_FUZZY_EQUAL(1.0f, planted2.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
@ -315,7 +316,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(planted3);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_EQUAL(planted2.getIntId(), *planted3.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
ASSERT_FUZZY_EQUAL(2.0f, planted3.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
@ -329,7 +330,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(planted4);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_EQUAL(planted3.getIntId(), *planted4.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
ASSERT_FUZZY_EQUAL(3.0f, planted4.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
@ -337,13 +338,13 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
//Now delete planted3, which should place planted4 on top of planted2
domain->removeEntity(planted3);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_EQUAL(planted2.getIntId(), *planted4.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
ASSERT_FUZZY_EQUAL(2.0f, planted4.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
domain->removeEntity(planted1);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_EQUAL(rootEntity.getIntId(), *planted2.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
ASSERT_FUZZY_EQUAL(0.0f, planted2.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
@ -436,7 +437,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(fixed1);
OpVector res;
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_EQUAL(0, fixed1.requirePropertyClassFixed<PositionProperty>().data().y());
@ -450,7 +451,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(planted1);
domain->tick(0, res);
domain->tick(0ms, res);
Entity planted2(context.newId());
planted2.requirePropertyClassFixed<PositionProperty>().data() = {0, 2, 1};
@ -461,7 +462,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(planted2);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_FUZZY_EQUAL(2.0f, planted2.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1f);
@ -475,7 +476,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(freeEntity);
ASSERT_FUZZY_EQUAL(4.0f, freeEntity.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1);
domain->tick(1, res);
domain->tick(1000ms, res);
ASSERT_FUZZY_EQUAL(4.0f, freeEntity.requirePropertyClassFixed<PositionProperty>().data().y(), 0.1);
@ -489,7 +490,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
ASSERT_FUZZY_EQUAL(WFMath::Point<3>(10, 12, 11), planted2.requirePropertyClassFixed<PositionProperty>().data(), epsilon);
ASSERT_TRUE(WFMath::Equal(WFMath::Point<3>(11, 14, 10), freeEntity.requirePropertyClassFixed<PositionProperty>().data(), 0.1));
}
domain->tick(0, res);
domain->tick(0ms, res);
//Only change orientation
@ -502,7 +503,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
ASSERT_FUZZY_EQUAL(WFMath::Point<3>(11, 12, 10), planted2.requirePropertyClassFixed<PositionProperty>().data(), epsilon);
ASSERT_TRUE(WFMath::Equal(WFMath::Point<3>(10, 14, 9), freeEntity.requirePropertyClassFixed<PositionProperty>().data(), 0.1));
}
domain->tick(0, res);
domain->tick(0ms, res);
//Move it, and at the same time rotate it 90 degrees around the y axis.
{
@ -515,7 +516,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
ASSERT_FUZZY_EQUAL(WFMath::Point<3>(15, 17, 14), planted2.requirePropertyClassFixed<PositionProperty>().data(), epsilon);
ASSERT_TRUE(WFMath::Equal(WFMath::Point<3>(14, 19, 15), freeEntity.requirePropertyClassFixed<PositionProperty>().data(), 0.1));
}
domain->tick(0, res);
domain->tick(0ms, res);
//Move away the first planted entity, which should also move along the second planted and the free entity, and not affect the fixed entity.
{
@ -586,7 +587,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain.addEntity(planted1);
OpVector res;
domain.tick(0, res);
domain.tick(0ms, res);
ASSERT_TRUE(planted1.getPropertyClassFixed<ModeDataProperty>())
ASSERT_TRUE(planted1.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId)
@ -617,7 +618,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain.addEntity(planted2);
domain.tick(0, res);
domain.tick(0ms, res);
ASSERT_TRUE(planted2.getPropertyClassFixed<ModeDataProperty>());
ASSERT_TRUE(planted2.getPropertyClassFixed<ModeDataProperty>()->getPlantedOnData().entityId);
@ -722,7 +723,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
OpVector res;
std::set<LocatedEntity*> transformedEntities;
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_FUZZY_EQUAL(terrain.get(10, 10), 10.0f, 0.1f);
@ -740,7 +741,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
}
domain->applyTransform(terrainModEntity, Domain::TransformData{WFMath::Quaternion(), WFMath::Point<3>(10, 10, 10), nullptr, {}}, transformedEntities);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_FUZZY_EQUAL(terrain.get(10, 10), 5.0f, 0.1f);
ASSERT_TRUE(terrain.hasMod(terrainModEntity.getIntId()));
@ -762,7 +763,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
modeProperty->apply(terrainModEntity);
terrainModEntity.propertyApplied.emit("mode", *modeProperty);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_FUZZY_EQUAL(terrain.get(10, 10), 10.0f, 0.1f);
ASSERT_FALSE(terrain.hasMod(terrainModEntity.getIntId()));
@ -773,7 +774,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
modeProperty->apply(terrainModEntity);
terrainModEntity.propertyApplied.emit("mode", *modeProperty);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_FUZZY_EQUAL(terrain.get(10, 10), 5.0f, 0.1f);
ASSERT_TRUE(terrain.hasMod(terrainModEntity.getIntId()));
@ -857,7 +858,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(floatingEntity);
OpVector res;
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Submerged);
ASSERT_TRUE(freeEntity2.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
ASSERT_TRUE(floatingEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Planted);
@ -879,8 +880,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
}
};
double tickSize = 1.0 / 15.0;
double time = 0;
std::chrono::milliseconds tickSize(1000 / 15);
std::chrono::milliseconds time(0);
TypeNode rockType("rock");
TypeNode lakeType("lake");
@ -939,8 +940,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
OpVector res;
std::set<LocatedEntity*> transformedEntities;
domain->tick(0, res);
while (time < 5) {
domain->tick(0ms, res);
while (time < 5000ms) {
time += tickSize;
domain->tick(tickSize, res);
}
@ -956,13 +957,13 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
//Move outside
domain->applyTransform(freeEntity, Domain::TransformData{WFMath::Quaternion::IDENTITY(), WFMath::Point<3>(20, 60, 0), nullptr, {}}, transformedEntities);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_GREATER(freeEntity.requirePropertyClassFixed<PositionProperty>().data().y(), 0);
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
//Move back in.
domain->applyTransform(freeEntity, Domain::TransformData{WFMath::Quaternion::IDENTITY(), WFMath::Point<3>(20, -10, 0), nullptr, {}}, transformedEntities);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_LESS(freeEntity.requirePropertyClassFixed<PositionProperty>().data().y(), 0);
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Submerged);
ASSERT_TRUE(freeEntity3.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
@ -970,7 +971,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
//Move the lake to where freeEntity3 is
domain->applyTransform(lake, Domain::TransformData{WFMath::Quaternion(), freeEntity3.requirePropertyClassFixed<PositionProperty>().data() + WFMath::Vector<3>(0, 5, 0), nullptr, {}},
transformedEntities);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_TRUE(freeEntity3.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Submerged);
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
@ -990,12 +991,12 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
bBoxProperty.apply(lake);
lake.test_propertyApplied().emit("bbox", bBoxProperty);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_TRUE(freeEntity3.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
domain->removeEntity(lake);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
ASSERT_TRUE(freeEntity2.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
ASSERT_TRUE(freeEntity3.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
@ -1003,8 +1004,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
}
void test_ocean(TestContext& context) {
double tickSize = 1.0 / 15.0;
double time = 0;
std::chrono::milliseconds tickSize(1000 / 15);
std::chrono::milliseconds time(0);
TypeNode rockType("rock");
TypeNode oceanType("ocean");
@ -1055,8 +1056,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
OpVector res;
std::set<LocatedEntity*> transformedEntities;
domain->tick(0, res);
while (time < 5) {
domain->tick(0ms, res);
while (time < 5000ms) {
time += tickSize;
domain->tick(tickSize, res);
}
@ -1069,18 +1070,18 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
//Move outside
domain->applyTransform(freeEntity, Domain::TransformData{WFMath::Quaternion::IDENTITY(), WFMath::Point<3>(0, 60, 0), nullptr, {}}, transformedEntities);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_TRUE(freeEntity.requirePropertyClassFixed<PositionProperty>().data().y() > 0);
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
//Move back in.
domain->applyTransform(freeEntity, Domain::TransformData{WFMath::Quaternion::IDENTITY(), WFMath::Point<3>(0, -10, 0), nullptr, {}}, transformedEntities);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_TRUE(freeEntity.requirePropertyClassFixed<PositionProperty>().data().y() < 0);
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Submerged);
domain->removeEntity(ocean);
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_TRUE(freeEntity.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
ASSERT_TRUE(freeEntity2.getPropertyClassFixed<ModeProperty>()->getMode() == ModeProperty::Mode::Free);
}
@ -1226,8 +1227,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
void test_fallToBottom(TestContext& context) {
double tickSize = 1.0 / 15.0;
double time = 0;
std::chrono::milliseconds tickSize(1000 / 15);
std::chrono::milliseconds time(0);
Entity rootEntity(context.newId());
rootEntity.incRef();
@ -1262,12 +1263,12 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
OpVector res;
//First tick should not update anything
domain->tick(0, res);
domain->tick(0ms, res);
ASSERT_EQUAL(freeEntity.requirePropertyClassFixed<PositionProperty>().data(), WFMath::Point<3>::ZERO());
ASSERT_EQUAL(fixedEntity.requirePropertyClassFixed<PositionProperty>().data(), WFMath::Point<3>(10, 0, 10));
//Inject enough ticks to move rock to bottom
while (time < 5) {
while (time < 5000ms) {
time += tickSize;
domain->tick(tickSize, res);
}
@ -1279,8 +1280,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
void test_standOnFixed(TestContext& context) {
double tickSize = 1.0 / 15.0;
double time = 0;
std::chrono::milliseconds tickSize(1000 / 15);
std::chrono::milliseconds time(0);
Entity rootEntity(context.newId());
rootEntity.incRef();
rootEntity.requirePropertyClassFixed<PositionProperty>().data() = WFMath::Point<3>::ZERO();
@ -1314,7 +1315,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
OpVector res;
//Inject enough ticks to move rock to bottom
while (time < 5) {
while (time < 5000ms) {
time += tickSize;
domain->tick(tickSize, res);
}
@ -1323,8 +1324,8 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
void test_fallToTerrain(TestContext& context) {
double tickSize = 1.0 / 15.0;
double time = 0;
std::chrono::milliseconds tickSize(1000 / 15);
std::chrono::milliseconds time(0);
Entity rootEntity(context.newId());
rootEntity.incRef();
TerrainProperty terrainProperty{};
@ -1370,7 +1371,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
OpVector res;
//Inject enough ticks to move rock to bottom
while (time < 5) {
while (time < 5000ms) {
time += tickSize;
domain->tick(tickSize, res);
}
@ -1391,7 +1392,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
void test_collision(TestContext& context) {
double tickSize = 1.0 / 15.0;
std::chrono::milliseconds tickSize(1000 / 15);
Property<double> zeroFrictionProperty{};
zeroFrictionProperty.data() = 0;
@ -1460,7 +1461,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
ASSERT_FUZZY_EQUAL(freeEntity.requirePropertyClassFixed<PositionProperty>().data().z(), 10 + (2.0 / 15.0), 0.1f);
//Inject ticks for one second
domain->tick(14.0 / 15.0, res);
domain->tick(14 * tickSize, res);
//Should have moved 2 meters in y axis
ASSERT_FUZZY_EQUAL(freeEntity.requirePropertyClassFixed<PositionProperty>().data().z(), 12, 0.1f);
@ -1475,7 +1476,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
ASSERT_EQUAL(plantedEntity.requirePropertyClassFixed<PositionProperty>().data(), plantedPos);
domain->removeEntity(plantedEntity);
domain->tick(1.0, res);
domain->tick(1000ms, res);
//Should have moved two more meters as planted entity was removed.
ASSERT_FUZZY_EQUAL(freeEntity.requirePropertyClassFixed<PositionProperty>().data().z(), 15, 0.1f);
@ -1485,7 +1486,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
void test_mode(TestContext& context) {
double tickSize = 1.0 / 15.0;
std::chrono::milliseconds tickSize(1000 / 15);
ModeProperty modePlantedProperty{};
modePlantedProperty.set("planted");
@ -1567,7 +1568,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
void test_determinism(TestContext& context) {
double tickSize = 1.0 / 15.0;
std::chrono::milliseconds tickSize(1000 / 15);
TypeNode rockType("rock");
@ -1762,7 +1763,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
OpVector res;
std::set<LocatedEntity*> transformedEntities;
domain->tick(0.1, res);
domain->tick(100ms, res);
ASSERT_TRUE(domain->isEntityVisibleFor(observerEntity, observerEntity));
@ -1785,7 +1786,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
//Now move the observer to "small1"
domain->applyTransform(observerEntity, Domain::TransformData{WFMath::Quaternion(), WFMath::Point<3>(30, 0, 30), nullptr, {}}, transformedEntities);
//Force visibility updates
domain->tick(2, res);
domain->tick(2000ms, res);
{
ASSERT_TRUE(domain->isEntityVisibleFor(observerEntity, smallVisibleEntity));
ASSERT_TRUE(domain->isEntityVisibleFor(observerEntity, smallEntity1));
@ -1869,7 +1870,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(*human);
OpVector res;
domain->tick(2, res);
domain->tick(2000ms, res);
ASSERT_FUZZY_EQUAL(-0.5f, human->requirePropertyClassFixed<PositionProperty>().data().z(), 0.1f);
domain->removeEntity(*human);
@ -1889,7 +1890,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(*human);
OpVector res;
domain->tick(2, res);
domain->tick(2000ms, res);
ASSERT_FUZZY_EQUAL(0.5, human->requirePropertyClassFixed<PositionProperty>().data().z(), 0.3f);
domain->removeEntity(*human);
@ -1923,7 +1924,7 @@ struct Tested : public Cyphesis::TestBaseWithContext<TestContext> {
domain->addEntity(*human);
OpVector res;
domain->tick(2, res);
domain->tick(2000ms, res);
ASSERT_FUZZY_EQUAL(0, human->requirePropertyClassFixed<PositionProperty>().data().y(), 0.01f);
ASSERT_FUZZY_EQUAL(-0.4f, human->requirePropertyClassFixed<PositionProperty>().data().z(), 0.1f);

View file

@ -99,7 +99,7 @@ void SystemAccounttest::teardown() {
void SystemAccounttest::test_getType() {
const char* type = m_account->getType();
ASSERT_EQUAL(std::string("sys"), type);
ASSERT_EQUAL(std::string("system_account"), type);
}
void SystemAccounttest::test_store() {

View file

@ -128,7 +128,7 @@ int main() {
}
{
auto ac = tc.test_newAccount("sys",
auto ac = tc.test_newAccount("system_account",
"bob",
"unit_test_hash",
1);

View file

@ -204,7 +204,7 @@ void WorldRouterintegration::test_sequence() {
test_world.addEntity(ent2, base);
Tick tick;
tick->setFutureSeconds(0);
tick->setFutureMilliseconds(0);
tick->setTo(ent2->getId());
test_world.message(tick, *ent2);

View file

@ -161,7 +161,7 @@ void WorldRoutertest::test_addEntity_tick() {
test_world->addEntity(ent2, m_rootEntity);
Tick tick;
tick->setFutureSeconds(0);
tick->setFutureMilliseconds(0);
tick->setTo(ent2->getId());
test_world->message(tick, *ent2);
}
@ -176,7 +176,7 @@ void WorldRoutertest::test_addEntity_tick_get() {
test_world->addEntity(ent2, m_rootEntity);
Tick tick;
tick->setFutureSeconds(0);
tick->setFutureMilliseconds(0);
tick->setTo(ent2->getId());
test_world->message(tick, *ent2);

View file

@ -18,7 +18,7 @@
#ifndef STUB_CreatorClient_handleMakeResponse
//#define STUB_CreatorClient_handleMakeResponse
LocatedEntity* CreatorClient::handleMakeResponse(const Atlas::Objects::Operation::RootOperation&, double)
LocatedEntity* CreatorClient::handleMakeResponse(const Atlas::Objects::Operation::RootOperation&, std::chrono::milliseconds)
{
return nullptr;
}

View file

@ -93,7 +93,7 @@
#ifndef STUB_Awareness_avoidObstacles
//#define STUB_Awareness_avoidObstacles
bool Awareness::avoidObstacles(long avatarEntityId, const WFMath::Point<2>& position, const WFMath::Vector<2>& desiredVelocity, WFMath::Vector<2>& newVelocity, double currentTimestamp, const WFMath::Point<2>* nextWayPoint) const
bool Awareness::avoidObstacles(long avatarEntityId, const WFMath::Point<2>& position, const WFMath::Vector<2>& desiredVelocity, WFMath::Vector<2>& newVelocity, std::chrono::milliseconds currentTimestamp, const WFMath::Point<2>* nextWayPoint) const
{
return false;
}
@ -189,7 +189,7 @@
#ifndef STUB_Awareness_projectPosition
//#define STUB_Awareness_projectPosition
bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, double currentServerTimestamp) const
bool Awareness::projectPosition(long entityId, WFMath::Point<3>& pos, std::chrono::milliseconds currentServerTimestamp) const
{
return false;
}
@ -197,7 +197,7 @@
#ifndef STUB_Awareness_projectPosition
//#define STUB_Awareness_projectPosition
WFMath::Point<3> Awareness::projectPosition(long entityId, double currentServerTimestamp) const
WFMath::Point<3> Awareness::projectPosition(long entityId, std::chrono::milliseconds currentServerTimestamp) const
{
return *static_cast<WFMath::Point<3>*>(nullptr);
}
@ -213,7 +213,7 @@
#ifndef STUB_Awareness_processEntityUpdate
//#define STUB_Awareness_processEntityUpdate
bool Awareness::processEntityUpdate(EntityEntry& entry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, double timestamp)
bool Awareness::processEntityUpdate(EntityEntry& entry, const MemEntity& entity, const Atlas::Objects::Entity::RootEntity& ent, std::chrono::milliseconds timestamp)
{
return false;
}

View file

@ -28,7 +28,7 @@
#ifndef STUB_Steering_queryDestination
//#define STUB_Steering_queryDestination
int Steering::queryDestination(const EntityLocation& destination, double currentServerTimestamp)
int Steering::queryDestination(const EntityLocation& destination, std::chrono::milliseconds currentServerTimestamp)
{
return 0;
}
@ -36,7 +36,7 @@
#ifndef STUB_Steering_setDestination
//#define STUB_Steering_setDestination
void Steering::setDestination(SteeringDestination destination, double currentServerTimestamp)
void Steering::setDestination(SteeringDestination destination, std::chrono::milliseconds currentServerTimestamp)
{
}
@ -44,7 +44,7 @@
#ifndef STUB_Steering_updatePath
//#define STUB_Steering_updatePath
int Steering::updatePath(double currentTimestamp, const WFMath::Point<3>& currentAvatarPosition)
int Steering::updatePath(std::chrono::milliseconds currentTimestamp, const WFMath::Point<3>& currentAvatarPosition)
{
return 0;
}
@ -52,7 +52,7 @@
#ifndef STUB_Steering_updatePath
//#define STUB_Steering_updatePath
int Steering::updatePath(double currentTimestamp)
int Steering::updatePath(std::chrono::milliseconds currentTimestamp)
{
return 0;
}
@ -132,7 +132,7 @@
#ifndef STUB_Steering_update
//#define STUB_Steering_update
SteeringResult Steering::update(double currentTimestamp)
SteeringResult Steering::update(std::chrono::milliseconds currentTimestamp)
{
return *static_cast<SteeringResult*>(nullptr);
}
@ -140,7 +140,7 @@
#ifndef STUB_Steering_getCurrentAvatarPosition
//#define STUB_Steering_getCurrentAvatarPosition
WFMath::Point<3> Steering::getCurrentAvatarPosition(double currentTimestamp) const
WFMath::Point<3> Steering::getCurrentAvatarPosition(std::chrono::milliseconds currentTimestamp) const
{
return *static_cast<WFMath::Point<3>*>(nullptr);
}
@ -164,7 +164,7 @@
#ifndef STUB_Steering_isAtDestination
//#define STUB_Steering_isAtDestination
bool Steering::isAtDestination(double currentTimestamp, const SteeringDestination& destination) const
bool Steering::isAtDestination(std::chrono::milliseconds currentTimestamp, const SteeringDestination& destination) const
{
return false;
}
@ -172,7 +172,7 @@
#ifndef STUB_Steering_isAtCurrentDestination
//#define STUB_Steering_isAtCurrentDestination
bool Steering::isAtCurrentDestination(double currentTimestamp) const
bool Steering::isAtCurrentDestination(std::chrono::milliseconds currentTimestamp) const
{
return false;
}
@ -180,7 +180,7 @@
#ifndef STUB_Steering_distanceTo
//#define STUB_Steering_distanceTo
std::optional<double> Steering::distanceTo(double currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const
std::optional<double> Steering::distanceTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location, MeasureType fromSelf, MeasureType toDestination) const
{
return *static_cast<std::optional<double>*>(nullptr);
}
@ -188,7 +188,7 @@
#ifndef STUB_Steering_directionTo
//#define STUB_Steering_directionTo
WFMath::Vector<3> Steering::directionTo(double currentTimestamp, const EntityLocation& location) const
WFMath::Vector<3> Steering::directionTo(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const
{
return *static_cast<WFMath::Vector<3>*>(nullptr);
}
@ -196,7 +196,7 @@
#ifndef STUB_Steering_resolvePosition
//#define STUB_Steering_resolvePosition
Steering::ResolvedPosition Steering::resolvePosition(double currentTimestamp, const EntityLocation& location) const
Steering::ResolvedPosition Steering::resolvePosition(std::chrono::milliseconds currentTimestamp, const EntityLocation& location) const
{
return *static_cast<Steering::ResolvedPosition*>(nullptr);
}
@ -204,7 +204,7 @@
#ifndef STUB_Steering_setAwarenessArea
//#define STUB_Steering_setAwarenessArea
void Steering::setAwarenessArea(double currentServerTimestamp)
void Steering::setAwarenessArea(std::chrono::milliseconds currentServerTimestamp)
{
}
@ -236,7 +236,7 @@
#ifndef STUB_Steering_updatePosition
//#define STUB_Steering_updatePosition
void Steering::updatePosition(double currentServerTimestamp, long entityId, WFMath::Point<3>& pos) const
void Steering::updatePosition(std::chrono::milliseconds currentServerTimestamp, long entityId, WFMath::Point<3>& pos) const
{
}

View file

@ -75,9 +75,9 @@
#ifndef STUB_AwareMind_getCurrentServerTime
//#define STUB_AwareMind_getCurrentServerTime
double AwareMind::getCurrentServerTime() const
std::chrono::milliseconds AwareMind::getCurrentServerTime() const
{
return 0;
return *static_cast<std::chrono::milliseconds*>(nullptr);
}
#endif //STUB_AwareMind_getCurrentServerTime

View file

@ -9,7 +9,7 @@
#ifndef STUB_MemMap_readEntity
//#define STUB_MemMap_readEntity
void MemMap::readEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, double timestamp)
void MemMap::readEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp)
{
}
@ -17,7 +17,7 @@
#ifndef STUB_MemMap_updateEntity
//#define STUB_MemMap_updateEntity
void MemMap::updateEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, double timestamp)
void MemMap::updateEntity(const Ref<MemEntity>&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp)
{
}
@ -25,7 +25,7 @@
#ifndef STUB_MemMap_newEntity
//#define STUB_MemMap_newEntity
Ref<MemEntity> MemMap::newEntity(RouterId, const Atlas::Objects::Entity::RootEntity&, double timestamp)
Ref<MemEntity> MemMap::newEntity(const RouterId&, const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds timestamp)
{
return *static_cast<Ref<MemEntity>*>(nullptr);
}
@ -41,7 +41,7 @@
#ifndef STUB_MemMap_addId
//#define STUB_MemMap_addId
Ref<MemEntity> MemMap::addId(RouterId id)
Ref<MemEntity> MemMap::addId(const RouterId& id)
{
return *static_cast<Ref<MemEntity>*>(nullptr);
}
@ -49,7 +49,7 @@
#ifndef STUB_MemMap_applyTypePropertiesToEntity
//#define STUB_MemMap_applyTypePropertiesToEntity
void MemMap::applyTypePropertiesToEntity(const Ref<MemEntity>& entity)
void MemMap::applyTypePropertiesToEntity(const Ref<MemEntity>& entity)
{
}
@ -130,7 +130,7 @@
#ifndef STUB_MemMap_updateAdd
//#define STUB_MemMap_updateAdd
Ref<MemEntity> MemMap::updateAdd(const Atlas::Objects::Entity::RootEntity&, const double&)
Ref<MemEntity> MemMap::updateAdd(const Atlas::Objects::Entity::RootEntity&, std::chrono::milliseconds)
{
return *static_cast<Ref<MemEntity>*>(nullptr);
}
@ -178,7 +178,7 @@
#ifndef STUB_MemMap_findByLocation
//#define STUB_MemMap_findByLocation
EntityVector MemMap::findByLocation(const EntityLocation& where, WFMath::CoordType radius, const std::string& what)
EntityVector MemMap::findByLocation(const EntityLocation& where, WFMath::CoordType radius, const std::string& what) const
{
return *static_cast<EntityVector*>(nullptr);
}
@ -186,7 +186,7 @@
#ifndef STUB_MemMap_check
//#define STUB_MemMap_check
void MemMap::check(const double&)
void MemMap::check(std::chrono::milliseconds t)
{
}

View file

@ -129,13 +129,13 @@
}
#endif //STUB_CyPy_Operation_setTo
#ifndef STUB_CyPy_Operation_setSeconds
//#define STUB_CyPy_Operation_setSeconds
Py::Object CyPy_Operation::setSeconds(const Py::Tuple& args)
#ifndef STUB_CyPy_Operation_setStamp
//#define STUB_CyPy_Operation_setStamp
Py::Object CyPy_Operation::setStamp(const Py::Tuple& args)
{
return *static_cast<Py::Object*>(nullptr);
}
#endif //STUB_CyPy_Operation_setSeconds
#endif //STUB_CyPy_Operation_setStamp
#ifndef STUB_CyPy_Operation_setFutureSeconds
//#define STUB_CyPy_Operation_setFutureSeconds
@ -145,6 +145,14 @@
}
#endif //STUB_CyPy_Operation_setFutureSeconds
#ifndef STUB_CyPy_Operation_setFutureMilliseconds
//#define STUB_CyPy_Operation_setFutureMilliseconds
Py::Object CyPy_Operation::setFutureMilliseconds(const Py::Tuple& args)
{
return *static_cast<Py::Object*>(nullptr);
}
#endif //STUB_CyPy_Operation_setFutureMilliseconds
#ifndef STUB_CyPy_Operation_setName
//#define STUB_CyPy_Operation_setName
Py::Object CyPy_Operation::setName(const Py::Tuple& args)
@ -201,13 +209,13 @@
}
#endif //STUB_CyPy_Operation_getTo
#ifndef STUB_CyPy_Operation_getSeconds
//#define STUB_CyPy_Operation_getSeconds
Py::Object CyPy_Operation::getSeconds()
#ifndef STUB_CyPy_Operation_getStamp
//#define STUB_CyPy_Operation_getStamp
Py::Object CyPy_Operation::getStamp()
{
return *static_cast<Py::Object*>(nullptr);
}
#endif //STUB_CyPy_Operation_getSeconds
#endif //STUB_CyPy_Operation_getStamp
#ifndef STUB_CyPy_Operation_getFutureSeconds
//#define STUB_CyPy_Operation_getFutureSeconds
@ -217,6 +225,14 @@
}
#endif //STUB_CyPy_Operation_getFutureSeconds
#ifndef STUB_CyPy_Operation_getFutureMilliseconds
//#define STUB_CyPy_Operation_getFutureMilliseconds
Py::Object CyPy_Operation::getFutureMilliseconds()
{
return *static_cast<Py::Object*>(nullptr);
}
#endif //STUB_CyPy_Operation_getFutureMilliseconds
#ifndef STUB_CyPy_Operation_getName
//#define STUB_CyPy_Operation_getName
Py::Object CyPy_Operation::getName()

View file

@ -80,6 +80,14 @@
}
#endif //STUB_BaseWorld_getTime
#ifndef STUB_BaseWorld_getTimeAsMilliseconds
//#define STUB_BaseWorld_getTimeAsMilliseconds
std::chrono::milliseconds BaseWorld::getTimeAsMilliseconds() const
{
return *static_cast<std::chrono::milliseconds*>(nullptr);
}
#endif //STUB_BaseWorld_getTimeAsMilliseconds
#ifndef STUB_BaseWorld_getTimeAsSeconds
//#define STUB_BaseWorld_getTimeAsSeconds
float BaseWorld::getTimeAsSeconds() const

View file

@ -23,7 +23,15 @@ Ref<LocatedEntity> BaseWorld::getEntity(long id) const
assert(I->second);
return I->second;
} else {
return 0;
return nullptr;
}
}
#endif //STUB_BaseWorld_getEntity
#ifndef STUB_BaseWorld_getTimeAsMilliseconds
#define STUB_BaseWorld_getTimeAsMilliseconds
std::chrono::milliseconds BaseWorld::getTimeAsMilliseconds() const
{
return std::chrono::milliseconds();
}
#endif //STUB_BaseWorld_getTimeAsMilliseconds

View file

@ -115,7 +115,7 @@
#ifndef STUB_PhysicalDomain_tick
//#define STUB_PhysicalDomain_tick
void PhysicalDomain::tick(double t, OpVector& res)
void PhysicalDomain::tick(std::chrono::milliseconds t, OpVector& res)
{
}
@ -211,7 +211,7 @@
#ifndef STUB_PhysicalDomain_processMovedEntity
//#define STUB_PhysicalDomain_processMovedEntity
void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, double timeSinceLastUpdate)
void PhysicalDomain::processMovedEntity(BulletEntry& bulletEntry, std::chrono::milliseconds timeSinceLastUpdate)
{
}
@ -275,7 +275,7 @@
#ifndef STUB_PhysicalDomain_applyDestination
//#define STUB_PhysicalDomain_applyDestination
void PhysicalDomain::applyDestination(double tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp)
void PhysicalDomain::applyDestination(std::chrono::milliseconds tickSize, BulletEntry& entry, const PropelProperty* propelProp, const Vector3Property& destinationProp)
{
}
@ -307,7 +307,7 @@
#ifndef STUB_PhysicalDomain_createCollisionShapeForEntry
//#define STUB_PhysicalDomain_createCollisionShapeForEntry
std::shared_ptr<btCollisionShape> PhysicalDomain::createCollisionShapeForEntry(LocatedEntity& entity, const WFMath::AxisBox<3>& bbox, float mass, btVector3& centerOfMassOffse)
std::shared_ptr<btCollisionShape> PhysicalDomain::createCollisionShapeForEntry(LocatedEntity& entity, const WFMath::AxisBox<3>& bbox, float mass, btVector3& centerOfMassOffset)
{
return *static_cast<std::shared_ptr<btCollisionShape>*>(nullptr);
}

View file

@ -365,8 +365,8 @@ void ServerWidget::fillAllowedCharacterTypes(Eris::Account* account) {
auto& spawnPoints = account->getSpawnPoints();
//If the account inherits from "admin" we're an admin and can create a creator entity. This also applies if we're a "sys" account.
if (account->getParent() == "admin" || account->getParent() == "sys") {
//If the account inherits from "admin" we're an admin and can create a creator entity. This also applies if we're a "system_account" account.
if (account->getParent() == "admin" || account->getParent() == "system_account") {
mUseCreator->setVisible(true);
mUseCreator->setEnabled(true);
} else {

View file

@ -326,15 +326,15 @@ std::vector<ActionChange> EmberEntity::processActionsChange(const Atlas::Message
if (!v.isMap()) {
//Remove all existing actions
for (auto& entry: mActionsData) {
actionChanges.emplace_back(ActionChange::ChangeType::Removed, ActionEntry{entry.first, 0, 0});
actionChanges.emplace_back(ActionChange::ChangeType::Removed, ActionEntry{entry.first, std::chrono::milliseconds(0), std::chrono::milliseconds(0)});
}
mActionsData.clear();
} else if (mActionsData.empty()) {
auto& newMap = v.Map();
//All new actions
for (auto& newEntry: newMap) {
AtlasQuery::find<Atlas::Message::FloatType>(newEntry.second, "start_time", [&](const auto& startTime) {
ActionEntry actionEntry{newEntry.first, startTime, 0};
AtlasQuery::find<Atlas::Message::IntType>(newEntry.second, "start_time", [&](const auto& startTime) {
ActionEntry actionEntry{newEntry.first, std::chrono::milliseconds(startTime), std::chrono::milliseconds(0)};
actionChanges.emplace_back(ActionChange::ChangeType::Added, std::move(actionEntry));
});
}
@ -345,20 +345,20 @@ std::vector<ActionChange> EmberEntity::processActionsChange(const Atlas::Message
for (auto& newEntry: newMap) {
auto existingI = existingMap.find(newEntry.first);
if (existingI == existingMap.end()) {
AtlasQuery::find<Atlas::Message::FloatType>(newEntry.second, "start_time", [&](const auto& startTime) {
ActionEntry actionEntry{newEntry.first, startTime, 0};
AtlasQuery::find<Atlas::Message::IntType>(newEntry.second, "start_time", [&](const auto& startTime) {
ActionEntry actionEntry{newEntry.first, std::chrono::milliseconds(startTime), std::chrono::milliseconds(0)};
actionChanges.emplace_back(ActionChange::ChangeType::Added, std::move(actionEntry));
});
} else {
AtlasQuery::find<Atlas::Message::FloatType>(newEntry.second, "start_time", [&](const auto& startTime) {
ActionEntry actionEntry{newEntry.first, startTime, 0};
AtlasQuery::find<Atlas::Message::IntType>(newEntry.second, "start_time", [&](const auto& startTime) {
ActionEntry actionEntry{newEntry.first, std::chrono::milliseconds(startTime), std::chrono::milliseconds(0)};
actionChanges.emplace_back(ActionChange::ChangeType::Updated, std::move(actionEntry));
});
existingMap.erase(existingI);
}
}
for (auto& entry: existingMap) {
actionChanges.emplace_back(ActionChange::ChangeType::Removed, ActionEntry{entry.first, 0, 0});
actionChanges.emplace_back(ActionChange::ChangeType::Removed, ActionEntry{entry.first, std::chrono::milliseconds(0), std::chrono::milliseconds(0)});
}
mActionsData = newMap;
}

View file

@ -45,13 +45,13 @@ class EntityTalk;
struct ActionEntry {
ActionEntry(std::string actionName_,
double startTime_,
std::optional<double> endTime_)
std::chrono::milliseconds startTime_,
std::optional<std::chrono::milliseconds> endTime_)
: actionName(std::move(actionName_)), startTime(startTime_), endTime(endTime_) {}
std::string actionName;
double startTime;
std::optional<double> endTime;
std::chrono::milliseconds startTime;
std::optional<std::chrono::milliseconds> endTime;
};

View file

@ -23,10 +23,10 @@
#include <Eris/Account.h>
#include <Eris/Connection.h>
#include <Eris/Response.h>
#include <Eris/CustomEntities.h>
#include <Eris/SpawnPoint.h>
#include <Atlas/Objects/Operation.h>
#include <Atlas/Objects/Entity.h>
#include <wfmath/MersenneTwister.h>
@ -47,7 +47,7 @@ LocalServerAdminCreator::LocalServerAdminCreator(ServerService& serverService) {
}
void LocalServerAdminCreator::server_GotAccount(Eris::Account* account) {
//When connecting to a local socket we should use a "sys" account.
//When connecting to a local socket we should use a "system_account" account.
//This works very much like an "admin" account, but is not persisted on the server.
//Thus we will first create a new account on the server, with a random name and password.
@ -63,7 +63,7 @@ void LocalServerAdminCreator::server_GotAccount(Eris::Account* account) {
ss_username << rand.randInt(9);
}
Atlas::Objects::Entity::Sys sysAccountOp;
Atlas::Objects::Entity::SystemAccount sysAccountOp;
sysAccountOp->setAttr("username", ss_username.str());
sysAccountOp->setAttr("password", ss_password.str());

View file

@ -44,7 +44,7 @@ protected:
/**
* @author Erik Ogenvik
* @brief Handles the flow of creating a "sys" account and logging in the user.
* @brief Handles the flow of creating a "system_account" account and logging in the user.
*
* This is meant to be used when the connected to a local server through a socket
* and the user wants to enter the world as a creator entity.

View file

@ -1,8 +1,3 @@
Outline of changes in the next version:
times change from float to int, and specced in milliseconds
merge SECONDS and STAMP
abolish STAMP_CONTAINS and FUTURE_SECONDS
- binary2
- specify operations and their args semantically much more than currently is done:
especially movement modes

View file

@ -626,6 +626,11 @@ This gives one rotation angle in 2D, the three Euler angles in 3D, etc.
parents:["seconds"],
summary:"Time in seconds to add current time"
},
{
id:"future_milliseconds",
parents:["int"],
summary:"Time in milliseconds to add current time"
},
{
id:"time_string",
parents:["string"],

View file

@ -9,7 +9,6 @@
pos:[0.0,0.0,0.0]
velocity:[0.0,0.0,0.0]
contains:[]
stamp_contains:0.0
:map:
id:"admin_entity"
@ -34,6 +33,11 @@
parent:"account"
description:"Privileged accounts"
:map:
id:"system_account"
parent:"account"
description:"Privileged accounts which aren't persisted on the server."
:map:
id:"game"
parent:"admin_entity"
@ -45,3 +49,5 @@
specification:"atlas_game"
interface:"game_interface"
description:"All In Game classes and objects"

View file

@ -8,13 +8,11 @@
description:"Base operation for all operators"
long_description:"""This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'."""
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for."""
from:""
to:""
seconds:0.0
future_seconds:0.0
future_milliseconds:0
time_string:""
args:[]

View file

@ -2,8 +2,7 @@
:map:
id:"root"
parent:""
stamp:0.0
stamp_inherit:0.0
stamp:0
objtype:"meta"
interface:"base_interface"
name:""

View file

@ -159,7 +159,7 @@ For more about URI see
:map:
id:"characters"
parent:"contains"
description:"List of characters account can control"
description:"List of characters the account can control."
:map:
id:"args"
@ -170,33 +170,18 @@ For more about URI see
:map:
id:"operations"
parent:"id_list"
description:"List of alloved operations"
description:"List of allowed operations"
long_description:"Content ids can be either another interface or operation ids or both."
:map:
id:"stamp"
parent:"float"
parent:"int"
objtype:"type"
description:"Last time this object was modified."
long_description:"""Value should be reflect when something was
changed in this object. Any scheme is ok as long as newer numbers
are bigger than older stamps. For example, seconds since Jan 1st,
1970 or total game cycles would both be valid."""
:map:
id:"stamp_inherit"
parent:"stamp"
objtype:"type"
description:"Last time any object that inherits from this has been modified"
long_description:"Value should be reflect when something was changed in some object that inherits from this."
:map:
id:"stamp_contains"
parent:"stamp"
objtype:"type"
description:"Last time any object that uses this as reference recursively has been modified"
long_description:"Value should be reflect when something was changed in some object that is contained by this object."
long_description:"""A timestamp in milliseconds for when this object was updated on the server. The time scale used
doesn't necessarily need to be using any Epoch, it could instead be based on when the server was started. For
Operations this would indicate when it was sent from the server, whereas for Entities it would indicate when
properties were last updated."""
:map:
id:"objtype"
@ -206,11 +191,6 @@ For more about URI see
description:"What kind of object this is."
long_description:"""Examples of values: "op", "class", "type"."""
:map:
id:"interface"
parent:"id"
description:"What kind of operations are legal for this object."
:map:
id:"specification"
parent:"string"
@ -234,12 +214,6 @@ For more about URI see
parent:"message"
description:"What something has said."
:map:
id:"html"
parent:"string"
objtype:"type"
description:"String that is actually html."
:map:
id:"username"
parent:"string"
@ -254,7 +228,7 @@ For more about URI see
:map:
id:"description"
parent:"html"
parent:"string"
description:"This gives short description of object."
:map:
@ -299,22 +273,12 @@ For more about URI see
character can only control directly it's body."""
:map:
id:"seconds"
parent:"float"
objtype:"type"
description:"Time in seconds"
:map:
id:"future_seconds"
parent:"seconds"
description:"Time in seconds to add current time"
:map:
id:"time_string"
parent:"string"
objtype:"type"
description:"Time in string format: YYYY-MM-DD HH:MM:SS.ss"
long_description:"There can be variation in length of different fields if using some weird calendar"
id:"future_milliseconds"
parent:"int"
description:"Time in milliseconds to add current time."
long_description:"""This is used when you need to schedule something to happen on
the server some milliseconds from when the server receives the operation. If you want a more fixed time you can
instead set the 'stamp' attribute."""
:map:
id:"example"
@ -322,33 +286,6 @@ For more about URI see
objtype:"type"
description:"Gives some examples usage"
#attributes for map
:map:
id:"width"
parent:"float"
objtype:"type"
description:"width of something"
:map:
id:"grid_data"
parent:"list"
objtype:"type"
description:"grid data"
:map:
id:"grid_size"
parent:"int_list_length"
objtype:"type"
list_length:2
description:"size of grid area: width and height (and for space depth too) in grid units"
:map:
id:"cell_size"
parent:"float_list_length"
objtype:"type"
list_length:2
description:"cell size of grid area"
:map:
id:"height"
parent:"float"

File diff suppressed because it is too large Load diff

View file

@ -55,8 +55,7 @@ void AnonymousData::fillDefaultObjectInstance(AnonymousData& data, std::map<std:
data.attr_velocity.emplace_back(0.0);
data.attr_velocity.emplace_back(0.0);
data.attr_velocity.emplace_back(0.0);
data.attr_stamp_contains = 0.0;
data.attr_stamp = 0.0;
data.attr_stamp = 0;
}
} // namespace Atlas::Objects::Entity

View file

@ -22,7 +22,7 @@ Later in hierarchy tree objtype changes to 'object' when actual game objects are
class AnonymousData;
typedef SmartPtr<AnonymousData> Anonymous;
static const int ANONYMOUS_NO = 42;
static const int ANONYMOUS_NO = 43;
/// \brief Starting point for entity hierarchy.
///

View file

@ -166,7 +166,7 @@ protected:
std::string attr_username;
/// Password for account usually
std::string attr_password;
/// List of characters account can control
/// List of characters the account can control.
std::vector<std::string> attr_characters;
/// Send the "username" attribute to an Atlas::Bridge.
@ -203,7 +203,7 @@ extern const std::string CHARACTERS_ATTR;
// Inlined member functions follow.
//
const uint32_t USERNAME_FLAG = 1u << 11u;
const uint32_t USERNAME_FLAG = 1u << 10u;
inline void AccountData::setUsername(std::string val)
{
@ -211,7 +211,7 @@ inline void AccountData::setUsername(std::string val)
m_attrFlags |= USERNAME_FLAG;
}
const uint32_t PASSWORD_FLAG = 1u << 12u;
const uint32_t PASSWORD_FLAG = 1u << 11u;
inline void AccountData::setPassword(std::string val)
{
@ -219,7 +219,7 @@ inline void AccountData::setPassword(std::string val)
m_attrFlags |= PASSWORD_FLAG;
}
const uint32_t CHARACTERS_FLAG = 1u << 13u;
const uint32_t CHARACTERS_FLAG = 1u << 12u;
inline void AccountData::setCharacters(std::vector<std::string> val)
{
@ -424,6 +424,63 @@ private:
};
/** Privileged accounts which aren't persisted on the server.
Later in hierarchy tree objtype changes to 'object' when actual game objects are made.
*/
class SystemAccountData;
typedef SmartPtr<SystemAccountData> SystemAccount;
static const int SYSTEM_ACCOUNT_NO = 7;
/// \brief Privileged accounts which aren't persisted on the server..
///
/** Later in hierarchy tree objtype changes to 'object' when actual game objects are made.
*/
class SystemAccountData : public AccountData
{
protected:
/// Construct a SystemAccountData class definition.
explicit SystemAccountData(SystemAccountData *defaults = nullptr) :
AccountData((AccountData*)defaults)
{
m_class_no = SYSTEM_ACCOUNT_NO;
}
/// Default destructor.
~SystemAccountData() override = default;
public:
// The parent type for this object's superclass
static constexpr const char* super_parent = "account";
// The default parent type for this object
static constexpr const char* default_parent = "system_account";
// The default objtype for this object
static constexpr const char* default_objtype = "obj";
/// Copy this object.
SystemAccountData * copy() const override;
/// Is this instance of some class?
bool instanceOf(int classNo) const override;
public:
template <typename>
friend class ::Atlas::Objects::Allocator;
static Allocator<SystemAccountData> allocator;
protected:
///Resets the object as it's returned to the pool.
void reset() override;
void free() override;
private:
static void fillDefaultObjectInstance(SystemAccountData& data, std::map<std::string, uint32_t>& attr_data);
};
/** Games this server hosts
Later in hierarchy tree objtype changes to 'object' when actual game objects are made.
@ -433,7 +490,7 @@ Later in hierarchy tree objtype changes to 'object' when actual game objects are
class GameData;
typedef SmartPtr<GameData> Game;
static const int GAME_NO = 7;
static const int GAME_NO = 8;
/// \brief Games this server hosts.
///
@ -490,7 +547,7 @@ Later in hierarchy tree objtype changes to 'object' when actual game objects are
class GameEntityData;
typedef SmartPtr<GameEntityData> GameEntity;
static const int GAME_ENTITY_NO = 8;
static const int GAME_ENTITY_NO = 9;
/// \brief All In Game classes and objects.
///

View file

@ -13,7 +13,7 @@
namespace Atlas::Objects {
int Factories::enumMax = 44;
int Factories::enumMax = 45;
void Factories::installStandardTypes()
{
@ -30,6 +30,8 @@ void Factories::installStandardTypes()
addFactory<Entity::AdminData>("admin", Entity::ADMIN_NO);
addFactory<Entity::SystemAccountData>("system_account", Entity::SYSTEM_ACCOUNT_NO);
addFactory<Entity::GameData>("game", Entity::GAME_NO);
addFactory<Entity::GameEntityData>("game_entity", Entity::GAME_ENTITY_NO);

View file

@ -50,9 +50,8 @@ void GenericData::fillDefaultObjectInstance(GenericData& data, std::map<std::str
data.attr_objtype = default_objtype;
data.attr_serialno = 0;
data.attr_refno = 0;
data.attr_seconds = 0.0;
data.attr_future_seconds = 0.0;
data.attr_stamp = 0.0;
data.attr_future_milliseconds = 0;
data.attr_stamp = 0;
}
} // namespace Atlas::Objects::Operation

View file

@ -17,24 +17,22 @@ namespace Atlas::Objects::Operation {
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class GenericData;
typedef SmartPtr<GenericData> Generic;
static const int GENERIC_NO = 43;
static const int GENERIC_NO = 44;
/// \brief Base operation for all operators.
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class GenericData : public RootOperationData
{

View file

@ -44,6 +44,11 @@ namespace Entity {
typedef SmartPtr<AdminData> Admin;
}
namespace Entity {
class SystemAccountData;
typedef SmartPtr<SystemAccountData> SystemAccount;
}
namespace Entity {
class GameData;
typedef SmartPtr<GameData> Game;

View file

@ -18,24 +18,22 @@ namespace Atlas::Objects::Operation {
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ActionData;
typedef SmartPtr<ActionData> Action;
static const int ACTION_NO = 10;
static const int ACTION_NO = 11;
/// \brief This is base operator for operations that might have effects..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ActionData : public RootOperationData
{
@ -88,7 +86,7 @@ Map editor is main user for this in client side. Server uses this inside "info"
class CreateData;
typedef SmartPtr<CreateData> Create;
static const int CREATE_NO = 11;
static const int CREATE_NO = 12;
/// \brief Create new things from nothing using this operator..
///
@ -140,24 +138,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class DeleteData;
typedef SmartPtr<DeleteData> Delete;
static const int DELETE_NO = 12;
static const int DELETE_NO = 13;
/// \brief Delete something..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class DeleteData : public ActionData
{
@ -205,24 +201,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class SetData;
typedef SmartPtr<SetData> Set;
static const int SET_NO = 13;
static const int SET_NO = 14;
/// \brief Sets attributes for existing entity..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class SetData : public ActionData
{
@ -270,24 +264,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class AffectData;
typedef SmartPtr<AffectData> Affect;
static const int AFFECT_NO = 14;
static const int AFFECT_NO = 15;
/// \brief Sets attributes for existing entity..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class AffectData : public SetData
{
@ -335,24 +327,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class HitData;
typedef SmartPtr<HitData> Hit;
static const int HIT_NO = 15;
static const int HIT_NO = 16;
/// \brief Operation for when one entity hits another..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class HitData : public AffectData
{
@ -405,7 +395,7 @@ More about <a href="move.html">movement here</a>
class MoveData;
typedef SmartPtr<MoveData> Move;
static const int MOVE_NO = 16;
static const int MOVE_NO = 17;
/// \brief Change position.
///
@ -457,24 +447,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class WieldData;
typedef SmartPtr<WieldData> Wield;
static const int WIELD_NO = 17;
static const int WIELD_NO = 18;
/// \brief Attach a tool to the character entity at a pre-defined location so that the character can use it..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class WieldData : public SetData
{
@ -522,24 +510,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class GetData;
typedef SmartPtr<GetData> Get;
static const int GET_NO = 18;
static const int GET_NO = 19;
/// \brief Generic operation for getting info about things..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class GetData : public ActionData
{
@ -587,24 +573,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class PerceiveData;
typedef SmartPtr<PerceiveData> Perceive;
static const int PERCEIVE_NO = 19;
static const int PERCEIVE_NO = 20;
/// \brief Generic base operation for perceiving things by eyes, ears, etc....
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class PerceiveData : public GetData
{
@ -652,24 +636,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class LookData;
typedef SmartPtr<LookData> Look;
static const int LOOK_NO = 20;
static const int LOOK_NO = 21;
/// \brief Looking at something.
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class LookData : public PerceiveData
{
@ -717,24 +699,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ListenData;
typedef SmartPtr<ListenData> Listen;
static const int LISTEN_NO = 21;
static const int LISTEN_NO = 22;
/// \brief Listen (something).
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ListenData : public PerceiveData
{
@ -782,24 +762,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class SniffData;
typedef SmartPtr<SniffData> Sniff;
static const int SNIFF_NO = 22;
static const int SNIFF_NO = 23;
/// \brief Sniff something.
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class SniffData : public PerceiveData
{
@ -847,24 +825,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class TouchData;
typedef SmartPtr<TouchData> Touch;
static const int TOUCH_NO = 23;
static const int TOUCH_NO = 24;
/// \brief Touch something.
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class TouchData : public PerceiveData
{
@ -917,7 +893,7 @@ For more about <a href="login.html">out of game atlas here</a>
class LoginData;
typedef SmartPtr<LoginData> Login;
static const int LOGIN_NO = 24;
static const int LOGIN_NO = 25;
/// \brief Operation for logging into server.
///
@ -974,7 +950,7 @@ For more about <a href="login.html">out of game atlas here</a>
class LogoutData;
typedef SmartPtr<LogoutData> Logout;
static const int LOGOUT_NO = 25;
static const int LOGOUT_NO = 26;
/// \brief Operation for logging out.
///
@ -1026,24 +1002,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class CommunicateData;
typedef SmartPtr<CommunicateData> Communicate;
static const int COMMUNICATE_NO = 26;
static const int COMMUNICATE_NO = 27;
/// \brief Base operator for all kind of communication..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class CommunicateData : public ActionData
{
@ -1096,7 +1070,7 @@ need to relook at that 'Magic voice that steps on something crunchy and makes ma
class TalkData;
typedef SmartPtr<TalkData> Talk;
static const int TALK_NO = 27;
static const int TALK_NO = 28;
/// \brief used for talking.
///
@ -1148,24 +1122,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ImaginaryData;
typedef SmartPtr<ImaginaryData> Imaginary;
static const int IMAGINARY_NO = 28;
static const int IMAGINARY_NO = 29;
/// \brief When something is not yet implemented in server, then character can pretend to do something ;-).
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ImaginaryData : public ActionData
{
@ -1213,24 +1185,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class UseData;
typedef SmartPtr<UseData> Use;
static const int USE_NO = 29;
static const int USE_NO = 30;
/// \brief Use a currently wielded tool..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class UseData : public ActionData
{
@ -1278,24 +1248,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ActivityData;
typedef SmartPtr<ActivityData> Activity;
static const int ACTIVITY_NO = 30;
static const int ACTIVITY_NO = 31;
/// \brief Activities performed by entities. This is mainly meant for actions that should be communicated to other entities (like 'digging' or 'twirling').
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ActivityData : public ActionData
{
@ -1343,24 +1311,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class InfoData;
typedef SmartPtr<InfoData> Info;
static const int INFO_NO = 31;
static const int INFO_NO = 32;
/// \brief This is base operator for operations that tell you info about objects or events..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class InfoData : public RootOperationData
{
@ -1413,7 +1379,7 @@ Base operator for all kind of perceptions
class PerceptionData;
typedef SmartPtr<PerceptionData> Perception;
static const int PERCEPTION_NO = 32;
static const int PERCEPTION_NO = 33;
/// \brief Character perceives something..
///
@ -1470,7 +1436,7 @@ Base operator for all kind of perceptions
class UnseenData;
typedef SmartPtr<UnseenData> Unseen;
static const int UNSEEN_NO = 33;
static const int UNSEEN_NO = 34;
/// \brief Character failed to interact with another entity because it does not exist..
///
@ -1527,7 +1493,7 @@ Base operator for all kind of perceptions
class SightData;
typedef SmartPtr<SightData> Sight;
static const int SIGHT_NO = 34;
static const int SIGHT_NO = 35;
/// \brief Character sees something.
///
@ -1584,7 +1550,7 @@ Base operator for all kind of perceptions
class AppearanceData;
typedef SmartPtr<AppearanceData> Appearance;
static const int APPEARANCE_NO = 35;
static const int APPEARANCE_NO = 36;
/// \brief Character sees something appearing: it literally appears or has it come in visible range.
///
@ -1641,7 +1607,7 @@ Base operator for all kind of perceptions
class DisappearanceData;
typedef SmartPtr<DisappearanceData> Disappearance;
static const int DISAPPEARANCE_NO = 36;
static const int DISAPPEARANCE_NO = 37;
/// \brief Character sees something disappearing: it literally disappears or has it gone too far to be visible.
///
@ -1698,7 +1664,7 @@ Base operator for all kind of perceptions
class SoundData;
typedef SmartPtr<SoundData> Sound;
static const int SOUND_NO = 37;
static const int SOUND_NO = 38;
/// \brief Character hears something.
///
@ -1755,7 +1721,7 @@ Base operator for all kind of perceptions
class SmellData;
typedef SmartPtr<SmellData> Smell;
static const int SMELL_NO = 38;
static const int SMELL_NO = 39;
/// \brief Character smells something.
///
@ -1812,7 +1778,7 @@ Base operator for all kind of perceptions
class FeelData;
typedef SmartPtr<FeelData> Feel;
static const int FEEL_NO = 39;
static const int FEEL_NO = 40;
/// \brief Character feels something (with fingers usually).
///
@ -1864,24 +1830,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ErrorData;
typedef SmartPtr<ErrorData> Error;
static const int ERROR_NO = 40;
static const int ERROR_NO = 41;
/// \brief Something went wrong.
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ErrorData : public InfoData
{
@ -1929,24 +1893,22 @@ private:
This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ChangeData;
typedef SmartPtr<ChangeData> Change;
static const int CHANGE_NO = 41;
static const int CHANGE_NO = 42;
/// \brief An operation used to signal to clients when things such as types have changed..
///
/** This is base operation for all other
operations and defines basic attributes. You can use this as
starting point for browsing whole operation hiearchy. refno refers
to operation this is reply for. In examples all attributes that
are just as examples (and thus world specific) are started with 'e_'.
starting point for browsing whole operation hierarchy. refno refers
to the operation that this is a reply for.
*/
class ChangeData : public InfoData
{

View file

@ -50,7 +50,7 @@ void RootData::setAttr(std::string name, Element attr, const Atlas::Objects::Fac
{
if (name == ID_ATTR) { setId(attr.moveString()); return; }
if (name == PARENT_ATTR) { setParent(attr.moveString()); return; }
if (name == STAMP_ATTR) { setStamp(attr.asFloat()); return; }
if (name == STAMP_ATTR) { setStamp(attr.asInt()); return; }
if (name == OBJTYPE_ATTR) { setObjtype(attr.moveString()); return; }
if (name == NAME_ATTR) { setName(attr.moveString()); return; }
BaseObjectData::setAttr(std::move(name), std::move(attr), factories);
@ -88,7 +88,7 @@ inline void RootData::sendParent(Atlas::Bridge & b) const
inline void RootData::sendStamp(Atlas::Bridge & b) const
{
if(m_attrFlags & STAMP_FLAG) {
b.mapFloatItem(STAMP_ATTR, attr_stamp);
b.mapIntItem(STAMP_ATTR, attr_stamp);
}
}
@ -161,7 +161,7 @@ bool RootData::instanceOf(int classNo) const
void RootData::fillDefaultObjectInstance(RootData& data, std::map<std::string, uint32_t>& attr_data)
{
data.attr_stamp = 0.0;
data.attr_stamp = 0;
data.attr_objtype = default_objtype;
data.attr_parent = default_parent;
attr_data[ID_ATTR] = ID_FLAG;

Some files were not shown because too many files have changed in this diff Show more