Skip to content

Commit

Permalink
Merged to master.
Browse files Browse the repository at this point in the history
  • Loading branch information
anirul committed Apr 5, 2024
2 parents c44e935 + 2c66763 commit 717344c
Show file tree
Hide file tree
Showing 49 changed files with 945 additions and 86 deletions.
77 changes: 77 additions & 0 deletions .github/workflows/cmake-multi-platform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# build the Frame code on linux and run the test
# copy from https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
name: CMake on multiple platforms

on:
push:

jobs:
build:
runs-on: ${{ matrix.os }}

strategy:
# Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
fail-fast: true
# Matrix not used, missing windows knowledge to do build it
# clang compiler not working with ubuntu because issue with std lib and clang (tested with clang15)
matrix:
os: [ubuntu-latest]
build_type: [Release]
c_compiler: [gcc]
cpp_compiler: [g++]
triplet: [x64-linux-release]
include:
- os: ubuntu-latest
c_compiler: gcc
cpp_compiler: g++
triplet: x64-linux-release

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
lfs: true
submodules: true
- name: Set reusable strings
# Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file.
id: strings
shell: bash
run: |
echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
- name: apt install
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
sudo apt update
sudo apt install -y libxmu-dev libxi-dev libgl-dev libglx-dev libgles-dev \
build-essential libx11-xcb-dev libegl1-mesa-dev libopengl-dev \
libxkbcommon-dev libwayland-dev libxrandr-dev mesa-vulkan-drivers libglu1-mesa-dev libdrm-dev libegl-dev libglm-dev
# the dependency list is too big but at least it works
# https://packages.ubuntu.com/search
- name: vcpkg build
id: vcpkg
uses: johnwason/vcpkg-action@v6 #cache build so improve the build time a lot
with:
manifest-dir: ${{ github.workspace }} # Set to directory containing vcpkg.json
triplet: "${{ matrix.triplet }}"
token: ${{ github.token }}
github-binarycache: true
cache-key: "${{ matrix.triplet }}" # TODO must use sha1 of vcpkg.json and triplet
- name: Configure CMake
run: >
cmake -B ${{ steps.strings.outputs.build-output-dir }}
-DBUILD_SKIP_CLIENT=ON
${{ steps.vcpkg.outputs.vcpkg-cmake-config }}
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-S ${{ github.workspace }} ;
- name: Build
# Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator).
run: >
CC="${{ matrix.c_compiler }}" CXX="${{ matrix.cpp_compiler }}" cmake
--build ${{ steps.strings.outputs.build-output-dir }} --verbose -j 4
- name: Show files after
run: ls -ltrR ${{ github.workspace }}
- name: Run tests
working-directory: ${{ steps.strings.outputs.build-output-dir }}
run: xvfb-run ctest --build-config ${{ matrix.build_type }}
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ jobs:
run: |
git clone https://github.com/microsoft/vcpkg.git
cd vcpkg
git checkout tags/2024.02.14
./bootstrap-vcpkg.bat
./vcpkg integrate install
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# C++ standard version.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Adding subfolder property.
Expand Down
1 change: 1 addition & 0 deletions examples/02-scene_simple/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
add_executable(02_SceneSimple
WIN32
main.cpp
modal_info.h
${CMAKE_CURRENT_SOURCE_DIR}/../../asset/json/scene_simple.json
)

Expand Down
9 changes: 8 additions & 1 deletion examples/02-scene_simple/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
#include "frame/file/file_system.h"
#include "frame/file/image_stb.h"
#include "frame/gui/draw_gui_factory.h"
#include "frame/gui/window_logger.h"
#include "frame/gui/window_resolution.h"
#include "frame/window_factory.h"
#include "modal_info.h"

