Skip to content

Commit

Permalink
Merge pull request #163 from Spartan322/improve-binding
Browse files Browse the repository at this point in the history
  • Loading branch information
Spartan322 authored Nov 10, 2023
2 parents f8da086 + cf591ed commit 0008bd6
Show file tree
Hide file tree
Showing 8 changed files with 317 additions and 113 deletions.
34 changes: 34 additions & 0 deletions extension/src/openvic-extension/Checksum.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include "Checksum.hpp"

#include <godot_cpp/core/error_macros.hpp>
#include <godot_cpp/variant/string.hpp>

#include "openvic-extension/utility/ClassBindings.hpp"

using namespace OpenVic;
using namespace godot;

void Checksum::_bind_methods() {
OV_BIND_METHOD(Checksum::get_checksum_text);
}

Checksum* Checksum::get_singleton() {
return _checksum;
}

Checksum::Checksum() {
ERR_FAIL_COND(_checksum != nullptr);
_checksum = this;
}

Checksum::~Checksum() {
ERR_FAIL_COND(_checksum != this);
_checksum = nullptr;
}

/* REQUIREMENTS:
* DAT-8
*/
godot::String Checksum::get_checksum_text() {
return godot::String("1234abcd");
}
27 changes: 7 additions & 20 deletions extension/src/openvic-extension/Checksum.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/object.hpp>
#include <godot_cpp/variant/string.hpp>

