Skip to content

Commit

Permalink
feat(engine): add asset explorer
Browse files Browse the repository at this point in the history
  • Loading branch information
DiogoMendonc-a authored and RiscadoA committed Jun 18, 2023
1 parent bee18d2 commit 41c836a
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 6 deletions.
4 changes: 2 additions & 2 deletions core/src/cubos/core/data/binary_deserializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ std::size_t BinaryDeserializer::beginArray()
{
uint64_t size;
this->readU64(size);
return size;
return (std::size_t)size;
}

void BinaryDeserializer::endArray()
Expand All @@ -115,7 +115,7 @@ std::size_t BinaryDeserializer::beginDictionary()
{
uint64_t size;
this->readU64(size);
return size;
return (std::size_t)size;
}

void BinaryDeserializer::endDictionary()
Expand Down
2 changes: 2 additions & 0 deletions engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ set(CUBOS_ENGINE_SOURCE
"src/cubos/engine/file_settings/plugin.cpp"
"src/cubos/engine/imgui/plugin.cpp"

"src/cubos/engine/tools/asset_explorer/plugin.cpp"
"src/cubos/engine/tools/settings_inspector/plugin.cpp"
"src/cubos/engine/tools/entity_selector/plugin.cpp"
"src/cubos/engine/tools/world_inspector/plugin.cpp"
Expand Down Expand Up @@ -66,6 +67,7 @@ set(CUBOS_ENGINE_INCLUDE
"include/cubos/engine/file_settings/plugin.hpp"
"include/cubos/engine/imgui/plugin.hpp"

"include/cubos/engine/tools/asset_explorer/plugin.hpp"
"include/cubos/engine/tools/settings_inspector/plugin.hpp"
"include/cubos/engine/tools/entity_selector/plugin.hpp"
"include/cubos/engine/tools/world_inspector/plugin.hpp"
Expand Down
4 changes: 4 additions & 0 deletions engine/include/cubos/engine/assets/assets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ namespace cubos::engine
[](void* data) { delete static_cast<T*>(data); });
}

/// Gets all assets that have been registered
/// @returns a vector with all registered assets.
std::vector<AnyAsset> listAll() const;

private:
/// Represents a known asset - may or may not be loaded.
struct Entry
Expand Down
25 changes: 25 additions & 0 deletions engine/include/cubos/engine/tools/asset_explorer/plugin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <cubos/engine/assets/plugin.hpp>

namespace cubos::engine::tools
{
/// @brief Event sent when an asset is selected.
struct AssetSelectedEvent {
AnyAsset asset;
};

/// Plugin that allows exploring and selecting assets through a ImGui window.
///
/// @details This plugin adds one system, which adds a ImGui window with the assets folder.
///
/// Dependencies:
/// - `imguiPlugin`
/// - `assetsPlugin`
///
/// Events:
/// - `AssetSelectedEvent`: sent when an asset is selected in the explorer.
///
/// @param cubos CUBOS. main class
void assetExplorerPlugin(Cubos& cubos);
} // namespace cubos::engine::tools
8 changes: 8 additions & 0 deletions engine/src/cubos/engine/assets/assets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -591,3 +591,11 @@ void Assets::loader()
}
}
}

std::vector<AnyAsset> Assets::listAll() const {
std::vector<AnyAsset> out;
for (auto const& [entry,_] : mEntries) {
out.emplace_back(entry);
}
return out;
}
140 changes: 140 additions & 0 deletions engine/src/cubos/engine/tools/asset_explorer/plugin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include <imgui.h>

#include <cubos/core/settings.hpp>

#include <cubos/engine/assets/plugin.hpp>
#include <cubos/engine/imgui/plugin.hpp>
#include <cubos/engine/tools/asset_explorer/plugin.hpp>

using cubos::core::ecs::Read;
using cubos::core::ecs::EventWriter;

using namespace cubos::engine;

static bool assetsCompare(AnyAsset const& a, AnyAsset const& b, Assets const& assets)
{
std::string aPath = assets.readMeta(a)->get("path").value();
std::string bPath = assets.readMeta(b)->get("path").value();

auto aCount = std::count(aPath.begin(), aPath.end(), '/');
auto bCount = std::count(bPath.begin(), bPath.end(), '/');

std::string aDir = aPath;
std::string bDir = bPath;

aDir.erase(aDir.rfind("/"));
bDir.erase(bDir.rfind("/"));

if (aCount != bCount)
{
if (aDir.find(bDir + "/") != std::string::npos)
{
return true;
}
else if (bDir.find(aDir + "/") != std::string::npos)
{
return false;
}
}

return aPath.compare(bPath) > 0;
}

static void showAsset(Assets const& assets, AnyAsset const& asset, EventWriter<tools::AssetSelectedEvent> events)
{
std::string path = assets.readMeta(asset)->get("path").value();
ImGui::PushID(path.c_str());
ImGui::BulletText("%s", path.erase(0, path.rfind("/") + 1).c_str());
ImGui::SameLine();
if (ImGui::Button("Select"))
{
events.push(tools::AssetSelectedEvent{asset});
}
ImGui::PopID();
}

