Skip to content

Commit

Permalink
Allow applications to customize how the global managers are initialized.
Browse files Browse the repository at this point in the history
  • Loading branch information
Themaister committed Oct 21, 2023
1 parent c68e7f3 commit 25ff7af
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 41 deletions.
9 changes: 9 additions & 0 deletions application/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_granite_internal_lib(granite-application
application.hpp
application_glue.hpp
application.cpp
platforms/application_headless.cpp)

Expand Down Expand Up @@ -42,6 +43,14 @@ target_link_libraries(granite-application-entry-headless
PRIVATE granite-application granite-platform granite-filesystem)
target_compile_options(granite-application-entry-headless PRIVATE ${GRANITE_CXX_FLAGS})

# Can be defined by application to get a custom entry point.
# Otherwise, get a default one.
if (NOT TARGET granite-application-interface-query)
add_granite_internal_lib(granite-application-interface-query STATIC application_interface_query.cpp)
target_compile_options(granite-application-interface-query PRIVATE ${GRANITE_CXX_FLAGS})
endif()
target_link_libraries(granite-application PRIVATE granite-application-interface-query)

add_subdirectory(events)
add_subdirectory(input)
add_subdirectory(platforms)
Expand Down
10 changes: 3 additions & 7 deletions application/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,6 @@ using namespace Vulkan;