// From: https://sourceforge.net/p/predef/wiki/OperatingSystems/
#if defined(_WIN32) || defined(_WIN64)
Expand All @@ -39,11 +41,16 @@ try
frame::RenderingAPIEnum::OPENGL,
size);
auto& device = win->GetDevice();
auto gui_window = frame::gui::CreateDrawGui(*win.get());
auto gui_window = frame::gui::CreateDrawGui(*win.get(), {}, 20.0f);
auto gui_resolution = std::make_unique<frame::gui::WindowResolution>(
"Resolution", size, win->GetDesktopSize(), win->GetPixelPerInch());
ptr_window_resolution = gui_resolution.get();
gui_window->AddWindow(std::move(gui_resolution));
gui_window->AddWindow(std::make_unique<frame::gui::WindowLogger>("Logger"));
// Set the main window in full.
// gui_window->SetVisible(false);
gui_window->AddModalWindow(
std::make_unique<ModalInfo>("Info", "This is a test modal window."));
win->GetDevice().AddPlugin(std::move(gui_window));
frame::common::Application app(std::move(win));
do
Expand Down
39 changes: 39 additions & 0 deletions examples/02-scene_simple/modal_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include "frame/gui/gui_window_interface.h"
#include <imgui.h>

class ModalInfo : public frame::gui::GuiWindowInterface
{
public:
ModalInfo(const std::string& name, const std::string& text) :
name_(name), text_(text)
{
}
bool DrawCallback() override
{
ImGui::TextUnformatted(text_.c_str());
if (ImGui::Button("Ok"))
{
end_ = true;
}
return true;
}
bool End() const override
{
return end_;
}
std::string GetName() const override
{
return name_;
}
void SetName(const std::string& name) override
{
name_ = name;
}

private:
bool end_ = false;
std::string name_;
std::string text_;
};
2 changes: 1 addition & 1 deletion examples/04-point_cloud/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ try
frame::gui::WindowResolution* ptr_window_resolution = nullptr;
frame::gui::WindowCamera* ptr_window_camera = nullptr;
frame::gui::WindowCubemap* ptr_window_cubemap = nullptr;
auto gui_window = frame::gui::CreateDrawGui(*win.get());
auto gui_window = frame::gui::CreateDrawGui(*win.get(), {}, 20.0f);
{
auto gui_resolution = std::make_unique<frame::gui::WindowResolution>(
"Resolution", size, win->GetDesktopSize(), win->GetPixelPerInch());
Expand Down
1 change: 1 addition & 0 deletions include/frame/buffer_interface.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <vector>
#include <cstdint>

#include "frame/name_interface.h"

Expand Down
1 change: 1 addition & 0 deletions include/frame/camera.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <array>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/glm.hpp>

namespace frame
Expand Down
9 changes: 7 additions & 2 deletions include/frame/common/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ class Application
* @param window: The unique pointer to the window (should have been
* created prior).
*/
Application(std::unique_ptr<frame::WindowInterface>&& window);
Application(std::unique_ptr<frame::WindowInterface> window);
/**
* @brief Get the Window object.
* @return The window.
*/
frame::WindowInterface& GetWindow();
/**
* @brief Startup this will initialized the inner level of the window
* according to a path.
Expand All @@ -34,7 +39,7 @@ class Application
* @brief Same as previously but this use a level.
* @param level: A unique pointer to a level.
*/
void Startup(std::unique_ptr<frame::LevelInterface>&& level);
void Startup(std::unique_ptr<frame::LevelInterface> level);
/**
* @brief A helper function that call the inner resize of the window.
* @param size: The new size of the window.
Expand Down
6 changes: 5 additions & 1 deletion include/frame/gui/draw_gui_factory.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <memory>
#include <filesystem>

#include "frame/device_interface.h"
#include "frame/gui/draw_gui_interface.h"
Expand All @@ -9,6 +10,9 @@
namespace frame::gui
{

std::unique_ptr<DrawGuiInterface> CreateDrawGui(WindowInterface& window);
std::unique_ptr<DrawGuiInterface> CreateDrawGui(
WindowInterface& window,
const std::filesystem::path& font_path,
float font_size);

} // End namespace frame::gui.
54 changes: 38 additions & 16 deletions include/frame/gui/draw_gui_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,13 @@

#include <functional>

#include "frame/gui/gui_window_interface.h"
#include "frame/name_interface.h"
#include "frame/plugin_interface.h"

namespace frame::gui
{

/**
* @class GuiWindowInterface
* @brief Draw GUI Window interface.
*
* It has a name interface that will be used as a pointer to the window.
*/
struct GuiWindowInterface : public NameInterface
{
//! @brief Draw callback setting.
virtual bool DrawCallback() = 0;
//! @brief Is it the end of the gui?
virtual bool End() const = 0;
};

/**
* @class DrawGuiInterface
* @brief Interface for drawing GUI elements.
Expand All @@ -35,7 +22,30 @@ class DrawGuiInterface : public PluginInterface
* @brief Add sub window to the main window.
* @param callback: A window callback that can add buttons, etc.
*/
virtual void AddWindow(std::unique_ptr<GuiWindowInterface>&& callback) = 0;
virtual void AddWindow(std::unique_ptr<GuiWindowInterface> callback) = 0;
/**
* @brief Add a overlay window.
* @param position: The position of the window.
* @param callback: A window callback that can add buttons, etc.
*
* Overlay window are drawn on top of the main window and are not
* affected. Also note that they are only display when the main window
* is fullscreen.
*/
virtual void AddOverlayWindow(
glm::vec2 position,
glm::vec2 size,
std::unique_ptr<GuiWindowInterface> callback) = 0;
/**
* @brief Add a modal window.
* @param callback: A window callback that can add buttons, etc.
*
* If the callback return is 0 the callback stay and if it is other it is
* removed. This will trigger an internal boolean that will decide if the
* modal is active or not.
*/
virtual void AddModalWindow(
std::unique_ptr<GuiWindowInterface> callback) = 0;
/**
* @brief Get a specific window (associated with a name).
* @param name: The name of the window.
Expand All @@ -49,7 +59,7 @@ class DrawGuiInterface : public PluginInterface
virtual std::vector<std::string> GetWindowTitles() const = 0;
/**
* @brief Delete a sub window.
* @param name: the name of the window to be deleted.
* @param name: the name of the window or overlay to be deleted.
*/
virtual void DeleteWindow(const std::string& name) = 0;
/**
Expand All @@ -62,6 +72,18 @@ class DrawGuiInterface : public PluginInterface
* @return True if enable.
*/
virtual bool IsVisible() const = 0;
/**
* @brief Poll event.
* @param event: The event to be polled.
* @return True if the event is captured.
*/
virtual void SetKeyboardPassed(bool is_keyboard_passed) = 0;
/**
* @brief Poll event.
* @param event: The event to be polled.
* @return True if the event is captured.
*/
virtual bool IsKeyboardPassed() const = 0;
};

} // End namespace frame::gui.
66 changes: 66 additions & 0 deletions include/frame/gui/gui_logger_sink.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#pragma once

