Skip to content

Commit f2edda9

Browse files
authored
association improvements, fixes, and tests (#27)
1 parent 9a357b1 commit f2edda9

File tree

14 files changed

+329
-38
lines changed

14 files changed

+329
-38
lines changed

.bazelrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ build --incompatible_strict_action_env
66
build --enable_runfiles
77

88
build:windows --platforms=//bazel/platforms:windows
9+
build:windows --host_platform=//bazel/platforms:windows
910

1011
build:linux --platforms=//bazel/platforms:linux
1112
build:linux --extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux

.github/workflows/ci-windows.bazelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# workaround long path issues on GitHub actions Windows machine
2+
startup --output_user_root=C:/tmp
3+
import %workspace%/.github/workflows/ci.bazelrc
4+

.github/workflows/ci.bazelrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ build --repository_cache=~/.cache/bazel-repo
1111
test --test_output=errors
1212
# Allows tests to run bazelisk-in-bazel, since this is the cache folder used
1313
test --test_env=XDG_CACHE_HOME
14+

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
/Users/runneradmin/.cache/bazel-disk-cache
2929
key: ${{runner.os}}-bazel-cache
3030
- uses: actions/checkout@v3
31-
- run: bazel --bazelrc=.github/workflows/ci.bazelrc test //...
31+
- run: bazel --bazelrc=.bazelrc --bazelrc=.github/workflows/ci-windows.bazelrc test //...
3232
test-linux:
3333
runs-on: ubuntu-latest
3434
steps:
@@ -45,4 +45,4 @@ jobs:
4545
env:
4646
# Bazelisk will download bazel to here, ensure it is cached between runs.
4747
XDG_CACHE_HOME: ~/.cache/bazel-repo
48-
run: bazel --bazelrc=$GITHUB_WORKSPACE/.github/workflows/ci.bazelrc --bazelrc=.bazelrc test //...
48+
run: bazel --bazelrc=.bazelrc --bazelrc=$GITHUB_WORKSPACE/.github/workflows/ci.bazelrc test //...

WORKSPACE.bazel

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ http_archive(
1111

1212
http_archive(
1313
name = "rules_ecsact",
14-
sha256 = "dfb1a2e7093110b2daf30c6d1a83f6d0bf19fb9dd52b12b1577c055fd217e990",
15-
strip_prefix = "rules_ecsact-0.2.0",
16-
url = "https://github.com/ecsact-dev/rules_ecsact/archive/refs/tags/0.2.0.tar.gz",
14+
sha256 = "e6d888c63aa536b5b7c6af10d217cdb8ad98b2262fa9d02515a99edbd0d94eea",
15+
strip_prefix = "rules_ecsact-0.2.1",
16+
url = "https://github.com/ecsact-dev/rules_ecsact/archive/refs/tags/0.2.1.tar.gz",
1717
)
1818

1919
http_archive(

bazel/copts.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
"""
33

44
copts = select({
5-
"@bazel_tools//tools/cpp:msvc": ["/std:c++20", "/Zc:preprocessor", "/permissive-"],
5+
"@bazel_tools//tools/cpp:msvc": ["/std:c++20", "/Zc:preprocessor", "/permissive-", "/diagnostics:caret"],
66
"//conditions:default": ["-std=c++20"],
77
})

ecsact/entt/detail/internal_markers.hh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <cstdint>
44
#include <type_traits>
5+
#include <concepts>
56

67
namespace ecsact::entt::detail {
78

@@ -11,6 +12,13 @@ struct association {
1112
static constexpr auto field_offset = FieldOffset;
1213
};
1314

15+
template<typename Assoc>
16+
concept association_concept = //
17+
requires {
18+
{ typename Assoc::component_type{} };
19+
{ Assoc::field_offset } -> std::convertible_to<std::size_t>;
20+
};
21+
1422
template<typename C>
1523
struct temp_storage;
1624

ecsact/entt/detail/system_execution_context.hh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ struct system_execution_context_base {
3939
const void* action;
4040
};
4141

42+
namespace detail {}
43+
4244
template<typename Package, typename SystemCapabilitiesInfo>
4345
struct system_execution_context : system_execution_context_base {
4446
using system_execution_context_base::const_cptr_t;
@@ -50,7 +52,7 @@ struct system_execution_context : system_execution_context_base {
5052

5153
using caps_info = SystemCapabilitiesInfo;
5254
using package = Package;
53-
using view_type = ecsact::entt::view_from_system_capabilities_type<caps_info>;
55+
using view_type = ecsact::entt::system_or_association_view_t<caps_info>;
5456
using association_views_type =
5557
ecsact::entt::association_views_type<caps_info>;
5658

@@ -380,7 +382,6 @@ struct system_execution_context : system_execution_context_base {
380382
mp_for_each<associations>([&]<typename Assoc>(Assoc) {
381383
using ComponentT = typename Assoc::component_type;
382384
constexpr std::size_t offset = Assoc::field_offset;
383-
auto compnent_name = typeid(ComponentT).name();
384385
const ComponentT& comp = info.registry.template get<ComponentT>(entity);
385386

386387
auto field_entity_value = *reinterpret_cast<const ecsact_entity_id*>(

ecsact/entt/runtime.hh

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -657,9 +657,10 @@ private:
657657
using caps_info = ecsact::system_capabilities_info<SystemT>;
658658
using associations = typename caps_info::associations;
659659

660-
auto view = system_view<SystemT>(info.registry);
661660
auto assoc_views = system_association_views<SystemT>(info.registry);
662661
auto assoc_views_itrs = system_association_views_iterators(assoc_views);
662+
663+
auto view = system_view<SystemT>(info.registry);
663664
const void* action_data = nullptr;
664665

665666
auto itr_view = [&] {
@@ -672,9 +673,10 @@ private:
672673
using Assoc = mp_at<associations, mp_size_t<I>>;
673674
using ComponentT = typename Assoc::component_type;
674675

675-
auto& assoc_view = std::get<I>(assoc_views);
676-
auto& assoc_view_itr = std::get<I>(assoc_views_itrs);
677676
constexpr auto offset = Assoc::field_offset;
677+
678+
auto& assoc_view = std::get<I>(assoc_views);
679+
auto& assoc_view_itr = std::get<I>(assoc_views_itrs);
678680
assert(view.contains(entity));
679681
auto& comp = view.template get<ComponentT>(entity);
680682

@@ -684,12 +686,16 @@ private:
684686
auto entt_field_entity_value =
685687
info.get_entt_entity_id(field_entity_value);
686688

687-
bool found_associated_entity = false;
688-
for(; assoc_view_itr != assoc_view.end(); ++assoc_view_itr) {
689-
found_associated_entity = *assoc_view_itr ==
690-
entt_field_entity_value;
691-
if(found_associated_entity) {
692-
break;
689+
bool found_associated_entity = *assoc_view_itr ==
690+
entt_field_entity_value;
691+
if(!found_associated_entity) {
692+
assoc_view_itr = assoc_view.begin();
693+
for(; assoc_view_itr != assoc_view.end(); ++assoc_view_itr) {
694+
found_associated_entity = *assoc_view_itr ==
695+
entt_field_entity_value;
696+
if(found_associated_entity) {
697+
break;
698+
}
693699
}
694700
}
695701

@@ -708,6 +714,10 @@ private:
708714
action_data,
709715
actions
710716
);
717+
718+
mp_for_each<mp_iota_c<mp_size<associations>::value>>([&](auto I) {
719+
++std::get<I>(assoc_views_itrs);
720+
});
711721
}
712722
}
713723
};

ecsact/entt/system_view.hh

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ auto system_view_helper(
2222

2323
namespace ecsact::entt {
2424

25-
template<typename SystemCapabilitiesInfo>
25+
template<
26+
typename SystemCapabilitiesInfo,
27+
typename ExtraGetTypes = ::ecsact::mp_list<>,
28+
typename ExtraExcludeTypes = ::ecsact::mp_list<>>
2629
auto view_from_system_capabilities(::entt::registry& registry) {
2730
using caps_info = SystemCapabilitiesInfo;
2831

@@ -50,48 +53,61 @@ auto view_from_system_capabilities(::entt::registry& registry) {
5053
readwrite_components,
5154
include_components,
5255
removes_components,
56+
ExtraGetTypes,
5357
mp_transform<beforechange_storage, readwrite_components>>,
5458
::ecsact::mp_list<>>>;
5559

5660
using exclude_types = mp_unique<mp_flatten<
57-
mp_push_back<exclude_components, adds_components>,
61+
mp_push_back<exclude_components, adds_components, ExtraExcludeTypes>,
5862
::ecsact::mp_list<>>>;
5963

6064
return detail::system_view_helper(get_types{}, exclude_types{}, registry);
6165
}
6266

63-
template<typename SystemCapabilitiesInfo>
67+
template<
68+
typename SystemCapabilitiesInfo,
69+
typename ExtraGetTypes = ::ecsact::mp_list<>,
70+
typename ExtraExcludeTypes = ::ecsact::mp_list<>>
6471
using view_from_system_capabilities_type =
65-
decltype(view_from_system_capabilities<SystemCapabilitiesInfo>(
66-
std::declval<::entt::registry&>()
67-
));
72+
decltype(view_from_system_capabilities<
73+
SystemCapabilitiesInfo,
74+
ExtraGetTypes,
75+
ExtraExcludeTypes>(std::declval<::entt::registry&>()));
76+
77+
template<typename Assoc>
78+
auto association_view(::entt::registry& registry) {
79+
using ecsact::entt::detail::association;
80+
using assoc_marker_component =
81+
association<typename Assoc::component_type, Assoc::field_offset>;
82+
using extra_get_types = ::ecsact::mp_list<assoc_marker_component>;
83+
using view_type = view_from_system_capabilities_type<Assoc, extra_get_types>;
84+
85+
return view_from_system_capabilities<Assoc, extra_get_types>(registry);
86+
}
87+
88+
template<typename Assoc>
89+
using association_view_type =
90+
decltype(association_view<Assoc>(std::declval<::entt::registry&>()));
6891

6992
template<typename SystemCapabilitiesInfo>
7093
auto association_views(::entt::registry& registry) {
94+
using boost::mp11::mp_empty;
7195
using boost::mp11::mp_for_each;
7296
using boost::mp11::mp_rename;
7397
using boost::mp11::mp_transform;
7498

7599
using caps_info = SystemCapabilitiesInfo;
100+
using assocs = typename caps_info::associations;
76101

77102
using result_type = mp_rename<
78-
mp_transform<
79-
view_from_system_capabilities_type,
80-
typename caps_info::associations>,
103+
mp_transform<association_view_type, typename caps_info::associations>,
81104
std::tuple>;
82105

83-
static_assert(
84-
boost::mp11::mp_size<typename caps_info::associations>::value ==
85-
std::tuple_size_v<result_type>,
86-
"[INTERNAL] result_type failure"
87-
);
88-
89106
result_type result;
90107

91-
mp_for_each<typename caps_info::associations>([&]<typename Assoc>(Assoc) {
92-
using view_type = view_from_system_capabilities_type<Assoc>;
93-
std::get<view_type>(result) =
94-
view_from_system_capabilities<Assoc>(registry);
108+
mp_for_each<assocs>([&]<typename Assoc>(Assoc) {
109+
std::get<association_view_type<Assoc>>(result) =
110+
association_view<Assoc>(registry);
95111
});
96112

97113
return result;
@@ -133,4 +149,19 @@ auto system_association_views_iterators(AssocViews& assoc_views) {
133149
assoc_views
134150
);
135151
}
152+
153+
template<typename T>
154+
struct system_or_association_view {
155+
using type = view_from_system_capabilities_type<T>;
156+
};
157+
158+
template<ecsact::entt::detail::association_concept T>
159+
struct system_or_association_view<T> {
160+
using type = association_view_type<T>;
161+
};
162+
163+
template<typename T>
164+
using system_or_association_view_t =
165+
typename system_or_association_view<T>::type;
166+
136167
} // namespace ecsact::entt

runtime/test/BUILD.bazel

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,15 @@ cc_test(
3535
"@com_google_googletest//:gtest_main",
3636
],
3737
)
38+
39+
cc_binary(
40+
name = "debug_print_entt_views",
41+
srcs = ["debug_print_entt_views.cc"],
42+
copts = copts,
43+
deps = [
44+
":runtime__public_cc",
45+
"//:lib",
46+
"@boost//libs/mp11",
47+
"@com_github_skypjack_entt//:entt",
48+
],
49+
)
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include <iostream>
2+
#include <type_traits>
3+
#include <boost/mp11.hpp>
4+
#include "ecsact/entt/system_view.hh"
5+
#include "runtime_test.ecsact.meta.hh"
6+
7+
auto replace_all(
8+
std::string& str,
9+
std::string_view find,
10+
std::string_view replace
11+
) {
12+
auto idx = str.find(find);
13+
while(idx != std::string::npos) {
14+
str.replace(idx, find.size(), replace);
15+
idx = str.find(find, idx + replace.size());
16+
}
17+
}
18+
19+
template<typename T>
20+
auto pretty_type_string() {
21+
std::string pretty_type = typeid(T).name();
22+
23+
replace_all(pretty_type, "class ", "");
24+
replace_all(pretty_type, "struct ", "");
25+
replace_all(pretty_type, "enum ", "");
26+
replace_all(pretty_type, "ecsact::entt::detail::", "");
27+
replace_all(pretty_type, "entt::basic_view", "view");
28+
replace_all(pretty_type, "runtime_test::", "");
29+
replace_all(pretty_type, ",", ", ");
30+
replace_all(pretty_type, "> >", ">>");
31+
32+
return pretty_type;
33+
}
34+
35+
template<typename S>
36+
auto print_system_views() {
37+
using boost::mp11::mp_for_each;
38+
using ecsact::entt::system_association_views_type;
39+
using ecsact::entt::system_view_type;
40+
41+
std::cout //
42+
<< " " << pretty_type_string<S>() << "\n"
43+
<< " | " << pretty_type_string<system_view_type<S>>() << "\n";
44+
45+
mp_for_each<system_association_views_type<S>>([]<typename V>(V) {
46+
std::cout //
47+
<< " | " << pretty_type_string<V>() << " (association view)\n";
48+
});
49+
50+
std::cout << "\n";
51+
}
52+
53+
auto main() -> int {
54+
using boost::mp11::mp_for_each;
55+
using runtime_test::package;
56+
57+
std::cout << " ==== [ System Views ] ==== \n";
58+
mp_for_each<typename package::systems>([]<typename S>(S) {
59+
print_system_views<S>();
60+
});
61+
62+
std::cout << " ==== [ Action Views ] ==== \n";
63+
mp_for_each<typename package::actions>([]<typename S>(S) {
64+
print_system_views<S>();
65+
});
66+
67+
return 0;
68+
}

0 commit comments

Comments
 (0)