Should be asleep, but that was fun at least

This commit is contained in:
ExeVirus 2024-05-06 00:22:01 -04:00
parent e9a8ba386f
commit 97e9f37bd8
11 changed files with 41 additions and 28 deletions

View File

@ -45,7 +45,7 @@ public:
// destructed.
}
virtual void step(float dtime, const std::function<void(T *)> &f) = 0;
virtual void step(float dtime, const std::function<void(T *, v3f& lastPosition, bool &position_changed)> &f) = 0;
virtual bool registerObject(std::unique_ptr<T> obj) = 0;
virtual void removeObject(u16 id) = 0;

View File

@ -46,8 +46,15 @@ void ActiveObjectMgr::clearIf(const std::function<bool(ServerActiveObject *, u16
}
}
void ActiveObjectMgr::invalidateCachedObjectID(u16 id, v3f &last_position, bool &position_changed)
{
if(position_changed) {
m_spatial_map.invalidate(id, last_position);
}
}
void ActiveObjectMgr::step(
float dtime, const std::function<void(ServerActiveObject *)> &f)
float dtime, const std::function<void(ServerActiveObject *, v3f &last_position, bool &position_changed)> &f)
{
size_t count = 0;
@ -93,7 +100,7 @@ bool ActiveObjectMgr::registerObject(std::unique_ptr<ServerActiveObject> obj)
auto obj_id = obj->getId();
m_active_objects.put(obj_id, std::move(obj));
m_spatial_map.insert(obj.get());
m_spatial_map.insert(obj_id);
auto new_size = m_active_objects.size();
verbosestream << "Server::ActiveObjectMgr::addActiveObjectRaw(): "
@ -111,8 +118,8 @@ void ActiveObjectMgr::removeObject(u16 id)
verbosestream << "Server::ActiveObjectMgr::removeObject(): "
<< "id=" << id << std::endl;
m_spatial_map.remove(m_active_objects.get(id).get());
m_spatial_map.remove(id, m_active_objects.get(id).get()->getBasePosition());
// this will take the object out of the map and then destruct it
bool ok = m_active_objects.remove(id);
if (!ok) {

View File

@ -35,9 +35,10 @@ public:
// If cb returns true, the obj will be deleted
void clearIf(const std::function<bool(ServerActiveObject *, u16)> &cb);
void step(float dtime,
const std::function<void(ServerActiveObject *)> &f) override;
const std::function<void(ServerActiveObject *, v3f &last_position, bool &position_changed)> &f) override;
bool registerObject(std::unique_ptr<ServerActiveObject> obj) override;
void removeObject(u16 id) override;
void invalidateCachedObjectID(u16 id, v3f &last_position, bool &position_changed);
void getObjectsInsideRadius(const v3f &pos, float radius,
std::vector<ServerActiveObject *> &result,
@ -50,6 +51,7 @@ public:
f32 player_radius, const std::set<u16> &current_objects,
std::vector<u16> &added_objects);
protected:
SpatialMap m_spatial_map;
};
} // namespace server

View File

@ -132,8 +132,9 @@ void LuaEntitySAO::dispatchScriptDeactivate(bool removal)
m_env->getScriptIface()->luaentity_Deactivate(m_id, removal);
}
void LuaEntitySAO::step(float dtime, bool send_recommended, bool &position_changed)
void LuaEntitySAO::step(float dtime, bool send_recommended, v3f &last_position, bool &position_changed)
{
last_position = m_base_position;
if (!m_properties_sent) {
m_properties_sent = true;
std::string str = getPropertyPacket();
@ -241,6 +242,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended, bool &position_chang
}
sendOutdatedData();
position_changed = last_position != m_base_position;
}
std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version)

View File

@ -40,7 +40,7 @@ public:
ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_LUAENTITY; }
ActiveObjectType getSendType() const { return ACTIVEOBJECT_TYPE_GENERIC; }
virtual void addedToEnvironment(u32 dtime_s);
void step(float dtime, bool send_recommended, bool &position_changed) override;
void step(float dtime, bool send_recommended, v3f& last_position, bool &position_changed) override;
std::string getClientInitializationData(u16 protocol_version);
bool isStaticAllowed() const { return m_prop.static_save; }

View File

