optimizations + bugfixes
* Bombs explode on damage/explosion * Orbits spell fixed * Performance: implemented shared component indexes, compiled Lua caching, and updates only for changed projectile fields. Also removed accumulating hidden entity slots.
This commit is contained in:
1 parent
87bff164f1
commit
a34f42d53e
17 files changed
+727
-131
No files matched your search
+45
-2
@@ -4,8 +4,12 @@
|
||||
// synchronised by the host; item pickup, chest opening and loot spawning run here, through the original scripts.
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "entity/entity.h"
|
||||
@@ -19,6 +23,9 @@ struct RtComponent {
|
||||
std::string type;
|
||||
std::map<std::string, std::string> attrs;
|
||||
bool enabled = true;
|
||||
uint64_t value_revision = 0;
|
||||
int gpu_lifetime = 0;
|
||||
bool gpu_lifetime_pending = false; // comp() materializes this GPU mirror before exposing the component
|
||||
std::set<std::string> tags;
|
||||
};
|
||||
|
||||
@@ -29,6 +36,9 @@ struct RtEntity {
|
||||
double x = 0, y = 0, rot = 0, sx = 1, sy = 1;
|
||||
bool alive = true;
|
||||
std::vector<int> comps;
|
||||
uint64_t component_revision = 0;
|
||||
int single_lua_component = 0, lua_component_count = 0, collision_component_count = 0;
|
||||
std::map<std::string, std::vector<int>, std::less<>> comps_by_type;
|
||||
int parent = 0;
|
||||
int born = 0;
|
||||
int died = -1; // the frame of kill(); the record and its components are erased a few frames later (tick)
|
||||
@@ -95,6 +105,8 @@ public:
|
||||
void tick();
|
||||
void load_entities(int id, int lc, bool notify); // a LoadEntitiesComponent loads its entities (at spawn, or when its timeout_frames timer comes)
|
||||
long script_runs() const { return script_runs_; } // periodic script executions so far (debug)
|
||||
bool native_projectile_scripts = true;
|
||||
long native_script_runs() const { return native_script_runs_; }
|
||||
// The area whose entities run their scripts (the loaded world around the camera): LuaComponents with execute_every_n_frame, CollisionTriggerComponents.
|
||||
void set_active_area(double cx, double cy, double hw, double hh) { act_cx_ = cx; act_cy_ = cy; act_hw_ = hw; act_hh_ = hh; scripts_on_ = true; }
|
||||
// Runs the script_death scripts of an entity (death(damage types, message, killer, drop_items)): the gold drop, loot, ... The caller kills the entity afterwards.
|
||||
@@ -137,7 +149,9 @@ public:
|
||||
// Kills every entity of the world except the player and what the player carries (the area was left).
|
||||
void clear_world_entities();
|
||||
std::vector<int> with_file(const std::string& part);
|
||||
std::vector<int> with_component(const std::string& type); // living entities with a component of the type // living entities whose file name contains the text
|
||||
std::vector<int> with_component(std::string_view type); // living entities with a component of the type
|
||||
// Incremental indexes for fields changed through set_value (null value: nonempty).
|
||||
std::vector<int> with_component_field(const std::string& type, const std::string& key, const std::optional<std::string>& value = std::nullopt);
|
||||
|
||||
int player() const { return player_id_; }
|
||||
void set_player(int id) { player_id_ = id; }
|
||||
@@ -174,6 +188,7 @@ public:
|
||||
void assign_card_slot(int wand, int card); // a spell card that becomes a child of a wand takes the first free slot of the wand
|
||||
int add_gun_action(int wand, const std::string& action_id, bool permanent) override;
|
||||
std::vector<int> components(int entity, const std::string& type, const std::string& tag, bool include_disabled) override;
|
||||
std::vector<int> components(int entity, const char* type, const std::string& tag, bool include_disabled) { return components_view(entity, type, tag, include_disabled); }
|
||||
int add_component(int entity, const std::string& type, const std::map<std::string, std::string>& attrs) override;
|
||||
void remove_component(int comp) override;
|
||||
void set_component_enabled(int comp, bool enabled) override;
|
||||
@@ -229,19 +244,47 @@ public:
|
||||
|
||||
private:
|
||||
int add_comp_internal(int entity, const std::string& type, std::map<std::string, std::string> attrs);
|
||||
void erase_comp_internal(int component);
|
||||
std::vector<int> components_view(int entity, std::string_view type, const std::string& tag, bool include_disabled);
|
||||
bool run_script_callback(int entity, int comp, const std::string& file, const std::string& function, const std::vector<LVal>& args);
|
||||
bool run_native_guard(int entity, const std::string& file);
|
||||
void update_component_fields(const RtComponent& component, int delta, std::string_view key = {});
|
||||
|
||||
const Wak& wak_;
|
||||
LuaHost& host_;
|
||||
EntityDb db_;
|
||||
std::map<int, RtEntity> ents_;
|
||||
std::map<int, RtComponent> comps_;
|
||||
std::unordered_map<int, RtComponent> comps_;
|
||||
std::map<std::string, std::map<int, int>, std::less<>> entities_by_component_;
|
||||
using FieldQuery = std::tuple<std::string, std::string, std::optional<std::string>>;
|
||||
std::map<FieldQuery, std::map<int, int>> component_fields_;
|
||||
struct LuaSchedule {
|
||||
uint64_t revision = uint64_t(-1);
|
||||
std::string file;
|
||||
int every = 1, times = 0, done = 0, next = -1;
|
||||
bool call_init = false, inited = false, remove = false;
|
||||
};
|
||||
std::unordered_map<int, LuaSchedule> lua_schedules_;
|
||||
struct NativeGuardState {
|
||||
uint64_t revision = uint64_t(-1);
|
||||
int angle_component = 0;
|
||||
const std::string *angle = nullptr, *rotation = nullptr, *owner = nullptr;
|
||||
std::string rotation_text, owner_text;
|
||||
double rotation_value = 0, owner_value = 0;
|
||||
bool has_storage = false;
|
||||
};
|
||||
std::unordered_map<int, NativeGuardState> native_guard_states_;
|
||||
double act_cx_ = 0, act_cy_ = 0, act_hw_ = 0, act_hh_ = 0;
|
||||
bool scripts_on_ = false;
|
||||
long script_runs_ = 0;
|
||||
long native_script_runs_ = 0;
|
||||
uint64_t native_source_revision_ = uint64_t(-1), native_api_revision_ = uint64_t(-1);
|
||||
bool native_guard_source_ = false, native_guard_api_ = false;
|
||||
std::string native_guard_env_;
|
||||
static constexpr int kDynamicIdBase = 1 << 16; // ids below are reserved for forced ids (the initial world entities: GPU slot + 1, the player 1)
|
||||
int next_ent_ = kDynamicIdBase, next_comp_ = 1, frame_ = 0, player_id_ = 0, world_state_ = 0;
|
||||
int updated_entity_ = 0, updated_comp_ = 0;
|
||||
uint64_t component_revision_ = 0;
|
||||
std::vector<GameMessage> messages_;
|
||||
std::vector<std::string> errors_;
|
||||
std::vector<int> pending_scripts_; // entities whose on-added scripts still have to run
|
||||
|
||||
Reference in new issue
Block a user