Skip to content

Commit 89a70a5

Browse files
committed
VkCube.cpp: Use map to dispatch platform execute
1 parent 555dca1 commit 89a70a5

File tree

1 file changed

+113
-147
lines changed

1 file changed

+113
-147
lines changed

cube/cube.cpp

Lines changed: 113 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include <iostream>
3333
#include <memory>
3434
#include <map>
35+
#include <functional>
36+
#include <string>
3537

3638
#if defined(VK_USE_PLATFORM_XLIB_KHR)
3739
#include "xlib_loader.h"
@@ -228,91 +230,71 @@ enum class WsiPlatform {
228230
invalid, // Sentinel just to indicate invalid user input
229231
};
230232

231-
WsiPlatform wsi_from_string(std::string const &str) {
232-
if (str == "auto") return WsiPlatform::auto_;
233+
constexpr std::pair<const char*, WsiPlatform> platform_data_[] = {
234+
{"auto", WsiPlatform::auto_},
233235
#if defined(VK_USE_PLATFORM_WIN32_KHR)
234-
if (str == "win32") return WsiPlatform::win32;
236+
{"win32", WsiPlatform::win32},
235237
#endif
236238
#if defined(VK_USE_PLATFORM_METAL_EXT)
237-
if (str == "metal") return WsiPlatform::metal;
239+
{"metal", WsiPlatform::metal},
238240
#endif
239241
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
240-
if (str == "android") return WsiPlatform::android;
242+
{"android", WsiPlatform::android},
241243
#endif
242244
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
243-
if (str == "qnx") return WsiPlatform::qnx;
245+
{"qnx", WsiPlatform::qnx},
244246
#endif
245247
#if defined(VK_USE_PLATFORM_XCB_KHR)
246-
if (str == "xcb") return WsiPlatform::xcb;
248+
{"xcb", WsiPlatform::xcb},
247249
#endif
248250
#if defined(VK_USE_PLATFORM_XLIB_KHR)
249-
if (str == "xlib") return WsiPlatform::xlib;
251+
{"xlib", WsiPlatform::xlib},
250252
#endif
251253
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
252-
if (str == "wayland") return WsiPlatform::wayland;
254+
{"wayland", WsiPlatform::wayland},
253255
#endif
254256
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
255-
if (str == "directfb") return WsiPlatform::directfb;
257+
{"directfb", WsiPlatform::directfb},
256258
#endif
257259
#if defined(VK_USE_PLATFORM_DISPLAY_KHR)
258-
if (str == "display") return WsiPlatform::display;
260+
{"display", WsiPlatform::display},
259261
#endif
260262
#if defined(VK_USE_PLATFORM_FUCHSIA)
261-
if (str == "fuchsia_display") return WsiPlatform::fuchsia_display;
262-
if (str == "fuchsia_scenic") return WsiPlatform::fuchsia_scenic;
263+
{"fuchsia_display", WsiPlatform::fuchsia_display},
264+
{"fuchsia_scenic", WsiPlatform::fuchsia_scenic},
263265
#endif
266+
};
267+
268+
template<typename T, size_t N>
269+
constexpr auto construct_array(const T (&data)[N]) {
270+
std::array<T, N> res{};
271+
272+
for (size_t i = 0; i < N; ++i) {
273+
res[i].first = data[i].first;
274+
res[i].second = data[i].second;
275+
}
276+
277+
return res;
278+
}
279+
280+
constexpr auto platform_data = construct_array(platform_data_);
281+
282+
WsiPlatform wsi_from_string(std::string const &str) {
283+
for (size_t i = 0; i < sizeof(platform_data)/sizeof(platform_data[0]); i++) {
284+
if (platform_data[i].first == str) {
285+
return platform_data[i].second;
286+
}
287+
}
264288
return WsiPlatform::invalid;
265289
};
266290

267291
const char *wsi_to_string(WsiPlatform wsi_platform) {
268-
switch (wsi_platform) {
269-
case (WsiPlatform::auto_):
270-
return "auto";
271-
#if defined(VK_USE_PLATFORM_WIN32_KHR)
272-
case (WsiPlatform::win32):
273-
return "win32";
274-
#endif
275-
#if defined(VK_USE_PLATFORM_METAL_EXT)
276-
case (WsiPlatform::metal):
277-
return "metal";
278-
#endif
279-
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
280-
case (WsiPlatform::android):
281-
return "android";
282-
#endif
283-
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
284-
case (WsiPlatform::qnx):
285-
return "qnx";
286-
#endif
287-
#if defined(VK_USE_PLATFORM_XCB_KHR)
288-
case (WsiPlatform::xcb):
289-
return "xcb";
290-
#endif
291-
#if defined(VK_USE_PLATFORM_XLIB_KHR)
292-
case (WsiPlatform::xlib):
293-
return "xlib";
294-
#endif
295-
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
296-
case (WsiPlatform::wayland):
297-
return "wayland";
298-
#endif
299-
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
300-
case (WsiPlatform::directfb):
301-
return "directfb";
302-
#endif
303-
#if defined(VK_USE_PLATFORM_DISPLAY_KHR)
304-
case (WsiPlatform::display):
305-
return "display";
306-
#endif
307-
#if defined(VK_USE_PLATFORM_FUCHSIA)
308-
case (WsiPlatform::fuchsia_display):
309-
return "fuchsia_display";
310-
case (WsiPlatform::fuchsia_scenic):
311-
return "fuchsia_scenic";
312-
#endif
313-
default:
314-
return "unknown";
292+
for (size_t i = 0; i < sizeof(platform_data)/sizeof(platform_data[0]); i++) {
293+
if (platform_data[i].second == wsi_platform) {
294+
return platform_data[i].first;
295+
}
315296
}
297+
return "unknown";
316298
};
317299

318300
struct SwapchainImageResources {
@@ -1118,47 +1100,13 @@ void Demo::init(int argc, char **argv) {
11181100
}
11191101

11201102
std::string wsi_platforms;
1121-
#if defined(VK_USE_PLATFORM_XCB_KHR)
1122-
wsi_platforms.append("xcb");
1123-
#endif
1124-
#if defined(VK_USE_PLATFORM_XLIB_KHR)
1125-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1126-
wsi_platforms.append("xlib");
1127-
#endif
1128-
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
1129-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1130-
wsi_platforms.append("wayland");
1131-
#endif
1132-
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
1133-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1134-
wsi_platforms.append("directfb");
1135-
#endif
1136-
#if defined(VK_USE_PLATFORM_DISPLAY_KHR)
1137-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1138-
wsi_platforms.append("display");
1139-
#endif
1140-
#if defined(VK_USE_PLATFORM_METAL_EXT)
1141-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1142-
wsi_platforms.append("metal");
1143-
#endif
1144-
#if defined(VK_USE_PLATFORM_WIN32_KHR)
1145-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1146-
wsi_platforms.append("win32");
1147-
#endif
1148-
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
1149-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1150-
wsi_platforms.append("android");
1151-
#endif
1152-
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
1153-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1154-
wsi_platforms.append("qnx");
1155-
#endif
1156-
#if defined(VK_USE_PLATFORM_FUCHSIA)
1157-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1158-
wsi_platforms.append("fuchsia_display");
1159-
if (!wsi_platforms.empty()) wsi_platforms.append("|");
1160-
wsi_platforms.append("fuchsia_scenic");
1161-
#endif
1103+
1104+
wsi_platforms.append(platform_data[0].first);
1105+
for (size_t index = 1; index < sizeof(platform_data)/sizeof(platform_data[0]); ++index) {
1106+
wsi_platforms.append("|");
1107+
wsi_platforms.append(platform_data[index].first);
1108+
}
1109+
11621110
std::stringstream usage;
11631111
usage << "Usage:\n " << APP_SHORT_NAME << "\t[--use_staging] [--validate]\n"
11641112
<< "\t[--break] [--c <framecount>] [--suppress_popups]\n"
@@ -4094,57 +4042,75 @@ void Demo::execute<WsiPlatform::display>() {
40944042
run<WsiPlatform::display>();
40954043
}
40964044

4045+
template<WsiPlatform platform>
4046+
auto get_dispatcher_element(Demo& demo) {
4047+
return std::pair<WsiPlatform, std::function<void()>>{ platform, [&demo](){demo.execute<platform>();} };
4048+
}
4049+
4050+
constexpr auto get_count_of_platform_run_from_main() {
4051+
size_t count = 0;
4052+
for (auto& data : platform_data) {
4053+
if (data.second == WsiPlatform::xcb ||
4054+
data.second == WsiPlatform::xlib ||
4055+
data.second == WsiPlatform::wayland ||
4056+
data.second == WsiPlatform::directfb ||
4057+
data.second == WsiPlatform::display ||
4058+
data.second == WsiPlatform::qnx ||
4059+
data.second == WsiPlatform::fuchsia_display ||
4060+
data.second == WsiPlatform::fuchsia_scenic) {
4061+
count++;
4062+
}
4063+
}
4064+
return count;
4065+
}
4066+
4067+
constexpr auto get_platform_run_from_main() {
4068+
std::array<WsiPlatform, get_count_of_platform_run_from_main()> platform_run_from_main{};
4069+
int i = 0;
4070+
for (auto& data : platform_data) {
4071+
if (data.second == WsiPlatform::xcb ||
4072+
data.second == WsiPlatform::xlib ||
4073+
data.second == WsiPlatform::wayland ||
4074+
data.second == WsiPlatform::directfb ||
4075+
data.second == WsiPlatform::display ||
4076+
data.second == WsiPlatform::qnx ||
4077+
data.second == WsiPlatform::fuchsia_display ||
4078+
data.second == WsiPlatform::fuchsia_scenic) {
4079+
platform_run_from_main[i++] = data.second;
4080+
}
4081+
}
4082+
return platform_run_from_main;
4083+
}
4084+
4085+
constexpr auto platform_run_from_main = get_platform_run_from_main();
4086+
4087+
template<size_t i=0>
4088+
auto construct_dispatcher(std::map<WsiPlatform, std::function<void()>>& map, Demo& demo) {
4089+
map.emplace(
4090+
get_dispatcher_element<platform_run_from_main[i]>(demo)
4091+
);
4092+
construct_dispatcher<i+1>(map, demo);
4093+
}
4094+
template<>
4095+
auto construct_dispatcher<platform_run_from_main.size()>(std::map<WsiPlatform, std::function<void()>>& map, Demo& demo) {
4096+
}
4097+
40974098
int main(int argc, char **argv) {
40984099
Demo demo;
40994100

41004101
demo.init(argc, argv);
41014102

4102-
switch (demo.wsi_platform) {
4103-
default:
4104-
case (WsiPlatform::auto_):
4105-
fprintf(stderr,
4106-
"WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with "
4107-
"--wsi\n");
4108-
exit(1);
4109-
break;
4110-
#if defined(VK_USE_PLATFORM_XCB_KHR)
4111-
case (WsiPlatform::xcb):
4112-
demo.execute<WsiPlatform::xcb>();
4113-
break;
4114-
#endif
4115-
#if defined(VK_USE_PLATFORM_XLIB_KHR)
4116-
case (WsiPlatform::xlib):
4117-
demo.execute<WsiPlatform::xlib>();
4118-
break;
4119-
#endif
4120-
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
4121-
case (WsiPlatform::wayland):
4122-
demo.execute<WsiPlatform::wayland>();
4123-
break;
4124-
#endif
4125-
#if defined(VK_USE_PLATFORM_DIRECTFB_EXT)
4126-
case (WsiPlatform::directfb):
4127-
demo.execute<WsiPlatform::directfb>();
4128-
break;
4129-
#endif
4130-
#if defined(VK_USE_PLATFORM_DISPLAY_KHR)
4131-
case (WsiPlatform::display):
4132-
demo.execute<WsiPlatform::display>();
4133-
break;
4134-
#endif
4135-
#if defined(VK_USE_PLATFORM_SCREEN_QNX)
4136-
case (WsiPlatform::qnx):
4137-
demo.execute<WsiPlatform::qnx>();
4138-
break;
4139-
#endif
4140-
#if defined(VK_USE_PLATFORM_FUCHSIA)
4141-
case (WsiPlatform::fuchsia_display):
4142-
demo.execute<WsiPlatform::fuchsia_display>();
4143-
break;
4144-
case (WsiPlatform::fuchsia_scenic):
4145-
demo.execute<WsiPlatform::fuchsia_scenic>();
4146-
break;
4147-
#endif
4103+
auto platform_map = std::map<WsiPlatform, std::function<void()>>{};
4104+
construct_dispatcher(platform_map, demo);
4105+
4106+
if (platform_map.find(demo.wsi_platform) != platform_map.end()) {
4107+
platform_map[demo.wsi_platform]();
4108+
}
4109+
else {
4110+
fprintf(stderr,
4111+
"WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with "
4112+
"--wsi\n");
4113+
exit(1);
41484114
}
41494115

41504116
demo.cleanup();

0 commit comments

Comments
 (0)