memory-related refactor

This commit is contained in:
MihailRis 2024-05-19 07:09:58 +03:00
parent f47c7d00a2
commit c5f663b7cb
16 changed files with 205 additions and 209 deletions

View File

@ -11,6 +11,7 @@
#include "../files/engine_paths.hpp"
#include "../content/Content.hpp"
#include "../content/ContentPack.hpp"
#include "../voxels/Block.hpp"
#include "../graphics/core/Texture.hpp"
#include "../logic/scripting/scripting.hpp"
@ -187,7 +188,7 @@ void AssetsLoader::addDefaults(AssetsLoader& loader, const Content* content) {
loader.processPreloadConfigs(content);
for (auto& entry : content->getBlockMaterials()) {
auto& material = entry.second;
auto& material = *entry.second;
loader.tryAddSound(material.stepsSound);
loader.tryAddSound(material.placeSound);
loader.tryAddSound(material.breakSound);

View File

@ -389,7 +389,7 @@ std::unique_ptr<Stream> ALAudio::openStream(std::shared_ptr<PCMStream> stream, b
return std::make_unique<ALStream>(this, stream, keepSource);
}
ALAudio* ALAudio::create() {
std::unique_ptr<ALAudio> ALAudio::create() {
ALCdevice* device = alcOpenDevice(nullptr);
if (device == nullptr)
return nullptr;
@ -400,7 +400,7 @@ ALAudio* ALAudio::create() {
}
AL_CHECK();
logger.info() << "initialized";
return new ALAudio(device, context);
return std::make_unique<ALAudio>(device, context);
}
uint ALAudio::getFreeSource(){

View File

@ -136,9 +136,8 @@ namespace audio {
std::vector<uint> freebuffers;
uint maxSources = 256;
ALAudio(ALCdevice* device, ALCcontext* context);
public:
ALAudio(ALCdevice* device, ALCcontext* context);
~ALAudio();
uint getFreeSource();
@ -164,7 +163,7 @@ namespace audio {
return false;
}
static ALAudio* create();
static std::unique_ptr<ALAudio> create();
};
}

View File

@ -17,6 +17,6 @@ std::unique_ptr<Stream> NoAudio::openStream(std::shared_ptr<PCMStream> stream, b
return std::make_unique<NoStream>(stream, keepSource);
}
NoAudio* NoAudio::create() {
return new NoAudio();
std::unique_ptr<NoAudio> NoAudio::create() {
return std::make_unique<NoAudio>();
}

View File

@ -81,7 +81,7 @@ namespace audio {
return true;
}
static NoAudio* create();
static std::unique_ptr<NoAudio> create();
};
}

View File

@ -147,11 +147,11 @@ public:
void audio::initialize(bool enabled) {
if (enabled) {
backend = ALAudio::create();
backend = ALAudio::create().release();
}
if (backend == nullptr) {
std::cerr << "could not to initialize audio" << std::endl;
backend = NoAudio::create();
backend = NoAudio::create().release();
}
create_channel("master");
}
@ -333,7 +333,7 @@ int audio::create_channel(const std::string& name) {
if (index != -1) {
return index;
}
channels.emplace_back(new Channel(name));
channels.emplace_back(std::make_unique<Channel>(name));
return channels.size()-1;
}

View File

@ -10,127 +10,6 @@
#include "ContentPack.hpp"
#include "../logic/scripting/scripting.hpp"
ContentBuilder::~ContentBuilder() {}
void ContentBuilder::add(Block* def) {
checkIdentifier(def->name);
blockDefs[def->name] = def;
blockIds.push_back(def->name);
}
void ContentBuilder::add(ItemDef* def) {
checkIdentifier(def->name);
itemDefs[def->name] = def;
itemIds.push_back(def->name);
}
void ContentBuilder::add(ContentPackRuntime* pack) {
packs.emplace(pack->getId(), pack);
}
void ContentBuilder::add(BlockMaterial material) {
blockMaterials.emplace(material.name, material);
}
Block& ContentBuilder::createBlock(std::string id) {
auto found = blockDefs.find(id);
if (found != blockDefs.end()) {
return *found->second;
// throw namereuse_error("name "+id+" is already used", contenttype::item);
}
Block* block = new Block(id);
add(block);
return *block;
}
ItemDef& ContentBuilder::createItem(std::string id) {
auto found = itemDefs.find(id);
if (found != itemDefs.end()) {
// if (found->second->generated) {
return *found->second;
// }
// throw namereuse_error("name "+id+" is already used", contenttype::item);
}
ItemDef* item = new ItemDef(id);
add(item);
return *item;
}
void ContentBuilder::checkIdentifier(std::string id) {
contenttype result;
if (((result = checkContentType(id)) != contenttype::none)) {
throw namereuse_error("name "+id+" is already used", result);
}
}
contenttype ContentBuilder::checkContentType(std::string id) {
if (blockDefs.find(id) != blockDefs.end()) {
return contenttype::block;
}
if (itemDefs.find(id) != itemDefs.end()) {
return contenttype::item;
}
return contenttype::none;
}
Content* ContentBuilder::build() {
std::vector<Block*> blockDefsIndices;
auto groups = std::make_unique<DrawGroups>();
for (const std::string& name : blockIds) {
Block* def = blockDefs[name];
// Generating runtime info
def->rt.id = blockDefsIndices.size();
def->rt.emissive = *reinterpret_cast<uint32_t*>(def->emission);
def->rt.solid = def->model == BlockModel::block;
if (def->rotatable) {
for (uint i = 0; i < BlockRotProfile::MAX_COUNT; i++) {
def->rt.hitboxes[i].reserve(def->hitboxes.size());
for (AABB aabb : def->hitboxes) {
def->rotations.variants[i].transform(aabb);
def->rt.hitboxes[i].push_back(aabb);
}
}
}
blockDefsIndices.push_back(def);
groups->insert(def->drawGroup);
}
std::vector<ItemDef*> itemDefsIndices;
for (const std::string& name : itemIds) {
ItemDef* def = itemDefs[name];
// Generating runtime info
def->rt.id = itemDefsIndices.size();
def->rt.emissive = *reinterpret_cast<uint32_t*>(def->emission);
itemDefsIndices.push_back(def);
}
auto indices = new ContentIndices(blockDefsIndices, itemDefsIndices);
auto content = std::make_unique<Content>(
indices,
std::move(groups),
blockDefs,
itemDefs,
std::move(packs),
std::move(blockMaterials)
);
// Now, it's time to resolve foreign keys
for (Block* def : blockDefsIndices) {
def->rt.pickingItem = content->requireItem(def->pickingItem).rt.id;
}
for (ItemDef* def : itemDefsIndices) {
def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id;
}
return content.release();
}
ContentIndices::ContentIndices(
std::vector<Block*> blockDefs,
std::vector<ItemDef*> itemDefs
@ -139,27 +18,21 @@ ContentIndices::ContentIndices(
{}
Content::Content(
ContentIndices* indices,
std::unique_ptr<ContentIndices> indices,
std::unique_ptr<DrawGroups> drawGroups,
std::unordered_map<std::string, Block*> blockDefs,
std::unordered_map<std::string, ItemDef*> itemDefs,
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs,
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs,
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
std::unordered_map<std::string, BlockMaterial> blockMaterials
) : blockDefs(blockDefs),
itemDefs(itemDefs),
indices(indices),
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
) : blockDefs(std::move(blockDefs)),
itemDefs(std::move(itemDefs)),
indices(std::move(indices)),
packs(std::move(packs)),
blockMaterials(std::move(blockMaterials)),
drawGroups(std::move(drawGroups))
{}
Content::~Content() {
for (auto& entry : blockDefs) {
delete entry.second;
}
for (auto& entry : itemDefs) {
delete entry.second;
}
}
Block* Content::findBlock(std::string id) const {
@ -167,7 +40,7 @@ Block* Content::findBlock(std::string id) const {
if (found == blockDefs.end()) {
return nullptr;
}
return found->second;
return found->second.get();
}
Block& Content::requireBlock(std::string id) const {
@ -183,7 +56,7 @@ ItemDef* Content::findItem(std::string id) const {
if (found == itemDefs.end()) {
return nullptr;
}
return found->second;
return found->second.get();
}
ItemDef& Content::requireItem(std::string id) const {
@ -199,7 +72,7 @@ const BlockMaterial* Content::findBlockMaterial(std::string id) const {
if (found == blockMaterials.end()) {
return nullptr;
}
return &found->second;
return found->second.get();
}
const ContentPackRuntime* Content::getPackRuntime(std::string id) const {
@ -210,7 +83,7 @@ const ContentPackRuntime* Content::getPackRuntime(std::string id) const {
return found->second.get();
}
const std::unordered_map<std::string, BlockMaterial>& Content::getBlockMaterials() const {
const std::unordered_map<std::string, std::unique_ptr<BlockMaterial>>& Content::getBlockMaterials() const {
return blockMaterials;
}

View File

@ -1,17 +1,19 @@
#ifndef CONTENT_CONTENT_HPP_
#define CONTENT_CONTENT_HPP_
#include "../typedefs.hpp"
#include <string>
#include <vector>
#include <memory>
#include <stdexcept>
#include <unordered_map>
#include <set>
#include "../typedefs.hpp"
#include "../voxels/Block.hpp"
using DrawGroups = std::set<ubyte>;
class Block;
struct BlockMaterial;
class ItemDef;
class Content;
class ContentPackRuntime;
@ -41,33 +43,6 @@ public:
}
};
class ContentBuilder {
std::unordered_map<std::string, Block*> blockDefs;
std::vector<std::string> blockIds;
std::unordered_map<std::string, ItemDef*> itemDefs;
std::vector<std::string> itemIds;
std::unordered_map<std::string, BlockMaterial> blockMaterials;
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs;
public:
~ContentBuilder();
void add(Block* def);
void add(ItemDef* def);
void add(ContentPackRuntime* pack);
void add(BlockMaterial material);
Block& createBlock(std::string id);
ItemDef& createItem(std::string id);
void checkIdentifier(std::string id);
contenttype checkContentType(std::string id);
Content* build();
};
/// @brief Runtime defs cache: indices
class ContentIndices {
std::vector<Block*> blockDefs;
@ -110,21 +85,21 @@ public:
/* Content is a definitions repository */
class Content {
std::unordered_map<std::string, Block*> blockDefs;
std::unordered_map<std::string, ItemDef*> itemDefs;
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs;
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs;
std::unique_ptr<ContentIndices> indices;
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs;
std::unordered_map<std::string, BlockMaterial> blockMaterials;
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials;
public:
std::unique_ptr<DrawGroups> const drawGroups;
Content(
ContentIndices* indices,
std::unique_ptr<ContentIndices> indices,
std::unique_ptr<DrawGroups> drawGroups,
std::unordered_map<std::string, Block*> blockDefs,
std::unordered_map<std::string, ItemDef*> itemDefs,
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs,
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs,
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
std::unordered_map<std::string, BlockMaterial> blockMaterials
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
);
~Content();
@ -142,7 +117,7 @@ public:
const ContentPackRuntime* getPackRuntime(std::string id) const;
const std::unordered_map<std::string, BlockMaterial>& getBlockMaterials() const;
const std::unordered_map<std::string, std::unique_ptr<BlockMaterial>>& getBlockMaterials() const;
const std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>>& getPacks() const;
};

View File

@ -0,0 +1,109 @@
#include "ContentBuilder.hpp"
ContentBuilder::~ContentBuilder() {}
void ContentBuilder::add(std::unique_ptr<ContentPackRuntime> pack) {
packs[pack->getId()] = std::move(pack);
}
Block& ContentBuilder::createBlock(std::string id) {
auto found = blockDefs.find(id);
if (found != blockDefs.end()) {
return *found->second;
}
checkIdentifier(id);
blockIds.push_back(id);
blockDefs[id] = std::make_unique<Block>(id);
return *blockDefs[id];
}
ItemDef& ContentBuilder::createItem(std::string id) {
auto found = itemDefs.find(id);
if (found != itemDefs.end()) {
return *found->second;
}
checkIdentifier(id);
itemIds.push_back(id);
itemDefs[id] = std::make_unique<ItemDef>(id);
return *itemDefs[id];
}
BlockMaterial& ContentBuilder::createBlockMaterial(std::string id) {
blockMaterials[id] = std::make_unique<BlockMaterial>();
auto& material = *blockMaterials[id];
material.name = id;
return material;
}
void ContentBuilder::checkIdentifier(std::string id) {
contenttype result;
if (((result = checkContentType(id)) != contenttype::none)) {
throw namereuse_error("name "+id+" is already used", result);
}
}
contenttype ContentBuilder::checkContentType(std::string id) {
if (blockDefs.find(id) != blockDefs.end()) {
return contenttype::block;
}
if (itemDefs.find(id) != itemDefs.end()) {
return contenttype::item;
}
return contenttype::none;
}
std::unique_ptr<Content> ContentBuilder::build() {
std::vector<Block*> blockDefsIndices;
auto groups = std::make_unique<DrawGroups>();
for (const std::string& name : blockIds) {
Block& def = *blockDefs[name];
// Generating runtime info
def.rt.id = blockDefsIndices.size();
def.rt.emissive = *reinterpret_cast<uint32_t*>(def.emission);
def.rt.solid = def.model == BlockModel::block;
if (def.rotatable) {
for (uint i = 0; i < BlockRotProfile::MAX_COUNT; i++) {
def.rt.hitboxes[i].reserve(def.hitboxes.size());
for (AABB& aabb : def.hitboxes) {
def.rotations.variants[i].transform(aabb);
def.rt.hitboxes[i].push_back(aabb);
}
}
}
blockDefsIndices.push_back(&def);
groups->insert(def.drawGroup);
}
std::vector<ItemDef*> itemDefsIndices;
for (const std::string& name : itemIds) {
ItemDef& def = *itemDefs[name];
// Generating runtime info
def.rt.id = itemDefsIndices.size();
def.rt.emissive = *reinterpret_cast<uint32_t*>(def.emission);
itemDefsIndices.push_back(&def);
}
auto content = std::make_unique<Content>(
std::make_unique<ContentIndices>(blockDefsIndices, itemDefsIndices),
std::move(groups),
std::move(blockDefs),
std::move(itemDefs),
std::move(packs),
std::move(blockMaterials)
);
// Now, it's time to resolve foreign keys
for (Block* def : blockDefsIndices) {
def->rt.pickingItem = content->requireItem(def->pickingItem).rt.id;
}
for (ItemDef* def : itemDefsIndices) {
def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id;
}
return content;
}

View File

@ -0,0 +1,37 @@
#ifndef CONTENT_CONTENT_BUILDER_HPP_
#define CONTENT_CONTENT_BUILDER_HPP_
#include "../items/ItemDef.hpp"
#include "../voxels/Block.hpp"
#include "../content/Content.hpp"
#include "../content/ContentPack.hpp"
#include <memory>
#include <vector>
#include <unordered_map>
class ContentBuilder {
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs;
std::vector<std::string> blockIds;
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs;
std::vector<std::string> itemIds;
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials;
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs;
public:
~ContentBuilder();
void add(std::unique_ptr<ContentPackRuntime> pack);
Block& createBlock(std::string id);
ItemDef& createItem(std::string id);
BlockMaterial& createBlockMaterial(std::string id);
void checkIdentifier(std::string id);
contenttype checkContentType(std::string id);
std::unique_ptr<Content> build();
};
#endif // CONTENT_CONTENT_BUILDER_HPP_

View File

@ -2,6 +2,7 @@
#include "Content.hpp"
#include "ContentPack.hpp"
#include "ContentBuilder.hpp"
#include "../coders/json.hpp"
#include "../core_defs.hpp"
#include "../data/dynamic.hpp"
@ -26,9 +27,11 @@ static debug::Logger logger("content-loader");
ContentLoader::ContentLoader(ContentPack* pack) : pack(pack) {
}
bool ContentLoader::fixPackIndices(fs::path folder,
dynamic::Map* indicesRoot,
std::string contentSection) {
bool ContentLoader::fixPackIndices(
fs::path folder,
dynamic::Map* indicesRoot,
std::string contentSection
) {
std::vector<std::string> detected;
std::vector<std::string> indexed;
if (fs::is_directory(folder)) {
@ -312,22 +315,22 @@ void ContentLoader::loadItem(ItemDef& def, std::string full, std::string name) {
}
}
BlockMaterial ContentLoader::loadBlockMaterial(fs::path file, std::string full) {
void ContentLoader::loadBlockMaterial(BlockMaterial& def, fs::path file) {
auto root = files::read_json(file);
BlockMaterial material {full};
root->str("steps-sound", material.stepsSound);
root->str("place-sound", material.placeSound);
root->str("break-sound", material.breakSound);
return material;
root->str("steps-sound", def.stepsSound);
root->str("place-sound", def.placeSound);
root->str("break-sound", def.breakSound);
}
void ContentLoader::load(ContentBuilder& builder) {
logger.info() << "loading pack [" << pack->id << "]";
auto runtime = new ContentPackRuntime(*pack, scripting::create_pack_environment(*pack));
builder.add(runtime);
auto runtime = std::make_unique<ContentPackRuntime>(
*pack, scripting::create_pack_environment(*pack)
);
env = runtime->getEnvironment();
ContentPackStats& stats = runtime->getStatsWriteable();
builder.add(std::move(runtime));
fixPackIndices();
@ -388,7 +391,7 @@ void ContentLoader::load(ContentBuilder& builder) {
for (auto entry : fs::directory_iterator(materialsDir)) {
fs::path file = entry.path();
std::string name = pack->id+":"+file.stem().u8string();
builder.add(loadBlockMaterial(file, name));
loadBlockMaterial(builder.createBlockMaterial(name), file);
}
}
}

View File

@ -1,13 +1,15 @@
#ifndef CONTENT_CONTENT_LOADER_HPP_
#define CONTENT_CONTENT_LOADER_HPP_
#include "../voxels/Block.hpp"
#include "../typedefs.hpp"
#include <string>
#include <filesystem>
namespace fs = std::filesystem;
class Block;
struct BlockMaterial;
class ItemDef;
struct ContentPack;
class ContentBuilder;
@ -23,7 +25,7 @@ class ContentLoader {
void loadBlock(Block& def, std::string full, std::string name);
void loadCustomBlockModel(Block& def, dynamic::Map* primitives);
void loadItem(ItemDef& def, std::string full, std::string name);
BlockMaterial loadBlockMaterial(fs::path file, std::string full);
void loadBlockMaterial(BlockMaterial& def, fs::path file);
public:
ContentLoader(ContentPack* pack);

View File

@ -12,17 +12,11 @@ class EnginePaths;
namespace fs = std::filesystem;
namespace scripting {
class Environment;
}
class contentpack_error : public std::runtime_error {
std::string packId;
fs::path folder;
public:
contentpack_error(std::string packId,
fs::path folder,
std::string message);
contentpack_error(std::string packId, fs::path folder, std::string message);
std::string getPackId() const;
fs::path getFolder() const;

View File

@ -2,6 +2,7 @@
#include "items/ItemDef.hpp"
#include "content/Content.hpp"
#include "content/ContentBuilder.hpp"
#include "window/Window.hpp"
#include "window/Events.hpp"
#include "window/input.hpp"

View File

@ -9,6 +9,7 @@
#include "coders/imageio.hpp"
#include "coders/json.hpp"
#include "coders/toml.hpp"
#include "content/ContentBuilder.hpp"
#include "content/ContentLoader.hpp"
#include "core_defs.hpp"
#include "files/files.hpp"
@ -273,7 +274,7 @@ void Engine::loadContent() {
ContentLoader loader(&pack);
loader.load(contentBuilder);
}
content.reset(contentBuilder.build());
content = contentBuilder.build();
resPaths = std::make_unique<ResPaths>(resdir, resRoots);
langs::setup(resdir, langs::current->getId(), contentPacks);

View File

@ -5,6 +5,7 @@
#include "../../graphics/core/Batch2D.hpp"
#include "../../graphics/core/Shader.hpp"
#include "../../graphics/core/Texture.hpp"
#include "../../maths/UVRegion.hpp"
#include "../../window/Window.hpp"
#include "../../window/Camera.hpp"
#include "../../engine.hpp"