static std::vector<AnyAsset>::iterator showFolder(Assets const& assets, std::string const& folder,
std::vector<AnyAsset>::iterator iter, std::vector<AnyAsset>::iterator end,
EventWriter<tools::AssetSelectedEvent> events)
{
std::string displayName = folder;
displayName.erase(0, displayName.rfind("/"));

ImGui::PushStyleColor(ImGuiCol_Text, (ImVec4)ImColor(149, 252, 75));
if (ImGui::TreeNode(displayName.c_str()))
{
ImGui::PopStyleColor(1);
while (iter != end)
{
AnyAsset asset = *iter;
std::string assetPath = assets.readMeta(asset)->get("path").value();
if (assetPath.find(folder + "/") == std::string::npos)
{
break;
}

std::string dirless = assetPath;
dirless.erase(0, folder.length() + 1);
auto pos = dirless.find('/');
if (pos != std::string::npos)
{
std::string subfolder = folder + "/" + dirless.substr(0, pos);
iter = showFolder(assets, subfolder, iter, end, events);
}
else
{
showAsset(assets, *iter, events);
iter++;
}
}
ImGui::TreePop();
}
else
{
ImGui::PopStyleColor(1);
while (iter != end)
{
if (assets.readMeta(*iter)->get("path").value().find(folder + "/") == std::string::npos)
{
break;
}
iter++;
}
}
return iter;
}

static void showAssets(Read<Assets> assets, Read<cubos::core::Settings> settings,
EventWriter<tools::AssetSelectedEvent> events)
{
ImGui::Begin("Asset Explorer");

std::string folder = settings->getString("assets.io.path", "");

folder.erase(0, folder.rfind("/"));

std::vector<AnyAsset> assetsVector;
for (auto const& a : assets->listAll())
{
if (assets->readMeta(a)->get("path").has_value())
{
assetsVector.push_back(a);
}
}
std::sort(assetsVector.begin(), assetsVector.end(),
[assets](AnyAsset const& a, AnyAsset const& b) { return assetsCompare(a, b, *assets); });

showFolder((*assets), folder, assetsVector.begin(), assetsVector.end(), events);

ImGui::End();
}

void cubos::engine::tools::assetExplorerPlugin(Cubos& cubos)
{
cubos.addEvent<AssetSelectedEvent>();

cubos.addPlugin(imguiPlugin);
cubos.addPlugin(assetsPlugin);

cubos.system(showAssets).tagged("cubos.imgui");
}
2 changes: 2 additions & 0 deletions tools/tesserato/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ set(TESSERATO_SOURCE
add_executable(tesserato ${TESSERATO_SOURCE})
target_link_libraries(tesserato PUBLIC cubos-core cubos-engine)
cubos_common_target_options(tesserato)

target_compile_definitions(tesserato PUBLIC TESSERATO_ASSETS_FOLDER="${CMAKE_CURRENT_SOURCE_DIR}/assets")
Empty file.
3 changes: 3 additions & 0 deletions tools/tesserato/assets/example_asset.txt.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"id": "059c16e7-a439-44c7-9bdc-6e069dba0c75"
}
Empty file.
3 changes: 3 additions & 0 deletions tools/tesserato/assets/subfolder/example_asset_2.txt.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"id": "059c16e7-a449-44c7-9bdc-6e069dba0c75"
}
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"id": "059c16e7-a449-44c7-0bdc-6e069dba0c75"
}
30 changes: 26 additions & 4 deletions tools/tesserato/src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,41 @@
#include <imgui.h>

#include <cubos/engine/imgui/plugin.hpp>
#include <cubos/engine/tools/asset_explorer/plugin.hpp>

#include <cubos/engine/renderer/plugin.hpp>
#include <cubos/engine/transform/plugin.hpp>

#include <cubos/core/settings.hpp>

using namespace cubos::engine;
using cubos::core::ecs::Write;
using cubos::core::ecs::Commands;

static void show()
static void mockCamera(Write<ActiveCameras> camera, Commands cmds) {
camera->entities[0] = cmds.create()
.add(Camera{.fovY = 60.0F, .zNear = 0.1F, .zFar = 100.0F})
.add(LocalToWorld{})
.add(Position{{5.0F, 5.0F, -10.0F}})
.add(Rotation{glm::quatLookAt(glm::vec3{0.0F, 0.0F, 1.0F}, glm::vec3{0.0F, 1.0F, 0.0F})})
.entity();

}

static void mockSettings(Write<cubos::core::Settings> settings)
{
ImGui::Begin("Editor");
ImGui::End();
settings->setString("assets.io.path", TESSERATO_ASSETS_FOLDER);
}

int main(int argc, char** argv)
{
Cubos cubos(argc, argv);
cubos.addPlugin(imguiPlugin);
cubos.system(show).tagged("cubos.imgui");
cubos.addPlugin(rendererPlugin);
cubos.addPlugin(tools::assetExplorerPlugin);

cubos.startupSystem(mockCamera).tagged("setup");
cubos.startupSystem(mockSettings).tagged("setup");

cubos.run();
}

0 comments on commit 41c836a

Please sign in to comment.