#include <mutex>
#include <spdlog/sinks/base_sink.h>
#include <string>

#include "frame/logger.h"

namespace frame::gui
{

/**
* @brief A sink for spdlog that stores log messages in a vector of strings.
*
* This sink is useful for testing and debugging, as it allows to check the
* log messages that have been generated by the application.
*
* The sink stores the log messages in a vector of strings, which can be
* accessed using the GetLogs() method. The logs are stored in the order they
* were generated, and can be cleared using the ClearLogs() method.
*
* The sink is thread safe, and can be used with multiple threads.
*/
class GuiLoggerSink : public spdlog::sinks::base_sink<std::mutex>
{
protected:
void sink_it_(const spdlog::details::log_msg& msg) override
{
// log_msg is a struct containing the log entry info like level,
// timestamp, thread id etc. msg.raw contains pre formatted log

// If needed (very likely but not mandatory), the sink formats the
// message before sending it to its final desination:
spdlog::memory_buf_t formatted;
spdlog::sinks::base_sink<std::mutex>::formatter_->format(
msg, formatted);
const auto time = std::chrono::current_zone()
->to_local(std::chrono::system_clock::now());
const auto current_milli{
duration_cast<std::chrono::milliseconds>(time.time_since_epoch())
.count() % 1000};
const auto time_p = std::format("{:%X}.{:03} ", time, current_milli);
std::string formatted_message(msg.payload.begin(), msg.payload.end());
logs.push_back({msg.level, std::move(time_p + formatted_message)});
}
void flush_() override
{
}

public:
/// @brief Get the logs that have been generated.
const std::vector<LogMessage>& GetLogs() const
{
return logs;
}
/// @brief Clear the logs that have been generated.
void ClearLogs()
{
logs.clear();
}

private:
std::vector<LogMessage> logs;
};

} // namespace frame::gui.
Loading

0 comments on commit 717344c

Please sign in to comment.