Compare commits
2 Commits
609f7337da
...
851e1ee122
| Author | SHA1 | Date | |
|---|---|---|---|
| 851e1ee122 | |||
| fbd6d43e89 |
@ -1,220 +0,0 @@
|
|||||||
#include <backends/imgui_impl_sdl2.h>
|
|
||||||
#include <backends/imgui_impl_sdlrenderer2.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include "MainWindow.hpp"
|
|
||||||
#include "gui_exceptions.hpp"
|
|
||||||
#include "../common/ougge_format.hpp"
|
|
||||||
#include "../common/math.hpp"
|
|
||||||
|
|
||||||
namespace ougge::gui {
|
|
||||||
|
|
||||||
f32 MainWindow::getDPI(){
|
|
||||||
i32 w=0, h=0;
|
|
||||||
SDL_GetRendererOutputSize(sdl_renderer, &w, &h);
|
|
||||||
i32 sim_w=0, sim_h=0;
|
|
||||||
SDL_GetWindowSize(sdl_window, &sim_w, &sim_h);
|
|
||||||
f32 wdpi=(f32)w / sim_w;
|
|
||||||
f32 hdpi=(f32)h / sim_h;
|
|
||||||
f32 dpi=SDL_sqrtf(wdpi*wdpi + hdpi*hdpi);
|
|
||||||
return dpi;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::open(const std::string& window_title, resources::ResourceManager& resourceManager){
|
|
||||||
SDL_TRY(SDL_Init(SDL_INIT_EVERYTHING));
|
|
||||||
SDL_version v;
|
|
||||||
SDL_GetVersion(&v);
|
|
||||||
std::cout<<ougge_format("SDL version: %u.%u.%u\n", v.major, v.minor, v.patch);
|
|
||||||
|
|
||||||
// From 2.0.18: Enable native IME.
|
|
||||||
#ifdef SDL_HINT_IME_SHOW_UI
|
|
||||||
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(
|
|
||||||
SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI
|
|
||||||
);
|
|
||||||
sdl_window = SDL_CreateWindow(window_title.c_str(),
|
|
||||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
|
||||||
1280, 720, window_flags);
|
|
||||||
if(sdl_window == nullptr)
|
|
||||||
throw SDLException();
|
|
||||||
|
|
||||||
SDL_RendererFlags renderer_flags = (SDL_RendererFlags)(
|
|
||||||
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
|
|
||||||
);
|
|
||||||
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, renderer_flags);
|
|
||||||
if(sdl_renderer == nullptr)
|
|
||||||
throw SDLException();
|
|
||||||
|
|
||||||
SDL_RendererInfo info;
|
|
||||||
SDL_GetRendererInfo(sdl_renderer, &info);
|
|
||||||
std::cout<<"Current SDL_Renderer driver: "<<info.name<<std::endl;
|
|
||||||
|
|
||||||
// Setup Dear ImGui context
|
|
||||||
IMGUI_CHECKVERSION();
|
|
||||||
ImGui::CreateContext();
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
||||||
io.ConfigDockingTransparentPayload = true;
|
|
||||||
io.ConfigInputTextCursorBlink = false;
|
|
||||||
// io.ConfigViewportsNoTaskBarIcon = true;
|
|
||||||
io.ConfigWindowsMoveFromTitleBarOnly = true;
|
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
|
||||||
if(!ImGui_ImplSDL2_InitForSDLRenderer(sdl_window, sdl_renderer))
|
|
||||||
throw SDLException();
|
|
||||||
if(!ImGui_ImplSDLRenderer2_Init(sdl_renderer))
|
|
||||||
throw SDLException();
|
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
|
||||||
ImGui::StyleColorsDark();
|
|
||||||
|
|
||||||
resources::ResourceFactory* font_res = resourceManager.tryGetResource(default_font_path);
|
|
||||||
if(font_res == nullptr)
|
|
||||||
throw UsefulException("can't find default font resource");
|
|
||||||
f32 dpi = getDPI();
|
|
||||||
io.FontDefault = resources::ImFont_LoadFromResource(font_res, default_font_size, dpi);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::close(){
|
|
||||||
ImGui_ImplSDLRenderer2_Shutdown();
|
|
||||||
ImGui_ImplSDL2_Shutdown();
|
|
||||||
ImGui::DestroyContext();
|
|
||||||
SDL_DestroyRenderer(sdl_renderer);
|
|
||||||
SDL_DestroyWindow(sdl_window);
|
|
||||||
SDL_Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::pollEvents(bool* loopRunning){
|
|
||||||
SDL_Event event;
|
|
||||||
while (SDL_PollEvent(&event)) {
|
|
||||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
|
||||||
switch(event.type){
|
|
||||||
case SDL_QUIT: {
|
|
||||||
*loopRunning = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SDL_WINDOWEVENT: {
|
|
||||||
if(event.window.event == SDL_WINDOWEVENT_CLOSE
|
|
||||||
&& event.window.windowID == SDL_GetWindowID(sdl_window))
|
|
||||||
{
|
|
||||||
*loopRunning = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void MainWindow::beginFrame(){
|
|
||||||
// Start the Dear ImGui frame
|
|
||||||
ImGui_ImplSDLRenderer2_NewFrame();
|
|
||||||
ImGui_ImplSDL2_NewFrame();
|
|
||||||
ImGui::NewFrame();
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
SDL_RenderSetScale(sdl_renderer, io.DisplayFramebufferScale.x, io.DisplayFramebufferScale.y);
|
|
||||||
SDL_SetRenderDrawColor(sdl_renderer,
|
|
||||||
(u8)(clear_color.x * 255),
|
|
||||||
(u8)(clear_color.y * 255),
|
|
||||||
(u8)(clear_color.z * 255),
|
|
||||||
(u8)(clear_color.w * 255));
|
|
||||||
SDL_RenderClear(sdl_renderer);
|
|
||||||
|
|
||||||
draw_bg_window();
|
|
||||||
draw_debug_window();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::endFrame(){
|
|
||||||
ImGui::Render();
|
|
||||||
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(), sdl_renderer);
|
|
||||||
// Swap buffers
|
|
||||||
SDL_RenderPresent(sdl_renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::draw_bg_window(){
|
|
||||||
const ImGuiDockNodeFlags dockspace_flags =
|
|
||||||
ImGuiDockNodeFlags_PassthruCentralNode;
|
|
||||||
const ImGuiWindowFlags window_flags =
|
|
||||||
ImGuiWindowFlags_MenuBar |
|
|
||||||
ImGuiWindowFlags_NoDocking |
|
|
||||||
ImGuiWindowFlags_NoScrollbar |
|
|
||||||
ImGuiWindowFlags_NoScrollWithMouse |
|
|
||||||
ImGuiWindowFlags_NoBringToFrontOnFocus |
|
|
||||||
ImGuiWindowFlags_NoFocusOnAppearing |
|
|
||||||
ImGuiWindowFlags_NoMove |
|
|
||||||
ImGuiWindowFlags_NoResize |
|
|
||||||
ImGuiWindowFlags_NoCollapse |
|
|
||||||
ImGuiWindowFlags_NoTitleBar |
|
|
||||||
ImGuiWindowFlags_NoBackground;
|
|
||||||
// not dockable window that always bound to viewport
|
|
||||||
ImGuiViewport* viewport = ImGui::GetWindowViewport();
|
|
||||||
ImGui::SetNextWindowPos(viewport->Pos, ImGuiCond_Always);
|
|
||||||
ImGui::SetNextWindowSize(viewport->Size, ImGuiCond_Always);
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
|
||||||
ImGui::Begin("bg_window", nullptr, window_flags);
|
|
||||||
ImGui::PopStyleVar(3);
|
|
||||||
|
|
||||||
// DockSpace
|
|
||||||
ImGuiID dockspace_id = ImGui::GetID("bg_dockspace");
|
|
||||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
|
||||||
|
|
||||||
// MenuBar
|
|
||||||
if(ImGui::BeginMainMenuBar()){
|
|
||||||
if(ImGui::BeginMenu("test")){
|
|
||||||
if(ImGui::MenuItem("throw exception")){
|
|
||||||
ImGui::EndMenu();
|
|
||||||
ImGui::EndMainMenuBar();
|
|
||||||
ImGui::End();
|
|
||||||
throw UsefulException("example exception");
|
|
||||||
}
|
|
||||||
if(ImGui::MenuItem("throw const char*")){
|
|
||||||
ImGui::EndMenu();
|
|
||||||
ImGui::EndMainMenuBar();
|
|
||||||
ImGui::End();
|
|
||||||
throw "cptr";
|
|
||||||
}
|
|
||||||
if(ImGui::MenuItem("throw std::string")){
|
|
||||||
ImGui::EndMenu();
|
|
||||||
ImGui::EndMainMenuBar();
|
|
||||||
ImGui::End();
|
|
||||||
throw std::string("str");
|
|
||||||
}
|
|
||||||
if(ImGui::MenuItem("throw unknown")){
|
|
||||||
ImGui::EndMenu();
|
|
||||||
ImGui::EndMainMenuBar();
|
|
||||||
ImGui::End();
|
|
||||||
throw 111;
|
|
||||||
}
|
|
||||||
ImGui::EndMenu();
|
|
||||||
}
|
|
||||||
ImGui::EndMainMenuBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::draw_debug_window(){
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
if(ImGui::Begin("Debug Options", &show_debug_window)){
|
|
||||||
ImGui::ColorEdit3("clear_color", (float*)&clear_color);
|
|
||||||
ImGui::InputInt("fps_max", &fps_max);
|
|
||||||
ImGui::Text("Application average %.3f ms/frame (%.2f FPS)", 1000.0f / io.Framerate, io.Framerate);
|
|
||||||
ImGui::Checkbox("Demo Window", &show_demo_window);
|
|
||||||
ImGui::Checkbox("Metrics/Debug Window", &show_metrics_window);
|
|
||||||
ImGui::End();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (show_demo_window)
|
|
||||||
ImGui::ShowDemoWindow(&show_demo_window);
|
|
||||||
|
|
||||||
if (show_metrics_window)
|
|
||||||
ImGui::ShowMetricsWindow(&show_metrics_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
#include <imgui.h>
|
|
||||||
#include "../common/std.hpp"
|
|
||||||
#include "../common/time.hpp"
|
|
||||||
#include "../resources/resources.hpp"
|
|
||||||
#include "../resources/fonts.hpp"
|
|
||||||
|
|
||||||
/// converts hex color to float vector
|
|
||||||
#define RGBAHexToF(R8,G8,B8,A8) ImVec4(((u8)35)/255.0f, ((u8)35)/255.0f, ((u8)50)/255.0f, ((u8)255)/255.0f)
|
|
||||||
/// converts float vector to hex color
|
|
||||||
#define RGBAFToHex(VEC4) {(u8)(VEC4.x*255), (u8)(VEC4.y*255), (u8)(VEC4.z*255), (u8)(VEC4.w*255)}
|
|
||||||
|
|
||||||
namespace ougge::gui {
|
|
||||||
|
|
||||||
#define default_font_path "fonts/DroidSans.ttf"
|
|
||||||
|
|
||||||
class MainWindow {
|
|
||||||
public:
|
|
||||||
i32 fps_max = 60;
|
|
||||||
f32 default_font_size = 14.0f;
|
|
||||||
ImVec4 clear_color = RGBAHexToF(35,35,50,255);
|
|
||||||
SDL_Window* sdl_window = nullptr;
|
|
||||||
SDL_Renderer* sdl_renderer = nullptr;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool show_debug_window = true;
|
|
||||||
bool show_demo_window = false;
|
|
||||||
bool show_metrics_window = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
void open(const std::string& window_title, resources::ResourceManager& resourceManager);
|
|
||||||
void close();
|
|
||||||
|
|
||||||
/// process io events happened since previous frame
|
|
||||||
void pollEvents(bool* loopRunning);
|
|
||||||
void beginFrame();
|
|
||||||
void endFrame();
|
|
||||||
|
|
||||||
f32 getDPI();
|
|
||||||
private:
|
|
||||||
void draw_debug_window();
|
|
||||||
void draw_bg_window();
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
#include "GameObject.hpp"
|
|
||||||
|
|
||||||
namespace ougge::game {
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& s, Transform& t){
|
|
||||||
s<<"{ position: {x: "<<t.position.x<<", y: "<<t.position.y;
|
|
||||||
s<<"}, rotation: "<<t.rotation;
|
|
||||||
s<<", scale {x: "<<t.scale.x<<", y: "<<t.scale.y<<"} }";
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameObject::GameObject(Mono::Object managed_obj)
|
|
||||||
: object_handle(managed_obj)
|
|
||||||
{}
|
|
||||||
|
|
||||||
GameObject::GameObject(GameObject &&o) :
|
|
||||||
object_handle(std::move(o.object_handle)),
|
|
||||||
parent(o.parent),
|
|
||||||
transform(o.transform)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GameObject& GameObject::operator=(GameObject &&o){
|
|
||||||
object_handle = std::move(o.object_handle);
|
|
||||||
parent = o.parent;
|
|
||||||
transform = o.transform;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <iostream>
|
|
||||||
#include "../common/math.hpp"
|
|
||||||
#include "../common/UsefulException.hpp"
|
|
||||||
#include "../mono/mono.hpp"
|
|
||||||
|
|
||||||
namespace ougge::game {
|
|
||||||
|
|
||||||
class GameObject;
|
|
||||||
|
|
||||||
struct Transform {
|
|
||||||
Vec2 scale = { 1, 1 };
|
|
||||||
Vec2 position = { 0, 0 };
|
|
||||||
angle_t rotation = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& s, Transform& t);
|
|
||||||
|
|
||||||
|
|
||||||
class GameObject {
|
|
||||||
Mono::ObjectHandle object_handle;
|
|
||||||
GameObject* parent;
|
|
||||||
Transform transform;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/// @warning Do not use this to create objects.
|
|
||||||
/// This constructor creates null values for GameObject arrays
|
|
||||||
/// GameObject* array = new GameObject[10];
|
|
||||||
/// array[0] = GameObject(initialized_mono_object_ptr)
|
|
||||||
GameObject() = default;
|
|
||||||
GameObject(Mono::Object managed_obj);
|
|
||||||
GameObject(const GameObject& o) = delete;
|
|
||||||
GameObject(GameObject&& o);
|
|
||||||
|
|
||||||
GameObject& operator=(GameObject&& o);
|
|
||||||
|
|
||||||
inline Mono::ObjectHandle& getObjectHandle() { return object_handle; }
|
|
||||||
inline GameObject* getParent() { return parent; }
|
|
||||||
inline void setParent(GameObject* p) { parent = p; }
|
|
||||||
inline Transform& getTransform() { return transform; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,130 +0,0 @@
|
|||||||
#include "GameObjectPool.hpp"
|
|
||||||
#include <bit>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace ougge::game {
|
|
||||||
|
|
||||||
GameObjectPool::GameObjectPool(u32 size)
|
|
||||||
{
|
|
||||||
useful_assert(size % 64 == 0, "size of GameObjectPool must be a multiple of 64");
|
|
||||||
this->size = size;
|
|
||||||
first_unused_index = 0;
|
|
||||||
buffer = new GameObject[size];
|
|
||||||
used_indices = new u64[size/64];
|
|
||||||
// std::memset(buffer, 0, size*sizeof(GameObject));
|
|
||||||
std::memset(used_indices, 0, size/8);
|
|
||||||
}
|
|
||||||
|
|
||||||
GameObjectPool::~GameObjectPool()
|
|
||||||
{
|
|
||||||
delete[] buffer;
|
|
||||||
delete[] used_indices;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GameObjectPool::isIndexUsed(u32 index)
|
|
||||||
{
|
|
||||||
return ( used_indices[index/64] & (u64(1)<<(index%64)) ) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GameObjectPool::getNearestUnusedIndex(u32 startIndex)
|
|
||||||
{
|
|
||||||
if(startIndex >= size)
|
|
||||||
return -1;
|
|
||||||
if(!isIndexUsed(startIndex))
|
|
||||||
return startIndex;
|
|
||||||
|
|
||||||
u32 i = startIndex/64;
|
|
||||||
// mark previous bits as used
|
|
||||||
u64 u = used_indices[i] | ( (u64(1)<<startIndex%64) -1 );
|
|
||||||
while(u == u64(-1)){
|
|
||||||
i++;
|
|
||||||
if(i == size/64)
|
|
||||||
return -1;
|
|
||||||
u = used_indices[i];
|
|
||||||
}
|
|
||||||
u32 bitpos = std::countr_one(u);
|
|
||||||
if(bitpos == 64)
|
|
||||||
return -1;
|
|
||||||
u32 index = i*64 + bitpos;
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 GameObjectPool::getNearestUsedIndex(u32 startIndex)
|
|
||||||
{
|
|
||||||
if(startIndex >= size)
|
|
||||||
return -1;
|
|
||||||
if(isIndexUsed(startIndex))
|
|
||||||
return startIndex;
|
|
||||||
|
|
||||||
u32 i = startIndex/64;
|
|
||||||
// mark previous bits as unused
|
|
||||||
u64 u = used_indices[i] & !( (u64(1)<<startIndex%64) -1 );
|
|
||||||
while(u == 0){
|
|
||||||
i++;
|
|
||||||
if(i == size/64)
|
|
||||||
return -1;
|
|
||||||
u = used_indices[i];
|
|
||||||
}
|
|
||||||
u32 bitpos = std::countr_zero(u);
|
|
||||||
if(bitpos == 64)
|
|
||||||
return -1;
|
|
||||||
u32 index = i*64 + bitpos;
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameObject& GameObjectPool::get(u32 index)
|
|
||||||
{
|
|
||||||
if(index >= size)
|
|
||||||
throw UsefulException(ougge_format("index %i is out of size %i", index, size));
|
|
||||||
if(!isIndexUsed(index))
|
|
||||||
throw UsefulException(ougge_format("there is no object at index %i", index));
|
|
||||||
return buffer[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<u32, GameObject&> GameObjectPool::emplace(GameObject&& new_obj)
|
|
||||||
{
|
|
||||||
u32 i = first_unused_index;
|
|
||||||
if(i == u32(-1))
|
|
||||||
throw UsefulException("can't put new GameObject to GameObjectPool because it's full");
|
|
||||||
|
|
||||||
buffer[i] = std::move(new_obj);
|
|
||||||
GameObject& r = buffer[i];
|
|
||||||
used_indices[i/64] |= u64(1)<<(i%64); // mark index bit as used
|
|
||||||
first_unused_index = getNearestUnusedIndex(i+1);
|
|
||||||
return std::pair<u32, GameObject&>(i, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GameObjectPool::erase(u32 index)
|
|
||||||
{
|
|
||||||
if(index >= size)
|
|
||||||
throw UsefulException(ougge_format("index %i is out of size %i", index, size));
|
|
||||||
if(!isIndexUsed(index))
|
|
||||||
throw UsefulException(ougge_format("there is no object at index %i", index));
|
|
||||||
|
|
||||||
buffer[index] = GameObject();
|
|
||||||
used_indices[index/64] &= ~(u64(1)<<(index%64)); // mark index bit as unused
|
|
||||||
if(index < first_unused_index)
|
|
||||||
first_unused_index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameObjectPool::iterator::iterator(GameObjectPool* pool, u32 index)
|
|
||||||
: pool(pool), index(index)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<u32, GameObject&> GameObjectPool::iterator::operator*()
|
|
||||||
{
|
|
||||||
if(index >= pool->size)
|
|
||||||
throw UsefulException("can't get value of end() iterator");
|
|
||||||
|
|
||||||
GameObject& r = pool->buffer[index];
|
|
||||||
return std::pair<u32, GameObject&>(index, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
GameObjectPool::iterator& GameObjectPool::iterator::operator++()
|
|
||||||
{
|
|
||||||
index = pool->getNearestUsedIndex(index+1);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
#include "GameObject.hpp"
|
|
||||||
|
|
||||||
namespace ougge::game {
|
|
||||||
|
|
||||||
/*
|
|
||||||
Fixed array that stores deleted elements indices as bits in array of u64.
|
|
||||||
Fast emplace, erase and lookup.
|
|
||||||
|
|
||||||
------------------------[construct]------------------------
|
|
||||||
operation 'GameObjectPool::GameObjectPool()' took 1.0549 ms
|
|
||||||
operation 'other_collections_construct' took 0.0133 ms
|
|
||||||
-------------------------[emplace]-------------------------
|
|
||||||
operation 'GameObjectPool::emplace' took 8.0557 ms
|
|
||||||
operation 'vector::emplace_back' took 11.3735 ms
|
|
||||||
operation 'set::emplace' took 80.5633 ms
|
|
||||||
operation 'list::emplace_front' took 18.1442 ms
|
|
||||||
operation 'forward_list::emplace_front' took 11.5467 ms
|
|
||||||
--------------------------[erase]--------------------------
|
|
||||||
operation 'GameObjectPool::erase' took 0.2745 ms
|
|
||||||
operation 'vector::erase' took 15790.6 ms
|
|
||||||
operation 'set::erase' took 1.2697 ms
|
|
||||||
operation 'list::erase_after' took 0.93 ms
|
|
||||||
operation 'forward_list::erase_after' took 1.1127 ms
|
|
||||||
-------------------------[iterate]-------------------------
|
|
||||||
operation 'GameObjectPool::iterate' took 1.1166 ms
|
|
||||||
operation 'vector::iterate' took 0.8883 ms
|
|
||||||
operation 'set::iterate' took 2.8011 ms
|
|
||||||
operation 'list::iterate' took 2.0766 ms
|
|
||||||
operation 'forward_list::iterate' took 2.0823 ms
|
|
||||||
*/
|
|
||||||
|
|
||||||
class GameObjectPool {
|
|
||||||
GameObject* buffer;
|
|
||||||
u64* used_indices;
|
|
||||||
u32 size;
|
|
||||||
u32 first_unused_index;
|
|
||||||
|
|
||||||
bool isIndexUsed(u32 index);
|
|
||||||
u32 getNearestUnusedIndex(u32 startIndex);
|
|
||||||
u32 getNearestUsedIndex(u32 startIndex);
|
|
||||||
public:
|
|
||||||
|
|
||||||
///@param size must be a multiple of 64
|
|
||||||
GameObjectPool(u32 size);
|
|
||||||
~GameObjectPool();
|
|
||||||
GameObject& get(u32 index);
|
|
||||||
std::pair<u32, GameObject&> emplace(GameObject&& new_obj);
|
|
||||||
void erase(u32 index);
|
|
||||||
|
|
||||||
#pragma region iterator class
|
|
||||||
class iterator {
|
|
||||||
GameObjectPool* pool;
|
|
||||||
u32 index = 0;
|
|
||||||
|
|
||||||
public:
|
|
||||||
iterator(GameObjectPool* pool, u32 index);
|
|
||||||
std::pair<u32, GameObject&> operator*();
|
|
||||||
iterator& operator++();
|
|
||||||
inline bool operator!=(const iterator& o) const { return index != o.index; };
|
|
||||||
inline bool operator==(const iterator& o) const { return index == o.index; };
|
|
||||||
};
|
|
||||||
#pragma endregion
|
|
||||||
|
|
||||||
inline iterator begin() { return iterator(this, 0); }
|
|
||||||
inline iterator end() { return iterator(this, -1); }
|
|
||||||
|
|
||||||
friend class iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
#include "mono.hpp"
|
|
||||||
|
|
||||||
namespace Mono {
|
|
||||||
|
|
||||||
Assembly::Assembly(MonoAssembly *ptr)
|
|
||||||
: ptr(ptr), image(mono_assembly_get_image(ptr))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoClass* Assembly::getClass(const std::string &name_space, const std::string &name){
|
|
||||||
auto c = mono_class_from_name(image, name_space.c_str(), name.c_str());
|
|
||||||
if(!c)
|
|
||||||
throw UsefulException(ougge_format("can't get class '%s.%s'", name_space.c_str(), name.c_str()));
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
#include "mono.hpp"
|
|
||||||
#include <mono/metadata/appdomain.h>
|
|
||||||
|
|
||||||
namespace Mono {
|
|
||||||
|
|
||||||
template <> MonoClass* getClass<SByte>(){ return mono_get_sbyte_class(); }
|
|
||||||
template <> MonoClass* getClass<Byte>(){ return mono_get_byte_class(); }
|
|
||||||
template <> MonoClass* getClass<Short>(){ return mono_get_int16_class(); }
|
|
||||||
template <> MonoClass* getClass<UShort>(){ return mono_get_uint16_class(); }
|
|
||||||
template <> MonoClass* getClass<Int>(){ return mono_get_int32_class(); }
|
|
||||||
template <> MonoClass* getClass<UInt>(){ return mono_get_uint32_class(); }
|
|
||||||
template <> MonoClass* getClass<Long>(){ return mono_get_int64_class(); }
|
|
||||||
template <> MonoClass* getClass<ULong>(){ return mono_get_uint64_class(); }
|
|
||||||
template <> MonoClass* getClass<Float>(){ return mono_get_single_class(); }
|
|
||||||
template <> MonoClass* getClass<Double>(){ return mono_get_double_class(); }
|
|
||||||
template <> MonoClass* getClass<Bool>(){ return mono_get_boolean_class(); }
|
|
||||||
template <> MonoClass* getClass<Char>(){ return mono_get_char_class(); }
|
|
||||||
template <> MonoClass* getClass<String>(){ return mono_get_string_class(); }
|
|
||||||
template <> MonoClass* getClass<Object>(){ return mono_get_object_class(); }
|
|
||||||
template <> MonoClass* getClass<Void>(){ return mono_get_void_class(); }
|
|
||||||
|
|
||||||
|
|
||||||
void getMethodSignatureTypes(MonoMethod* mono_method,
|
|
||||||
MonoType** return_type,
|
|
||||||
std::vector<MonoType*>& argument_types)
|
|
||||||
{
|
|
||||||
auto signature = mono_method_signature(mono_method);
|
|
||||||
void* iter = nullptr;
|
|
||||||
*return_type = mono_signature_get_return_type(signature);
|
|
||||||
MonoType* pt = nullptr;
|
|
||||||
while( (pt = mono_signature_get_params(signature, &iter)) ){
|
|
||||||
argument_types.push_back(pt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MonoMethod* tryGetMonoMethod(MonoClass* target_class, const std::string& name,
|
|
||||||
MonoClass* return_class, MonoClass* arg_classes[], size_t arg_classes_size)
|
|
||||||
{
|
|
||||||
if(target_class == nullptr)
|
|
||||||
throw UsefulException("target_class is nullptr");
|
|
||||||
|
|
||||||
// iterate each method
|
|
||||||
void* iter = nullptr;
|
|
||||||
MonoMethod* m = nullptr;
|
|
||||||
std::vector<MonoType*> argument_types;
|
|
||||||
while( (m = mono_class_get_methods(target_class, &iter)) ){
|
|
||||||
// compare name
|
|
||||||
std::string m_name = mono_method_get_name(m);
|
|
||||||
if(m_name != name)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
argument_types.clear();
|
|
||||||
MonoType* return_type = nullptr;
|
|
||||||
getMethodSignatureTypes(m, &return_type, argument_types);
|
|
||||||
// compare argument count
|
|
||||||
if(argument_types.size() != arg_classes_size)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// compare return type
|
|
||||||
if(!mono_metadata_type_equal(return_type, mono_class_get_type(return_class)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// compare argument types
|
|
||||||
bool argument_types_mismatch = false;
|
|
||||||
for(size_t i = 0; i < arg_classes_size; i++){
|
|
||||||
if(!mono_metadata_type_equal(argument_types[i], mono_class_get_type(arg_classes[i]))){
|
|
||||||
argument_types_mismatch = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(argument_types_mismatch)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// passed all tests successfully
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return m;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,187 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../common/std.hpp"
|
|
||||||
#include "../common/UsefulException.hpp"
|
|
||||||
#include "../common/ougge_format.hpp"
|
|
||||||
#include <vector>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <mono/metadata/class.h>
|
|
||||||
#include <mono/metadata/assembly.h>
|
|
||||||
#include <mono/metadata/object.h>
|
|
||||||
|
|
||||||
namespace Mono {
|
|
||||||
|
|
||||||
typedef i8 SByte;
|
|
||||||
typedef u8 Byte;
|
|
||||||
typedef i16 Short;
|
|
||||||
typedef u16 UShort;
|
|
||||||
typedef i32 Int;
|
|
||||||
typedef u32 UInt;
|
|
||||||
typedef i64 Long;
|
|
||||||
typedef u64 ULong;
|
|
||||||
typedef f32 Float;
|
|
||||||
typedef f64 Double;
|
|
||||||
typedef union { mono_bool wide_bool; } Bool; //USAGE: Bool t = {true};
|
|
||||||
typedef char16_t Char;
|
|
||||||
typedef MonoString* String;
|
|
||||||
/// @warning MonoObject can be moved in memory by GC in any time and raw pointer will be invalid.
|
|
||||||
/// Use ObjectHandle where it is possible.
|
|
||||||
typedef MonoObject* Object;
|
|
||||||
typedef void Void;
|
|
||||||
|
|
||||||
|
|
||||||
template<typename PrimitiveT>
|
|
||||||
MonoClass* getClass();
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void* valueToVoidPtr(T& v){ return &v; }
|
|
||||||
template<>
|
|
||||||
inline void* valueToVoidPtr<Object>(Object& v){ return v; }
|
|
||||||
template<>
|
|
||||||
inline void* valueToVoidPtr<String>(String& v){ return v; }
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T valueFromMonoObject(MonoObject* o){
|
|
||||||
void* result_value_ptr = mono_object_unbox(o);
|
|
||||||
if(result_value_ptr == nullptr)
|
|
||||||
throw UsefulException("can't unbox method value");
|
|
||||||
return *((T*)result_value_ptr);
|
|
||||||
}
|
|
||||||
template<>
|
|
||||||
inline Object valueFromMonoObject<Object>(MonoObject* o){ return o; }
|
|
||||||
template<>
|
|
||||||
inline String valueFromMonoObject<String>(MonoObject* o){ return (String)((void*)o); }
|
|
||||||
|
|
||||||
void getMethodSignatureTypes(MonoMethod* mono_method,
|
|
||||||
MonoType** return_type,
|
|
||||||
std::vector<MonoType*>& argument_types);
|
|
||||||
|
|
||||||
/// searches for method `name` in `target_class` with return type `return_class` and argument types `arg_classes`
|
|
||||||
/// @return found method or nullptr
|
|
||||||
MonoMethod* tryGetMonoMethod(MonoClass* target_class, const std::string& name,
|
|
||||||
MonoClass* return_class, MonoClass* arg_classes[], size_t arg_classes_size);
|
|
||||||
|
|
||||||
|
|
||||||
template<typename SignatureT> class Method;
|
|
||||||
template<typename ReturnT, typename... ArgTypes>
|
|
||||||
class Method<ReturnT(ArgTypes...)>
|
|
||||||
{
|
|
||||||
MonoMethod* method_ptr;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Method() { method_ptr = nullptr; }
|
|
||||||
|
|
||||||
/// all types must implement getClass<T>()
|
|
||||||
Method(MonoClass* target_class, const std::string& name){
|
|
||||||
static MonoClass* arg_classes[] { getClass<ArgTypes>()... };
|
|
||||||
static MonoClass* return_class { getClass<ReturnT>() };
|
|
||||||
method_ptr = tryGetMonoMethod(target_class, name, return_class, arg_classes, sizeof...(ArgTypes));
|
|
||||||
if(method_ptr == nullptr){
|
|
||||||
throw UsefulException(ougge_format("can't get method '%s' from class '%s'",
|
|
||||||
name.c_str(), mono_class_get_name(target_class)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReturnT not is void
|
|
||||||
template<typename RT = ReturnT>
|
|
||||||
std::enable_if_t<!std::is_void<RT>::value, RT> operator()(MonoObject* class_instance, ArgTypes... args) const {
|
|
||||||
if(method_ptr == nullptr)
|
|
||||||
throw UsefulException("method_ptr is null");
|
|
||||||
|
|
||||||
void* arg_array[] = { valueToVoidPtr(args)..., nullptr };
|
|
||||||
MonoObject* ex = nullptr;
|
|
||||||
MonoObject* result = mono_runtime_invoke(method_ptr, class_instance, arg_array, &ex);
|
|
||||||
if(ex){
|
|
||||||
//TODO: call mono_trace_set_printerr_handler from mono/mono/utils/mono-logger.h
|
|
||||||
mono_print_unhandled_exception(ex);
|
|
||||||
throw UsefulException("Some C# exception occured");
|
|
||||||
}
|
|
||||||
return valueFromMonoObject<ReturnT>(result);
|
|
||||||
};
|
|
||||||
|
|
||||||
// ReturnT is void
|
|
||||||
template<typename RT = ReturnT>
|
|
||||||
std::enable_if_t<std::is_void<RT>::value, RT> operator()(MonoObject* class_instance, ArgTypes... args) const {
|
|
||||||
if(method_ptr == nullptr)
|
|
||||||
throw UsefulException("method_ptr is null");
|
|
||||||
|
|
||||||
void* arg_array[] = { valueToVoidPtr(args)..., nullptr };
|
|
||||||
MonoObject* ex = nullptr;
|
|
||||||
mono_runtime_invoke(method_ptr, class_instance, arg_array, &ex);
|
|
||||||
if(ex){
|
|
||||||
//TODO: call mono_trace_set_printerr_handler from mono/mono/utils/mono-logger.h
|
|
||||||
mono_print_unhandled_exception(ex);
|
|
||||||
throw UsefulException("Some C# exception occured");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Assembly {
|
|
||||||
MonoAssembly* ptr;
|
|
||||||
MonoImage* image;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Assembly(MonoAssembly* ptr);
|
|
||||||
Assembly(const Assembly&) = delete;
|
|
||||||
|
|
||||||
MonoClass* getClass(const std::string& name_space, const std::string& name);
|
|
||||||
MonoAssembly* getMonoAssembly() const { return ptr; }
|
|
||||||
MonoImage* getMonoImage() const { return image; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
///LINUX: `config.xml`, `mscorelib.dll`, `libmono-native.so` in `mono-libs` directory
|
|
||||||
///
|
|
||||||
///WINDOWS: `config.xml`, `mscorelib.dll` in `mono-libs` directory
|
|
||||||
class RuntimeJIT {
|
|
||||||
MonoDomain* domain;
|
|
||||||
public:
|
|
||||||
RuntimeJIT(const std::string& domain_name = "OuggeDomain");
|
|
||||||
RuntimeJIT(const RuntimeJIT&) = delete;
|
|
||||||
~RuntimeJIT();
|
|
||||||
|
|
||||||
inline MonoDomain* getDomain() { return domain; }
|
|
||||||
std::shared_ptr<Assembly> loadAssembly(const std::string& name);
|
|
||||||
|
|
||||||
inline Object createObject(MonoClass* klass) { return mono_object_new(domain, klass); }
|
|
||||||
inline String createString(const std::string& v) { return mono_string_new_len(domain, v.c_str(), v.size()); }
|
|
||||||
inline String createString(const char* v) { return mono_string_new(domain, v); }
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief ObjectHandle can be used to store reliable reference to MonoObject.
|
|
||||||
/// MonoObject can be moved in memory by GC in any time and raw pointer will be invalid.
|
|
||||||
struct ObjectHandle {
|
|
||||||
u32 gc_handle;
|
|
||||||
|
|
||||||
inline ObjectHandle() : gc_handle(0) {}
|
|
||||||
|
|
||||||
inline ObjectHandle(Object obj) {
|
|
||||||
gc_handle = mono_gchandle_new(obj, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// implicitly create new ObjectHandle instead
|
|
||||||
inline ObjectHandle(const ObjectHandle& o) = delete;
|
|
||||||
|
|
||||||
inline ObjectHandle(ObjectHandle&& o) {
|
|
||||||
gc_handle = o.gc_handle;
|
|
||||||
o.gc_handle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ObjectHandle& operator=(ObjectHandle&& o) {
|
|
||||||
gc_handle = o.gc_handle;
|
|
||||||
o.gc_handle = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline ~ObjectHandle() {
|
|
||||||
if(gc_handle)
|
|
||||||
mono_gchandle_free(gc_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Object getObject() const {
|
|
||||||
return mono_gchandle_get_target(gc_handle);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,30 +0,0 @@
|
|||||||
#include "mono.hpp"
|
|
||||||
#include <mono/jit/jit.h>
|
|
||||||
#include <mono/metadata/mono-config.h>
|
|
||||||
#include <mono/metadata/appdomain.h>
|
|
||||||
|
|
||||||
namespace Mono {
|
|
||||||
|
|
||||||
RuntimeJIT::RuntimeJIT(const std::string& domain_name){
|
|
||||||
mono_set_dirs("mono-libs", "mono-libs");
|
|
||||||
mono_set_assemblies_path("mono-libs");
|
|
||||||
mono_config_parse("mono-libs/config.xml");
|
|
||||||
|
|
||||||
domain = mono_jit_init(domain_name.c_str());
|
|
||||||
if(!domain)
|
|
||||||
throw UsefulException("can't initialize mono domain");
|
|
||||||
}
|
|
||||||
|
|
||||||
RuntimeJIT::~RuntimeJIT(){
|
|
||||||
// TODO: fix segfault on cleanup
|
|
||||||
// mono_jit_cleanup(domain);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Assembly> RuntimeJIT::loadAssembly(const std::string &name){
|
|
||||||
MonoAssembly* ptr = mono_domain_assembly_open(domain, name.c_str());
|
|
||||||
if(!ptr)
|
|
||||||
throw UsefulException(ougge_format("can't load assembly '%s'", name.c_str()));
|
|
||||||
return std::make_shared<Assembly>(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,40 +0,0 @@
|
|||||||
#include "MemoryStream.hpp"
|
|
||||||
|
|
||||||
class MemoryStreamBuf : public std::streambuf {
|
|
||||||
public:
|
|
||||||
MemoryStreamBuf(void* p, const std::size_t n);
|
|
||||||
|
|
||||||
virtual std::istream::pos_type seekoff(
|
|
||||||
std::istream::off_type off,
|
|
||||||
std::ios_base::seekdir dir,
|
|
||||||
std::ios_base::openmode which);
|
|
||||||
};
|
|
||||||
|
|
||||||
MemoryStreamBuf::MemoryStreamBuf(void* _p, const std::size_t n){
|
|
||||||
char* p=(char*)_p;
|
|
||||||
setg(p, p, p + n);
|
|
||||||
setp(p, p + n);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::istream::pos_type MemoryStreamBuf::seekoff(
|
|
||||||
std::istream::off_type off,
|
|
||||||
std::ios_base::seekdir dir,
|
|
||||||
std::ios_base::openmode which)
|
|
||||||
{
|
|
||||||
if (dir == std::ios_base::cur)
|
|
||||||
gbump(off);
|
|
||||||
else if (dir == std::ios_base::end)
|
|
||||||
setg(eback(), egptr() + off, egptr());
|
|
||||||
else if (dir == std::ios_base::beg)
|
|
||||||
setg(eback(), eback() + off, egptr());
|
|
||||||
return gptr() - eback();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
MemoryStreamRead::MemoryStreamRead(const void* p, const std::size_t n)
|
|
||||||
: std::istream(new MemoryStreamBuf((void*)p, n))
|
|
||||||
{}
|
|
||||||
|
|
||||||
MemoryStreamRead::~MemoryStreamRead(){
|
|
||||||
delete rdbuf();
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
#include <iostream>
|
|
||||||
|
|
||||||
class MemoryStreamRead : public std::istream {
|
|
||||||
public:
|
|
||||||
MemoryStreamRead(const void* p, const std::size_t n);
|
|
||||||
|
|
||||||
virtual ~MemoryStreamRead();
|
|
||||||
};
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////
|
|
||||||
// This file was generated by resource_embedder //
|
|
||||||
// https://timerix.ddns.net:3322/Timerix/resource_embedder //
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
// USAGE: //
|
|
||||||
// Put it in a SOURCE file to define variables //
|
|
||||||
// #define EMBEDDED_RESOURCE_DEFINITION //
|
|
||||||
// #define EMBEDDED_RESOURCE_POSTFIX your_postfix //
|
|
||||||
// #include "../../src/Resources/embedded_resources.h" //
|
|
||||||
// //
|
|
||||||
// Put it in a HEADER file to declare external variables //
|
|
||||||
// #define EMBEDDED_RESOURCE_POSTFIX your_postfix //
|
|
||||||
// #include "../../src/Resources/embedded_resources.h" //
|
|
||||||
// //
|
|
||||||
// Then you can access embedded files through //
|
|
||||||
// EmbeddedResource_table_your_postfix. You can get table //
|
|
||||||
// content by index and put it into a hashtable or a map. //
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#if __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char* path;
|
|
||||||
const char* data;
|
|
||||||
size_t size;
|
|
||||||
} EmbeddedResource;
|
|
||||||
|
|
||||||
#define RSCAT(A,B,C...) A##B##C
|
|
||||||
#ifdef EMBEDDED_RESOURCE_POSTFIX
|
|
||||||
#define _EmbeddedResource_table(P) \
|
|
||||||
RSCAT(EmbeddedResource_table_, P)
|
|
||||||
#define _EmbeddedResource_table_count(P) \
|
|
||||||
RSCAT(EmbeddedResource_table_, P, _count)
|
|
||||||
#else
|
|
||||||
#define _EmbeddedResource_table(P) \
|
|
||||||
EmbeddedResource_table
|
|
||||||
#define _EmbeddedResource_table_count(P) \
|
|
||||||
EmbeddedResource_table_count
|
|
||||||
#endif
|
|
||||||
extern const EmbeddedResource _EmbeddedResource_table(EMBEDDED_RESOURCE_POSTFIX)[];
|
|
||||||
extern const int _EmbeddedResource_table_count(EMBEDDED_RESOURCE_POSTFIX);
|
|
||||||
|
|
||||||
#ifdef EMBEDDED_RESOURCE_DEFINITION
|
|
||||||
const EmbeddedResource _EmbeddedResource_table(EMBEDDED_RESOURCE_POSTFIX)[]={
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const int _EmbeddedResource_table_count(EMBEDDED_RESOURCE_POSTFIX)=0;
|
|
||||||
#endif // EMBEDDED_RESOURCE_DEFINITION
|
|
||||||
|
|
||||||
#undef _EmbeddedResource_table
|
|
||||||
#undef _EmbeddedResource_table_count
|
|
||||||
#undef EMBEDDED_RESOURCE_POSTFIX
|
|
||||||
#undef RSCAT
|
|
||||||
|
|
||||||
#if __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
#include "fonts.hpp"
|
|
||||||
|
|
||||||
namespace ougge::resources {
|
|
||||||
|
|
||||||
// select all glyphs from font
|
|
||||||
static const ImWchar glyph_ranges[] = {
|
|
||||||
0x0020, 0xFFFF, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
ImFont* ImFont_LoadFromFile(const std::string& file_path, f32 font_size, f32 dpi){
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
font_size *= dpi;
|
|
||||||
return io.Fonts->AddFontFromFileTTF(file_path.c_str(), font_size, nullptr, glyph_ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImFont* ImFont_LoadFromResource(ResourceFactory* res, f32 font_size, f32 dpi){
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
font_size *= dpi;
|
|
||||||
ImFontConfig font_cfg = ImFontConfig();
|
|
||||||
std::sprintf(font_cfg.Name, "%s %ipx", res->path.c_str(), (i32)font_size);
|
|
||||||
|
|
||||||
char* font_data = new char[res->size];
|
|
||||||
res->openStream()->read(font_data, res->size);
|
|
||||||
|
|
||||||
return io.Fonts->AddFontFromMemoryTTF((void*)(font_data), res->size,
|
|
||||||
font_size, &font_cfg, glyph_ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <imgui.h>
|
|
||||||
#include "../common/std.hpp"
|
|
||||||
#include "resources.hpp"
|
|
||||||
|
|
||||||
namespace ougge::resources {
|
|
||||||
|
|
||||||
ImFont* ImFont_LoadFromFile(const std::string& file_path, f32 font_size, f32 dpi);
|
|
||||||
|
|
||||||
ImFont* ImFont_LoadFromResource(ResourceFactory* res, f32 font_size, f32 dpi);
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user