namespace OpenVic {
class Checksum : public godot::Object {
Expand All @@ -10,30 +12,15 @@ namespace OpenVic {
static inline Checksum* _checksum = nullptr;

protected:
static void _bind_methods() {
godot::ClassDB::bind_method(godot::D_METHOD("get_checksum_text"), &Checksum::get_checksum_text);
}
static void _bind_methods();

public:
static inline Checksum* get_singleton() {
return _checksum;
}
static Checksum* get_singleton();

inline Checksum() {
ERR_FAIL_COND(_checksum != nullptr);
_checksum = this;
}
inline ~Checksum() {
ERR_FAIL_COND(_checksum != this);
_checksum = nullptr;
}
Checksum();
~Checksum();
// END BOILERPLATE

/* REQUIREMENTS:
* DAT-8
*/
inline godot::String get_checksum_text() {
return godot::String("1234abcd");
}
godot::String get_checksum_text();
};
}
147 changes: 66 additions & 81 deletions extension/src/openvic-extension/GameSingleton.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
#include "GameSingleton.hpp"

#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/core/error_macros.hpp>
#include <godot_cpp/variant/utility_functions.hpp>

#include <openvic-simulation/utility/Logger.hpp>

#include "openvic-extension/LoadLocalisation.hpp"
#include "openvic-extension/Utilities.hpp"
#include "openvic-extension/utility/ClassBindings.hpp"

using namespace godot;
using namespace OpenVic;
Expand All @@ -14,94 +17,76 @@ using OpenVic::Utilities::godot_to_std_string;
using OpenVic::Utilities::std_to_godot_string;
using OpenVic::Utilities::std_view_to_godot_string;

GameSingleton* GameSingleton::singleton = nullptr;

#define BM ClassDB::bind_method
#define BSM ClassDB::bind_static_method

void GameSingleton::_bind_methods() {
BSM("GameSingleton", D_METHOD("setup_logger"), &GameSingleton::setup_logger);
BM(D_METHOD("load_defines_compatibility_mode", "file_paths"), &GameSingleton::load_defines_compatibility_mode);
BSM(
"GameSingleton", D_METHOD("search_for_game_path", "hint_path"), &GameSingleton::search_for_game_path, DEFVAL(String {})
);
BM(D_METHOD("lookup_file", "path"), &GameSingleton::lookup_file);
BM(D_METHOD("setup_game"), &GameSingleton::setup_game);

BM(D_METHOD("get_province_index_from_uv_coords", "coords"), &GameSingleton::get_province_index_from_uv_coords);
BM(D_METHOD("get_province_info_from_index", "index"), &GameSingleton::get_province_info_from_index);
BM(D_METHOD("get_width"), &GameSingleton::get_width);
BM(D_METHOD("get_height"), &GameSingleton::get_height);
BM(D_METHOD("get_aspect_ratio"), &GameSingleton::get_aspect_ratio);
BM(D_METHOD("get_terrain_texture"), &GameSingleton::get_terrain_texture);
BM(D_METHOD("get_province_shape_image_subdivisions"), &GameSingleton::get_province_shape_image_subdivisions);
BM(D_METHOD("get_province_shape_texture"), &GameSingleton::get_province_shape_texture);
BM(D_METHOD("get_province_colour_texture"), &GameSingleton::get_province_colour_texture);

BM(D_METHOD("get_mapmode_count"), &GameSingleton::get_mapmode_count);
BM(D_METHOD("get_mapmode_identifier", "index"), &GameSingleton::get_mapmode_identifier);
BM(D_METHOD("set_mapmode", "identifier"), &GameSingleton::set_mapmode);
BM(D_METHOD("get_selected_province_index"), &GameSingleton::get_selected_province_index);
BM(D_METHOD("set_selected_province", "index"), &GameSingleton::set_selected_province);

BM(D_METHOD("expand_building", "province_index", "building_type_identifier"), &GameSingleton::expand_building);

BM(D_METHOD("set_paused", "paused"), &GameSingleton::set_paused);
BM(D_METHOD("toggle_paused"), &GameSingleton::toggle_paused);
BM(D_METHOD("is_paused"), &GameSingleton::is_paused);
BM(D_METHOD("increase_speed"), &GameSingleton::increase_speed);
BM(D_METHOD("decrease_speed"), &GameSingleton::decrease_speed);
BM(D_METHOD("can_increase_speed"), &GameSingleton::can_increase_speed);
BM(D_METHOD("can_decrease_speed"), &GameSingleton::can_decrease_speed);
BM(D_METHOD("get_longform_date"), &GameSingleton::get_longform_date);
BM(D_METHOD("try_tick"), &GameSingleton::try_tick);
OV_BIND_SMETHOD(setup_logger);

OV_BIND_METHOD(GameSingleton::load_defines_compatibility_mode, { "file_paths" });
OV_BIND_SMETHOD(search_for_game_path, { "hint_path" }, DEFVAL(String {}));

OV_BIND_METHOD(GameSingleton::lookup_file, { "path" });
OV_BIND_METHOD(GameSingleton::setup_game);

OV_BIND_METHOD(GameSingleton::get_province_index_from_uv_coords, { "coords" });
OV_BIND_METHOD(GameSingleton::get_province_info_from_index, { "index" });

OV_BIND_METHOD(GameSingleton::get_width);
OV_BIND_METHOD(GameSingleton::get_height);
OV_BIND_METHOD(GameSingleton::get_aspect_ratio);
OV_BIND_METHOD(GameSingleton::get_terrain_texture);
OV_BIND_METHOD(GameSingleton::get_province_shape_image_subdivisions);
OV_BIND_METHOD(GameSingleton::get_province_shape_texture);
OV_BIND_METHOD(GameSingleton::get_province_colour_texture);

OV_BIND_METHOD(GameSingleton::get_mapmode_count);
OV_BIND_METHOD(GameSingleton::get_mapmode_identifier);
OV_BIND_METHOD(GameSingleton::set_mapmode, { "identifier" });
OV_BIND_METHOD(GameSingleton::get_selected_province_index);
OV_BIND_METHOD(GameSingleton::set_selected_province, { "index" });

OV_BIND_METHOD(GameSingleton::expand_building, { "province_index", "building_type_identifier" });

OV_BIND_METHOD(GameSingleton::set_paused, { "paused" });
OV_BIND_METHOD(GameSingleton::toggle_paused);
OV_BIND_METHOD(GameSingleton::is_paused);
OV_BIND_METHOD(GameSingleton::increase_speed);
OV_BIND_METHOD(GameSingleton::decrease_speed);
OV_BIND_METHOD(GameSingleton::can_increase_speed);
OV_BIND_METHOD(GameSingleton::can_decrease_speed);
OV_BIND_METHOD(GameSingleton::get_longform_date);
OV_BIND_METHOD(GameSingleton::try_tick);

ADD_SIGNAL(MethodInfo("state_updated"));
ADD_SIGNAL(MethodInfo("province_selected", PropertyInfo(Variant::INT, "index")));

BSM("GameSingleton", D_METHOD("get_province_info_province_key"), &GameSingleton::get_province_info_province_key);
BSM("GameSingleton", D_METHOD("get_province_info_region_key"), &GameSingleton::get_province_info_region_key);
BSM("GameSingleton", D_METHOD("get_province_info_life_rating_key"), &GameSingleton::get_province_info_life_rating_key);
BSM("GameSingleton", D_METHOD("get_province_info_terrain_type_key"), &GameSingleton::get_province_info_terrain_type_key);
BSM(
"GameSingleton", D_METHOD("get_province_info_total_population_key"),
&GameSingleton::get_province_info_total_population_key
);
BSM("GameSingleton", D_METHOD("get_province_info_pop_types_key"), &GameSingleton::get_province_info_pop_types_key);
BSM(
"GameSingleton", D_METHOD("get_province_info_pop_ideologies_key"),
&GameSingleton::get_province_info_pop_ideologies_key
);
BSM("GameSingleton", D_METHOD("get_province_info_pop_cultures_key"), &GameSingleton::get_province_info_pop_cultures_key);
BSM("GameSingleton", D_METHOD("get_province_info_rgo_key"), &GameSingleton::get_province_info_rgo_key);
BSM("GameSingleton", D_METHOD("get_province_info_buildings_key"), &GameSingleton::get_province_info_buildings_key);

BSM("GameSingleton", D_METHOD("get_building_info_building_key"), &GameSingleton::get_building_info_building_key);
BSM("GameSingleton", D_METHOD("get_building_info_level_key"), &GameSingleton::get_building_info_level_key);
BSM(
"GameSingleton", D_METHOD("get_building_info_expansion_state_key"),
&GameSingleton::get_building_info_expansion_state_key
);
BSM("GameSingleton", D_METHOD("get_building_info_start_date_key"), &GameSingleton::get_building_info_start_date_key);
BSM("GameSingleton", D_METHOD("get_building_info_end_date_key"), &GameSingleton::get_building_info_end_date_key);
BSM(
"GameSingleton", D_METHOD("get_building_info_expansion_progress_key"),
&GameSingleton::get_building_info_expansion_progress_key
OV_BIND_SMETHOD(get_province_info_province_key);
OV_BIND_SMETHOD(get_province_info_region_key);
OV_BIND_SMETHOD(get_province_info_life_rating_key);
OV_BIND_SMETHOD(get_province_info_terrain_type_key);
OV_BIND_SMETHOD(get_province_info_total_population_key);
OV_BIND_SMETHOD(get_province_info_pop_types_key);
OV_BIND_SMETHOD(get_province_info_pop_ideologies_key);
OV_BIND_SMETHOD(get_province_info_pop_cultures_key);
OV_BIND_SMETHOD(get_province_info_rgo_key);
OV_BIND_SMETHOD(get_province_info_buildings_key);

OV_BIND_SMETHOD(get_building_info_building_key);
OV_BIND_SMETHOD(get_building_info_level_key);
OV_BIND_SMETHOD(get_building_info_expansion_state_key);
OV_BIND_SMETHOD(get_building_info_start_date_key);
OV_BIND_SMETHOD(get_building_info_end_date_key);
OV_BIND_SMETHOD(get_building_info_expansion_progress_key);

OV_BIND_SMETHOD(get_piechart_info_size_key);
OV_BIND_SMETHOD(get_piechart_info_colour_key);

OV_BIND_SMETHOD(
draw_pie_chart,
{ "image", "stopAngles", "colours", "radius", "shadow_displacement", "shadow_tightness", "shadow_radius",
"shadow_thickness", "trim_colour", "trim_size", "gradient_falloff", "gradient_base", "donut", "donut_inner_trim",
"donut_inner_radius" }
);

BSM("GameSingleton", D_METHOD("get_piechart_info_size_key"), &GameSingleton::get_piechart_info_size_key);
BSM("GameSingleton", D_METHOD("get_piechart_info_colour_key"), &GameSingleton::get_piechart_info_colour_key);

BSM(
"GameSingleton",
D_METHOD(
"draw_pie_chart", "image", "stopAngles", "colours", "radius", "shadow_displacement", "shadow_tightness",
"shadow_radius", "shadow_thickness", "trim_colour", "trim_size", "gradient_falloff", "gradient_base", "donut",
"donut_inner_trim", "donut_inner_radius"
),
&GameSingleton::draw_pie_chart
);
BSM("GameSingleton", D_METHOD("load_image", "path"), &GameSingleton::load_image);
OV_BIND_SMETHOD(load_image, { "path" });
}

void GameSingleton::draw_pie_chart(
Expand Down
2 changes: 1 addition & 1 deletion extension/src/openvic-extension/GameSingleton.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace OpenVic {
class GameSingleton : public godot::Object {
GDCLASS(GameSingleton, godot::Object)

static GameSingleton* singleton;
inline static GameSingleton* singleton = nullptr;

GameManager game_manager;
Dataloader dataloader;
Expand Down
22 changes: 12 additions & 10 deletions extension/src/openvic-extension/MapMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@

#include <godot_cpp/templates/vector.hpp>

#include "openvic-extension/utility/ClassBindings.hpp"

using namespace godot;
using namespace OpenVic;

void MapMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_aspect_ratio", "ratio"), &MapMesh::set_aspect_ratio);
ClassDB::bind_method(D_METHOD("get_aspect_ratio"), &MapMesh::get_aspect_ratio);
OV_BIND_METHOD(MapMesh::set_aspect_ratio, { "ratio" });
OV_BIND_METHOD(MapMesh::get_aspect_ratio);

ClassDB::bind_method(D_METHOD("set_repeat_proportion", "proportion"), &MapMesh::set_repeat_proportion);
ClassDB::bind_method(D_METHOD("get_repeat_proportion"), &MapMesh::get_repeat_proportion);
OV_BIND_METHOD(MapMesh::set_repeat_proportion, { "proportion" });
OV_BIND_METHOD(MapMesh::get_repeat_proportion);

ClassDB::bind_method(D_METHOD("set_subdivide_width", "divisions"), &MapMesh::set_subdivide_width);
ClassDB::bind_method(D_METHOD("get_subdivide_width"), &MapMesh::get_subdivide_width);
OV_BIND_METHOD(MapMesh::set_subdivide_width, { "divisions" });
OV_BIND_METHOD(MapMesh::get_subdivide_width);

ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &MapMesh::set_subdivide_depth);
ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &MapMesh::get_subdivide_depth);
OV_BIND_METHOD(MapMesh::set_subdivide_depth, { "divisions" });
OV_BIND_METHOD(MapMesh::get_subdivide_depth);

ClassDB::bind_method(D_METHOD("get_core_aabb"), &MapMesh::get_core_aabb);
ClassDB::bind_method(D_METHOD("is_valid_uv_coord"), &MapMesh::is_valid_uv_coord);
OV_BIND_METHOD(MapMesh::get_core_aabb);
OV_BIND_METHOD(MapMesh::is_valid_uv_coord);

ADD_PROPERTY(
PropertyInfo(Variant::FLOAT, "aspect_ratio", PROPERTY_HINT_NONE, "suffix:m"), "set_aspect_ratio", "get_aspect_ratio"
Expand Down
90 changes: 90 additions & 0 deletions extension/src/openvic-extension/utility/ClassBindings.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#pragma once

#include <concepts>
#include <initializer_list>
#include <string_view>
#include <type_traits>

#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/string_name.hpp>

#include "openvic-extension/utility/StringLiteral.hpp"

namespace godot {
class Object;
}

#define OV_BIND_METHOD(Function, ...) \
::OpenVic::detail::bind_method<::OpenVic::detail::get_function_name<#Function>()>(&Function __VA_OPT__(, ) __VA_ARGS__)

#define OV_BIND_SMETHOD(Function, ...) \
::OpenVic::detail::bind_static_method<::OpenVic::detail::get_function_name<#Function>()>( \
get_class_static(), &Function __VA_OPT__(, ) __VA_ARGS__ \
)

#define OV_BIND_SMETHOD_T(ClassType, Function, ...) \
::OpenVic::detail::bind_static_method<ClassType, ::OpenVic::detail::get_function_name<#Function>()>( \
&Function __VA_OPT__(, ) __VA_ARGS__ \
)

namespace OpenVic::detail {
template<typename Func>
concept IsFunctionPointer = std::is_function_v<std::remove_pointer_t<Func>>;
template<typename Func>
concept IsMemberFunctionPointer = std::is_member_function_pointer_v<Func>;

template<StringLiteral In>
consteval auto get_function_name() {
constexpr auto result = [] {
constexpr auto prefix = std::string_view { "::" };

constexpr std::string_view in_sv = In;
constexpr auto start = in_sv.find_last_of(prefix);

if constexpr (start == std::string_view::npos) {
return In;
} else {
constexpr auto result = in_sv.substr(start + 1);
return StringLiteral<result.size()> { result };
}
}();

return result;
}

template<StringLiteral Name, IsMemberFunctionPointer Func, typename... DefaultsT>
void bind_method(Func func, std::initializer_list<godot::StringName> arg_names, DefaultsT&&... defaults) {
godot::MethodDefinition definition { Name.data() };
definition.args = { arg_names };
godot::ClassDB::bind_method(definition, func, defaults...);
}

template<StringLiteral Name, IsMemberFunctionPointer Func, typename... DefaultsT>
void bind_method(Func func, DefaultsT&&... defaults) {
bind_method<Name, Func>(func, {}, defaults...);
}

template<StringLiteral Name, IsFunctionPointer Func, typename... DefaultsT>
void bind_static_method(
godot::StringName class_name, Func func, std::initializer_list<godot::StringName> arg_names, DefaultsT&&... defaults
) {
godot::MethodDefinition definition { Name.data() };
definition.args = { arg_names };
godot::ClassDB::bind_static_method(class_name, definition, func, defaults...);
}

template<StringLiteral Name, IsFunctionPointer Func, typename... DefaultsT>
void bind_static_method(godot::StringName class_name, Func func, DefaultsT&&... defaults) {
bind_static_method<Name>(class_name, func, {}, defaults...);
}

template<std::derived_from<godot::Object> ClassT, StringLiteral Name, IsFunctionPointer Func, typename... DefaultsT>
void bind_static_method(Func func, std::initializer_list<godot::StringName> arg_names, DefaultsT&&... defaults) {
bind_static_method<Name>(ClassT::get_class_static(), func, arg_names, defaults...);
}

template<std::derived_from<godot::Object> ClassT, StringLiteral Name, IsFunctionPointer Func, typename... DefaultsT>
void bind_static_method(Func func, DefaultsT&&... defaults) {
bind_static_method<ClassT, Name>(func, {}, defaults...);
}
}
Loading

0 comments on commit 0008bd6

Please sign in to comment.