Skip to content

Commit

Permalink
Welcome winrt ! (JeanPhilippeKernel#402)
Browse files Browse the repository at this point in the history
* Welcome winrt !

* fixed file dialog logic impl
  • Loading branch information
JeanPhilippeKernel authored Nov 30, 2024
1 parent e6dd15d commit 1e5e35b
Show file tree
Hide file tree
Showing 14 changed files with 181 additions and 80 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ __externals/imgui/src/examples/example_glfw_vulkan/out/
__externals/SDL2
__externals/stb
__externals/spdlog
__externals/nuget

# Shader cache file folder
Resources/Shaders/Cache
Expand Down
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ set_property (GLOBAL PROPERTY USE_FOLDERS ON)
#
get_filename_component (ENLISTMENT_ROOT "." ABSOLUTE CACHE)
get_filename_component (EXTERNAL_DIR "${ENLISTMENT_ROOT}/__externals" ABSOLUTE CACHE)
get_filename_component (EXAMPLE_DIR "${ENLISTMENT_ROOT}/Examples" ABSOLUTE CACHE)
get_filename_component (EXTERNAL_NUGET_DIR "${ENLISTMENT_ROOT}/__externals/nuget" ABSOLUTE CACHE)

include(${ENLISTMENT_ROOT}/Scripts/CMake/NuGet.cmake)
include(${ENLISTMENT_ROOT}/Scripts/CMake/CppWinRT.cmake)
include(${ENLISTMENT_ROOT}/dependencies.cmake)


option (COPY_EXAMPLE_PROJECT "Copy example projects that show how to use Launcher" ON)
Expand Down
38 changes: 38 additions & 0 deletions Scripts/CMake/CppWinRT.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generates CppWinRT headers
#
# generate_winrt_headers(
# EXECUTABLE
# <path to cppwinrt.exe to use>
# INPUT
# <inputs>*
# OUTPUT
# <output path>
# [OPTIMIZE]
#
# Remarks:
#
function(generate_winrt_headers)
set(FLAG_ARGS OPTIMIZE)
set(ONE_VALUE_ARGS EXECUTABLE OUTPUT)
set(MULTI_VALUE_ARGS INPUT)

cmake_parse_arguments(CPPWINRT "${FLAG_ARGS}" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGV})

list(APPEND CPPWINRT_ARGUMENTS -output ${CPPWINRT_OUTPUT})

foreach(CPPWINRT_INPUT_ITEM ${CPPWINRT_INPUT})
list(APPEND CPPWINRT_ARGUMENTS -input ${CPPWINRT_INPUT_ITEM})
endforeach()

if(CPPWINRT_OPTIMIZE)
list(APPEND CPPWINRT_ARGUMENTS -optimize)
endif()