namespace Granite
{
Application::Application()
{
#ifdef HAVE_GRANITE_RENDERER
GRANITE_COMMON_RENDERER_DATA()->initialize_static_assets(GRANITE_ASSET_MANAGER(), GRANITE_FILESYSTEM());
#endif
}

Application::~Application()
{
auto *group = GRANITE_THREAD_GROUP();
Expand All @@ -53,6 +46,9 @@ Application::~Application()

bool Application::init_platform(std::unique_ptr<WSIPlatform> new_platform)
{
#ifdef HAVE_GRANITE_RENDERER
GRANITE_COMMON_RENDERER_DATA()->initialize_static_assets(GRANITE_ASSET_MANAGER(), GRANITE_FILESYSTEM());
#endif
platform = std::move(new_platform);
application_wsi.set_platform(platform.get());
return true;
Expand Down
20 changes: 2 additions & 18 deletions application/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
#include "wsi.hpp"
#include "application_wsi_events.hpp"
#include "input.hpp"
#include "application_glue.hpp"

namespace Granite
{
class Application
{
public:
Application();
virtual ~Application();
virtual void render_frame(double frame_time, double elapsed_time) = 0;
bool init_platform(std::unique_ptr<Vulkan::WSIPlatform> platform);
Expand Down Expand Up @@ -100,20 +100,4 @@ class Application
bool ready_pipelines = false;
void check_initialization_progress();
};

int application_main(Application *(*create_application)(int, char **), int argc, char **argv);
int application_main_headless(Application *(*create_application)(int, char **), int argc, char **argv);

extern Application *application_create(int argc, char *argv[]);

// Call this or setup_default_filesystem to ensure application-main is linked in correctly without having to mess around
// with -Wl,--whole-archive.
void application_dummy();
void application_setup_default_filesystem(const char *default_asset_directory);
}

#ifdef ASSET_DIRECTORY
#define GRANITE_APPLICATION_SETUP_FILESYSTEM() ::Granite::application_setup_default_filesystem(ASSET_DIRECTORY)
#else
#define GRANITE_APPLICATION_SETUP_FILESYSTEM() ::Granite::application_setup_default_filesystem(nullptr)
#endif
}
8 changes: 6 additions & 2 deletions application/application_entry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,13 @@ int main(int argc, char *argv[])
#endif

#ifdef APPLICATION_ENTRY_HEADLESS
int ret = Granite::application_main_headless(Granite::application_create, argc, argv);
int ret = Granite::application_main_headless(Granite::query_application_interface,
Granite::application_create,
argc, argv);
#else
int ret = Granite::application_main(Granite::application_create, argc, argv);
int ret = Granite::application_main(Granite::query_application_interface,
Granite::application_create,
argc, argv);
#endif

return ret;
Expand Down
68 changes: 68 additions & 0 deletions application/application_glue.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* Copyright (c) 2017-2023 Hans-Kristian Arntzen
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#pragma once
#include <stddef.h>
#include <stdint.h>

namespace Granite
{
enum class ApplicationQuery
{
DefaultManagerFlags
};

class Application;

int application_main(
bool (*query_application_interface)(ApplicationQuery, void *data, size_t size),
Application *(*create_application)(int, char **),
int argc, char **argv);

int application_main_headless(
bool (*query_application_interface)(ApplicationQuery, void *data, size_t size),
Application *(*create_application)(int, char **),
int argc, char **argv);

extern Application *application_create(int argc, char *argv[]);

struct ApplicationQueryDefaultManagerFlags
{
uint32_t manager_feature_flags;
};

extern bool query_application_interface(ApplicationQuery query, void *data, size_t size);

// Call this or setup_default_filesystem to ensure application-main is linked in correctly without having to mess around
// with -Wl,--whole-archive.
void application_dummy();

void application_setup_default_filesystem(const char *default_asset_directory);
}

#ifdef ASSET_DIRECTORY
#define GRANITE_APPLICATION_SETUP_FILESYSTEM() ::Granite::application_setup_default_filesystem(ASSET_DIRECTORY)
#else
#define GRANITE_APPLICATION_SETUP_FILESYSTEM() ::Granite::application_setup_default_filesystem(nullptr)
#endif

#define GRANITE_APPLICATION_DECL_DEFAULT_QUERY() namespace Granite { bool query_application_interface(Granite::ApplicationQuery, void *, size_t) { return false; } }
2 changes: 2 additions & 0 deletions application/application_interface_query.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include "application_glue.hpp"
GRANITE_APPLICATION_DECL_DEFAULT_QUERY()
5 changes: 4 additions & 1 deletion application/platforms/application_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1071,7 +1071,10 @@ void android_main(android_app *app)
global_state.app = app;

init_jni();
Global::init();

ApplicationQueryDefaultManagerFlags flags{Global::MANAGER_FEATURE_DEFAULT_BITS};
query_application_interface(ApplicationQuery::DefaultManagerFlags, &flags, sizeof(flags));
Global::init(flags.manager_feature_flags);

LOGI("Starting Granite!\n");

Expand Down
8 changes: 6 additions & 2 deletions application/platforms/application_glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -659,9 +659,13 @@ static void close_cb(GLFWwindow *window)

namespace Granite
{
int application_main(Application *(*create_application)(int, char **), int argc, char *argv[])
int application_main(
bool (*query_application_interface)(ApplicationQuery, void *, size_t),
Application *(*create_application)(int, char **), int argc, char *argv[])
{
Granite::Global::init();
ApplicationQueryDefaultManagerFlags flags{Global::MANAGER_FEATURE_DEFAULT_BITS};
query_application_interface(ApplicationQuery::DefaultManagerFlags, &flags, sizeof(flags));
Granite::Global::init(flags.manager_feature_flags);

Granite::WSIPlatformGLFW::Options options;
int exit_code;
Expand Down
24 changes: 16 additions & 8 deletions application/platforms/application_headless.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,10 @@ static void print_help()

namespace Granite
{
int application_main_headless(Application *(*create_application)(int, char **), int argc, char *argv[])
int application_main_headless(
bool (*query_application_interface)(ApplicationQuery, void *, size_t),
Application *(*create_application)(int, char **),
int argc, char *argv[])
{
if (argc < 1)
return 1;
Expand Down Expand Up @@ -522,14 +525,19 @@ int application_main_headless(Application *(*create_application)(int, char **),
if (!Util::parse_cli_filtered(std::move(cbs), argc, argv, exit_code))
return exit_code;

Granite::Global::init(Granite::Global::MANAGER_FEATURE_DEFAULT_BITS);
ApplicationQueryDefaultManagerFlags flags{Global::MANAGER_FEATURE_DEFAULT_BITS};
query_application_interface(ApplicationQuery::DefaultManagerFlags, &flags, sizeof(flags));
Granite::Global::init(flags.manager_feature_flags);

if (!args.assets.empty())
GRANITE_FILESYSTEM()->register_protocol("assets", std::make_unique<OSFilesystem>(args.assets));
if (!args.builtin.empty())
GRANITE_FILESYSTEM()->register_protocol("builtin", std::make_unique<OSFilesystem>(args.builtin));
if (!args.cache.empty())
GRANITE_FILESYSTEM()->register_protocol("cache", std::make_unique<OSFilesystem>(args.cache));
if (flags.manager_feature_flags & Global::MANAGER_FEATURE_FILESYSTEM_BIT)
{
if (!args.assets.empty())
GRANITE_FILESYSTEM()->register_protocol("assets", std::make_unique<OSFilesystem>(args.assets));
if (!args.builtin.empty())
GRANITE_FILESYSTEM()->register_protocol("builtin", std::make_unique<OSFilesystem>(args.builtin));
if (!args.cache.empty())
GRANITE_FILESYSTEM()->register_protocol("cache", std::make_unique<OSFilesystem>(args.cache));
}

auto app = std::unique_ptr<Application>(create_application(argc, argv));

Expand Down
9 changes: 7 additions & 2 deletions application/platforms/application_khr_display.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,14 @@ static void signal_handler(int)

namespace Granite
{
int application_main(Application *(*create_application)(int, char **), int argc, char *argv[])
int application_main(
bool (*query_application_interface)(ApplicationQuery, void *, size_t),
Application *(*create_application)(int, char **), int argc, char *argv[])
{
Global::init();
ApplicationQueryDefaultManagerFlags flags{Global::MANAGER_FEATURE_DEFAULT_BITS};
query_application_interface(ApplicationQuery::DefaultManagerFlags, &flags, sizeof(flags));
Global::init(flags.manager_feature_flags);

auto app = std::unique_ptr<Granite::Application>(create_application(argc, argv));
if (app)
{
Expand Down
4 changes: 3 additions & 1 deletion application/platforms/application_libretro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ static retro_hw_render_callback hw_render;

RETRO_API void retro_init(void)
{
Global::init();
ApplicationQueryDefaultManagerFlags flags{Global::MANAGER_FEATURE_DEFAULT_BITS};
query_application_interface(ApplicationQuery::DefaultManagerFlags, &flags, sizeof(flags));
Global::init(flags.manager_feature_flags);
}

RETRO_API void retro_deinit(void)
Expand Down

0 comments on commit 25ff7af

Please sign in to comment.