2013-07-27 22:23:09 +02:00
|
|
|
/*
|
|
|
|
|
Copyright (C) 2013 Erik Ogenvik
|
|
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "PossessionClient.h"
|
2015-05-05 22:01:11 +02:00
|
|
|
#include "PossessionAccount.h"
|
|
|
|
|
|
2013-07-27 22:23:09 +02:00
|
|
|
|
2013-07-27 23:38:47 +02:00
|
|
|
#include "common/Possess.h"
|
2015-05-05 22:01:11 +02:00
|
|
|
#include "common/id.h"
|
|
|
|
|
#include "common/custom.h"
|
|
|
|
|
#include "common/SystemTime.h"
|
2015-05-11 18:43:23 +02:00
|
|
|
#include "common/Inheritance.h"
|
2013-07-27 23:38:47 +02:00
|
|
|
|
2015-05-06 22:25:08 +02:00
|
|
|
#include "common/debug.h"
|
|
|
|
|
|
2013-07-27 22:23:09 +02:00
|
|
|
#include <Atlas/Objects/Entity.h>
|
|
|
|
|
|
2015-05-11 18:43:23 +02:00
|
|
|
static const bool debug_flag = false;
|
2015-05-06 22:25:08 +02:00
|
|
|
|
2013-07-28 22:25:15 +02:00
|
|
|
using Atlas::Message::Element;
|
|
|
|
|
using Atlas::Objects::Root;
|
|
|
|
|
using Atlas::Objects::Entity::Anonymous;
|
|
|
|
|
using Atlas::Objects::Operation::RootOperation;
|
|
|
|
|
|
2015-09-20 20:03:13 +02:00
|
|
|
PossessionClient::PossessionClient(MindKit& mindFactory) :
|
2018-04-25 20:09:14 +02:00
|
|
|
m_mindFactory(mindFactory),
|
|
|
|
|
m_account(nullptr),
|
2018-05-01 22:16:38 +02:00
|
|
|
m_operationsDispatcher([&](const Operation& op, BaseMind& from) { this->operationFromEntity(op, from); },
|
2018-04-25 20:09:14 +02:00
|
|
|
[&]() -> double { return getTime(); }),
|
|
|
|
|
m_inheritance(new Inheritance())
|
2013-07-27 22:23:09 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-05 22:01:11 +02:00
|
|
|
bool PossessionClient::idle()
|
2013-07-27 22:23:09 +02:00
|
|
|
{
|
2015-05-05 22:01:11 +02:00
|
|
|
return m_operationsDispatcher.idle();
|
|
|
|
|
}
|
2013-08-02 14:20:09 +02:00
|
|
|
|
2015-05-05 22:01:11 +02:00
|
|
|
double PossessionClient::secondsUntilNextOp() const
|
|
|
|
|
{
|
|
|
|
|
return m_operationsDispatcher.secondsUntilNextOp();
|
2013-07-27 22:23:09 +02:00
|
|
|
}
|
|
|
|
|
|
2015-05-05 22:01:11 +02:00
|
|
|
bool PossessionClient::isQueueDirty() const
|
2013-07-27 23:38:47 +02:00
|
|
|
{
|
2015-05-05 22:01:11 +02:00
|
|
|
return m_operationsDispatcher.isQueueDirty();
|
|
|
|
|
}
|
2013-07-27 22:23:09 +02:00
|
|
|
|
2015-05-05 22:01:11 +02:00
|
|
|
void PossessionClient::markQueueAsClean()
|
|
|
|
|
{
|
|
|
|
|
m_operationsDispatcher.markQueueAsClean();
|
|
|
|
|
}
|
2013-07-27 22:23:09 +02:00
|
|
|
|
2018-05-01 22:16:38 +02:00
|
|
|
void PossessionClient::addLocatedEntity(BaseMind* entity)
|
2015-05-05 22:01:11 +02:00
|
|
|
{
|
2015-05-06 22:30:19 +02:00
|
|
|
m_minds.insert(std::make_pair(entity->getIntId(), entity));
|
|
|
|
|
entity->incRef();
|
2015-05-05 22:01:11 +02:00
|
|
|
}
|
2013-07-27 22:23:09 +02:00
|
|
|
|
2018-05-01 22:16:38 +02:00
|
|
|
void PossessionClient::removeLocatedEntity(BaseMind* entity)
|
2015-05-05 22:01:11 +02:00
|
|
|
{
|
2015-05-06 22:30:19 +02:00
|
|
|
m_minds.erase(entity->getIntId());
|
|
|
|
|
entity->decRef();
|
2015-05-05 22:01:11 +02:00
|
|
|
}
|
2013-07-27 22:23:09 +02:00
|
|
|
|
2015-05-05 22:01:11 +02:00
|
|
|
void PossessionClient::createAccount(const std::string& accountId)
|
|
|
|
|
{
|
|
|
|
|
m_account = new PossessionAccount(accountId, integerId(accountId), *this, m_mindFactory);
|
|
|
|
|
OpVector res;
|
|
|
|
|
m_account->enablePossession(res);
|
|
|
|
|
for (auto& op : res) {
|
|
|
|
|
m_connection.send(op);
|
|
|
|
|
}
|
2013-07-27 22:23:09 +02:00
|
|
|
}
|
|
|
|
|
|
2018-05-01 22:16:38 +02:00
|
|
|
void PossessionClient::operationFromEntity(const Operation& op, BaseMind& locatedEntity)
|
2013-07-27 23:38:47 +02:00
|
|
|
{
|
2015-05-05 22:01:11 +02:00
|
|
|
if (!locatedEntity.isDestroyed()) {
|
|
|
|
|
OpVector res;
|
|
|
|
|
locatedEntity.operation(op, res);
|
|
|
|
|
for (auto& resOp : res) {
|
|
|
|
|
//All resulting ops should go out to the server, except for Ticks which we'll keep ourselves.
|
|
|
|
|
if (resOp->getClassNo() == Atlas::Objects::Operation::TICK_NO) {
|
|
|
|
|
resOp->setTo(resOp->getFrom());
|
|
|
|
|
m_operationsDispatcher.addOperationToQueue(resOp, locatedEntity);
|
|
|
|
|
} else {
|
|
|
|
|
resOp->setFrom(locatedEntity.getId());
|
|
|
|
|
send(resOp);
|
|
|
|
|
}
|
2013-08-09 21:37:36 +02:00
|
|
|
}
|
2015-05-06 22:25:08 +02:00
|
|
|
if (locatedEntity.isDestroyed()) {
|
2015-05-06 22:30:19 +02:00
|
|
|
removeLocatedEntity(&locatedEntity);
|
2015-05-06 22:25:08 +02:00
|
|
|
}
|
2013-08-09 21:37:36 +02:00
|
|
|
}
|
2015-05-05 22:01:11 +02:00
|
|
|
}
|
2013-08-09 21:37:36 +02:00
|
|
|
|
2018-04-25 20:09:14 +02:00
|
|
|
void PossessionClient::operation(const Operation& op, OpVector& res)
|
2015-05-05 22:01:11 +02:00
|
|
|
{
|
2015-05-06 22:25:08 +02:00
|
|
|
if (debug_flag) {
|
|
|
|
|
std::cout << "PossessionClient::operation {" << std::endl;
|
|
|
|
|
debug_dump(op, std::cout);
|
|
|
|
|
std::cout << "}" << std::endl << std::flush;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-05 22:01:11 +02:00
|
|
|
if (op->isDefaultTo() || op->getTo() == m_account->getId()) {
|
|
|
|
|
OpVector accountRes;
|
|
|
|
|
m_account->operation(op, accountRes);
|
|
|
|
|
for (auto& resOp : accountRes) {
|
|
|
|
|
//All resulting ops should go out to the server, except for Ticks which we'll keep ourselves.
|
|
|
|
|
if (resOp->getClassNo() == Atlas::Objects::Operation::TICK_NO) {
|
|
|
|
|
auto I = m_minds.find(integerId(resOp->getFrom()));
|
|
|
|
|
if (I != m_minds.end()) {
|
|
|
|
|
resOp->setTo(resOp->getFrom());
|
|
|
|
|
m_operationsDispatcher.addOperationToQueue(resOp, *I->second);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
res.push_back(resOp);
|
|
|
|
|
}
|
2013-08-02 14:20:09 +02:00
|
|
|
}
|
2013-07-27 23:38:47 +02:00
|
|
|
} else {
|
2015-05-05 22:01:11 +02:00
|
|
|
auto mindI = m_minds.find(integerId(op->getTo()));
|
2013-08-02 14:20:09 +02:00
|
|
|
if (mindI != m_minds.end()) {
|
2015-05-05 22:01:11 +02:00
|
|
|
OpVector mindRes;
|
2018-05-01 22:16:38 +02:00
|
|
|
auto mind = mindI->second;
|
2015-05-06 22:25:08 +02:00
|
|
|
mind->operation(op, mindRes);
|
2015-05-05 22:01:11 +02:00
|
|
|
for (auto& resOp : mindRes) {
|
2015-05-06 22:25:08 +02:00
|
|
|
resOp->setFrom(mind->getId());
|
2015-05-05 22:01:11 +02:00
|
|
|
//All resulting ops should go out to the server, except for Ticks which we'll keep ourselves.
|
|
|
|
|
if (resOp->getClassNo() == Atlas::Objects::Operation::TICK_NO) {
|
2015-05-06 22:25:08 +02:00
|
|
|
resOp->setTo(mind->getId());
|
|
|
|
|
m_operationsDispatcher.addOperationToQueue(resOp, *mind);
|
2015-05-05 22:01:11 +02:00
|
|
|
} else {
|
|
|
|
|
res.push_back(resOp);
|
|
|
|
|
}
|
2013-08-05 11:27:34 +02:00
|
|
|
}
|
2015-05-05 22:01:11 +02:00
|
|
|
|
2015-05-06 22:25:08 +02:00
|
|
|
if (mind->isDestroyed()) {
|
2015-05-06 22:30:19 +02:00
|
|
|
removeLocatedEntity(mind);
|
2015-05-06 22:25:08 +02:00
|
|
|
}
|
|
|
|
|
|
2013-08-02 14:20:09 +02:00
|
|
|
} else {
|
2015-05-05 22:01:11 +02:00
|
|
|
m_account->operation(op, res);
|
2013-08-02 14:20:09 +02:00
|
|
|
}
|
2013-07-27 23:38:47 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-05 22:01:11 +02:00
|
|
|
double PossessionClient::getTime() const
|
2013-07-27 23:38:47 +02:00
|
|
|
{
|
2015-05-05 22:01:11 +02:00
|
|
|
SystemTime time;
|
|
|
|
|
time.update();
|
2018-04-25 20:09:14 +02:00
|
|
|
return (double) (time.seconds()) + (double) time.microseconds() / 1000000.;
|
2013-07-27 23:38:47 +02:00
|
|
|
}
|