execute_process(
COMMAND "${CPPWINRT_EXECUTABLE}" ${CPPWINRT_ARGUMENTS}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND_ECHO STDOUT
OUTPUT_VARIABLE WINRT_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endfunction()
39 changes: 39 additions & 0 deletions Scripts/CMake/NuGet.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@

# Installs a NuGet package
#
# install_nuget_package(<nuget name> <nuget version> <path property>)
#
# The NuGet will be download during CMake generation.
#
function(install_nuget_package NUGET_PACKAGE_NAME NUGET_PACKAGE_VERSION NUGET_PATH_PROPERTY)
# NUGET_PACKAGE_NAME - The name of the NuGet package.
# NUGET_PACKAGE_VERSION - The version of the NuGet package.
find_program(NUGET_EXECUTABLE nuget REQUIRED)

if("${EXTERNAL_NUGET_DIR}" STREQUAL "")
set(EXTERNAL_NUGET_DIR "${CMAKE_BINARY_DIR}/__packages")
endif()

cmake_parse_arguments("NUGET" "" "SOURCE" "" ${ARGN})

if(NOT ("${NUGET_SOURCE}" STREQUAL ""))
message(STATUS "Nuget source for ${NUGET_PACKAGE_NAME}@${NUGET_PACKAGE_VERSION} is ${NUGET_SOURCE}")
set(NUGET_SOURCE_COMMAND -Source "${NUGET_SOURCE}")
endif()

# The NUGET_PACKAGE_ROOT is where NUGET_EXECUTABLE installed the package to.
set(NUGET_PACKAGE_ROOT "${EXTERNAL_NUGET_DIR}/${NUGET_PACKAGE_NAME}.${NUGET_PACKAGE_VERSION}")

if(NOT EXISTS "${NUGET_PACKAGE_ROOT}")
message(STATUS "nuget install ${NUGET_PACKAGE_NAME} -Version ${NUGET_PACKAGE_VERSION} -OutputDirectory ${EXTERNAL_NUGET_DIR}")
execute_process(
COMMAND ${NUGET_EXECUTABLE} install ${NUGET_PACKAGE_NAME} -Version ${NUGET_PACKAGE_VERSION} -OutputDirectory "${EXTERNAL_NUGET_DIR}" ${NUGET_SOURCE_COMMAND}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE NUGET_OUTPUT
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()

set(${NUGET_PATH_PROPERTY} "${NUGET_PACKAGE_ROOT}" PARENT_SCOPE)
endfunction()

function(restore_nuget_packages VS_SLN_OR_PROJ)
# VS_SLN_OR_PROJ - the Visual Studio .sln, .vcxproj or .csproj defining the nuget dependencies

Expand Down
31 changes: 20 additions & 11 deletions Tetragrama/Components/DockspaceUIComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#include <DockspaceUIComponent.h>
#include <Editor.h>
#include <Helpers/UIDispatcher.h>
#include <Helpers/WindowsHelper.h>
#include <Importers/AssimpImporter.h>
#include <MessageToken.h>
#include <Messengers/Messenger.h>
Expand Down Expand Up @@ -164,12 +163,18 @@ namespace Tetragrama::Components

if (ImGui::Button("...", ImVec2(50, 0)) && is_import_button_enabled)
{
Helpers::UIDispatcher::RunAsync([]() -> std::future<void> {
std::string filename = co_await Helpers::OpenFileDialogAsync();
if (!filename.empty())
Helpers::UIDispatcher::RunAsync([this]() -> std::future<void> {
if (auto layer = m_parent_layer.lock())
{
ZEngine::Helpers::secure_memset(s_asset_importer_input_buffer, 0, IM_ARRAYSIZE(s_asset_importer_input_buffer), IM_ARRAYSIZE(s_asset_importer_input_buffer));
ZEngine::Helpers::secure_memcpy(s_asset_importer_input_buffer, IM_ARRAYSIZE(s_asset_importer_input_buffer), filename.c_str(), filename.size());
auto window = layer->GetAttachedWindow();
std::vector<std::string_view> filters{".obj", ".gltf"};
std::string filename = co_await window->OpenFileDialogAsync(filters);

if (!filename.empty())
{
ZEngine::Helpers::secure_memset(s_asset_importer_input_buffer, 0, IM_ARRAYSIZE(s_asset_importer_input_buffer), IM_ARRAYSIZE(s_asset_importer_input_buffer));
ZEngine::Helpers::secure_memcpy(s_asset_importer_input_buffer, IM_ARRAYSIZE(s_asset_importer_input_buffer), filename.c_str(), filename.size());
}
}
});
}
Expand Down Expand Up @@ -551,13 +556,17 @@ namespace Tetragrama::Components

std::future<void> DockspaceUIComponent::OnOpenSceneAsync()
{
auto scene_filename = co_await Helpers::OpenFileDialogAsync();

if (!scene_filename.empty())
if (auto layer = m_parent_layer.lock())
{
m_editor_serializer->Deserialize(scene_filename);
auto window = layer->GetAttachedWindow();
std::vector<std::string_view> filters = {"."};
std::string scene_filename = co_await window->OpenFileDialogAsync(filters);

if (!scene_filename.empty())
{
m_editor_serializer->Deserialize(scene_filename);
}
}
ZENGINE_CORE_WARN("Editor stopped")
co_return;
}

Expand Down
46 changes: 46 additions & 0 deletions Tetragrama/EditorWindow.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
#include <pch.h>
#include <EditorWindow.h>
#include <ZEngine/Core/Coroutine.h>
#include <ZEngine/Engine.h>
#include <ZEngine/Event/EngineClosedEvent.h>
#include <ZEngine/Logging/LoggerDefinition.h>
#include <ZEngine/Windows/Inputs/KeyCode.h>

#ifdef _WIN32
#define GLFW_EXPOSE_NATIVE_WIN32

#include <ShObjIdl.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Storage.Pickers.h>
#include <winrt/Windows.Storage.h>

using namespace winrt;
using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Storage;
using namespace winrt::Windows::Storage::Pickers;

#endif
#include <GLFW/glfw3native.h>

Expand Down Expand Up @@ -359,6 +372,39 @@ namespace Tetragrama
m_swapchain->Present();
}

std::future<std::string> EditorWindow::OpenFileDialogAsync(std::span<std::string_view> type_filters)
{
std::string path{""};
#ifdef _WIN32

auto native_hwnd = glfwGetWin32Window(m_native_window);

FileOpenPicker file_picker;
file_picker.ViewMode(PickerViewMode::Thumbnail);
file_picker.SuggestedStartLocation(PickerLocationId::ComputerFolder);
file_picker.as<::IInitializeWithWindow>()->Initialize(native_hwnd);

if (!type_filters.empty())
{
auto filters = file_picker.FileTypeFilter();
filters.Clear();

for (std::string_view type : type_filters)
{
filters.Append(winrt::to_hstring(type));
}
}

IStorageFile file = co_await file_picker.PickSingleFileAsync();

if (file)
{
path = winrt::to_string(file.Path());
}
#endif
co_return path;
}

bool EditorWindow::CreateSurface(void* instance, void** out_window_surface)
{
if (!instance || !out_window_surface)
Expand Down
2 changes: 2 additions & 0 deletions Tetragrama/EditorWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ namespace Tetragrama
virtual void Update(ZEngine::Core::TimeStep delta_time) override;
virtual void Render() override;

virtual std::future<std::string> OpenFileDialogAsync(std::span<std::string_view> type_filters = {}) override;

virtual bool CreateSurface(void* instance, void** out_window_surface) override;
virtual std::vector<std::string> GetRequiredExtensionLayers() override;
ZEngine::Helpers::Ref<ZEngine::Rendering::Swapchain> GetSwapchain() const override;
Expand Down
2 changes: 2 additions & 0 deletions Tetragrama/EntryPoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,11 @@ int applicationEntryPoint(int argc, char* argv[])

#ifdef _WIN32
#include <windows.h>
#include <winrt/Windows.Foundation.h>

int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow)
{
winrt::init_apartment();
return applicationEntryPoint(__argc, __argv);
}

Expand Down
56 changes: 0 additions & 56 deletions Tetragrama/Helpers/WindowsHelper.cpp

This file was deleted.

8 changes: 0 additions & 8 deletions Tetragrama/Helpers/WindowsHelper.h

This file was deleted.

6 changes: 5 additions & 1 deletion ZEngine/ZEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,8 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_link_libraries(zEngineLib PRIVATE stdc++fs)
endif ()

target_link_libraries (zEngineLib PUBLIC imported::External_libs)
target_link_libraries (zEngineLib PUBLIC imported::External_libs)

if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
target_link_libraries (zEngineLib PUBLIC imported::cppwinrt_headers WindowsApp.lib)
endif()
3 changes: 1 addition & 2 deletions ZEngine/ZEngine/Core/Coroutine.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@
#error Compiler support for coroutines missing!
#endif

#include <Core/CoroutineScheduler.h>
#include <CoroutineScheduler.h>

#if defined(__cpp_impl_coroutine) || !defined(_MSC_VER)
namespace ZENGINE_COROUTINE_NAMESPACE
{

template <typename T, typename... Args>
struct coroutine_traits<future<T>, Args...>
{
Expand Down
5 changes: 4 additions & 1 deletion ZEngine/ZEngine/Windows/CoreWindow.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#pragma once

#include <Core/CoreEvent.h>
#include <Core/EventDispatcher.h>
#include <Core/IEventable.h>
Expand All @@ -14,6 +13,8 @@
#include <Rendering/Swapchain.h>
#include <WindowConfiguration.h>
#include <WindowProperty.h>
#include <future>
#include <span>

namespace ZEngine::Windows::Layers
{
Expand Down Expand Up @@ -58,6 +59,8 @@ namespace ZEngine::Windows
virtual void* GetNativeWindow() const = 0;
virtual Helpers::Ref<Rendering::Swapchain> GetSwapchain() const = 0;

virtual std::future<std::string> OpenFileDialogAsync(std::span<std::string_view> type_filters = {}) = 0;

virtual void PollEvent() = 0;
virtual float GetTime() = 0;
virtual float GetDeltaTime() = 0;
Expand Down
20 changes: 20 additions & 0 deletions dependencies.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
# Install necessary NuGet dependencies
install_nuget_package(Microsoft.Windows.CppWinRT 2.0.240405.15 CPPWINRT_NUGET_PATH)

# Generate CppWinRT headers for the local OS
generate_winrt_headers(
EXECUTABLE
${CPPWINRT_NUGET_PATH}/bin/cppwinrt.exe
INPUT
local
OUTPUT
${CMAKE_BINARY_DIR}/__winrt
OPTIMIZE
)

add_library(imported::cppwinrt_headers INTERFACE IMPORTED)
target_include_directories(imported::cppwinrt_headers INTERFACE
${CMAKE_BINARY_DIR}/__winrt
)
endif()

0 comments on commit 1e5e35b

Please sign in to comment.