@ -154,8 +154,9 @@ void PlayerSAO::getStaticData(std::string * result) const
FATAL_ERROR("This function shall not be called for PlayerSAO");
}
void PlayerSAO::step(float dtime, bool send_recommended, bool &position_changed)
void PlayerSAO::step(float dtime, bool send_recommended, v3f& last_position, bool &position_changed)
{
last_position = m_last_good_position;
if (!isImmortal() && m_drowning_interval.step(dtime, 2.0f)) {
// Get nose/mouth position, approximate with eye position
v3s16 p = floatToInt(getEyePosition(), BS);
@ -238,7 +239,6 @@ void PlayerSAO::step(float dtime, bool send_recommended, bool &position_changed)
warningstream << "PlayerSAO::step() id=" << m_id <<
" is attached to nonexistent parent. This is a bug." << std::endl;
clearParentAttachment();
// FIXHERE
setBasePosition(m_last_good_position);
m_env->getGameDef()->SendMovePlayer(this);
}
@ -308,6 +308,7 @@ void PlayerSAO::step(float dtime, bool send_recommended, bool &position_changed)
}
sendOutdatedData();
position_changed = last_position != m_base_position;
}
std::string PlayerSAO::generateUpdatePhysicsOverrideCommand() const

View File

@ -87,7 +87,7 @@ public:
bool shouldUnload() const override { return false; }
std::string getClientInitializationData(u16 protocol_version) override;
void getStaticData(std::string *result) const override;
void step(float dtime, bool send_recommended, bool &position_changed) override;
void step(float dtime, bool send_recommended, v3f& last_position, bool &position_changed) override;
void setBasePosition(v3f position);
void setPos(const v3f &pos) override;
void addPos(const v3f &added_pos) override;

View File

@ -107,7 +107,7 @@ public:
same time so that the data can be combined in a single
packet.
*/
virtual void step(float dtime, bool send_recommended, bool &position_changed){}
virtual void step(float dtime, bool send_recommended, v3f& last_position, bool &position_changed){}
/*
The return value of this is passed to the client-side object

View File

@ -25,18 +25,17 @@ namespace server
{
// all inserted entires go into the uncached vector
void SpatialMap::insert(ServerActiveObject* obj)
void SpatialMap::insert(u16 id)
{
m_uncached.push_back(obj->getId());
m_uncached.push_back(id);
}
// Invalidates upon position update
void SpatialMap::invalidate(ServerActiveObject* obj)
void SpatialMap::invalidate(u16 id, v3f &pos)
{
// remove from cache, if present
u16 id = obj->getId();
bool found = false;
auto range = m_cached.equal_range(SpatialKey(obj->getBasePosition()));
auto range = m_cached.equal_range(SpatialKey(pos));
for (auto it = range.first; it != range.second; ++it) {
if (it->second == id) {
m_cached.erase(it);
@ -47,25 +46,24 @@ void SpatialMap::invalidate(ServerActiveObject* obj)
if(found) {
// place back in uncached
insert(obj);
insert(id);
}
}
void SpatialMap::remove(ServerActiveObject* obj)
void SpatialMap::remove(u16 id, v3f pos)
{
SpatialKey key(obj->getBasePosition());
u16 idToRemove = obj->getId();
SpatialKey key(pos);
if(m_cached.find(key) != m_cached.end()) {
auto range = m_cached.equal_range(key);
for (auto it = range.first; it != range.second; ++it) {
if (it->second == idToRemove) {
if (it->second == id) {
m_cached.erase(it);
return; // Erase and leave early
}
}
};
auto it = std::find(m_uncached.begin(), m_uncached.end(), idToRemove);
auto it = std::find(m_uncached.begin(), m_uncached.end(), id);
if (it != m_uncached.end()) {
m_uncached.erase(it);
return;

View File

@ -30,16 +30,16 @@ class SpatialMap
{
public:
// all inserted entires go into the uncached vector
void insert(ServerActiveObject* obj);
void insert(u16 id);
// Invalidates upon position update or removal
void invalidate(ServerActiveObject* obj);
void invalidate(u16 id, v3f& pos);
// On active_object removal, remove.
void remove(ServerActiveObject* obj);
void remove(u16 id, v3f pos);
// Only when at least 64 uncached objects or 10% uncached overall
void cacheUpdate(ActiveObjectMgr& mgr);
void cacheUpdate(::server::ActiveObjectMgr &mgr);
// Use the same basic algorithm for both area and radius lookups
void getRelevantObjectIds(const aabb3f &box, std::vector<u16> &relevant_objs);

View File

@ -1587,7 +1587,10 @@ void ServerEnvironment::step(float dtime)
object_count++;
// Step object
obj->step(dtime, send_recommended);
v3f last_position;
bool position_changed;
obj->step(dtime, send_recommended, last_position, position_changed);
m_ao_manager.
// Read messages from object
obj->dumpAOMessagesToQueue(m_active_object_messages);
};