Skip to content

Commit b64e6ab

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

File tree

1 file changed

+116
-148
lines changed

1 file changed

+116
-148
lines changed

cube/cube.cpp

Lines changed: 116 additions & 148 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,90 +230,72 @@ 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
264-
return WsiPlatform::invalid;
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+
auto ite = std::find_if(platform_data.begin(), platform_data.end(), [&str](auto &data) { return data.first == str; });
284+
285+
if (ite != platform_data.end()) {
286+
return ite->second;
287+
} else {
288+
return WsiPlatform::invalid;
289+
}
265290
};
266291

267292
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";
293+
auto ite = std::find_if(platform_data.begin(), platform_data.end(), [&wsi_platform](auto &data) { return data.second == wsi_platform; });
294+
295+
if (ite != platform_data.end()) {
296+
return ite->first;
297+
} else {
298+
return "unknown";
315299
}
316300
};
317301

@@ -1118,47 +1102,13 @@ void Demo::init(int argc, char **argv) {
11181102
}
11191103

11201104
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
1105+
1106+
wsi_platforms.append(platform_data[0].first);
1107+
for (size_t index = 1; index < platform_data.size(); ++index) {
1108+
wsi_platforms.append("|");
1109+
wsi_platforms.append(platform_data[index].first);
1110+
}
1111+
11621112
std::stringstream usage;
11631113
usage << "Usage:\n " << APP_SHORT_NAME << "\t[--use_staging] [--validate]\n"
11641114
<< "\t[--break] [--c <framecount>] [--suppress_popups]\n"
@@ -4094,57 +4044,75 @@ void Demo::execute<WsiPlatform::display>() {
40944044
run<WsiPlatform::display>();
40954045
}
40964046

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

41004103
demo.init(argc, argv);
41014104

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
4105+
auto platform_map = std::map<WsiPlatform, std::function<void()>>{};
4106+
construct_dispatcher(platform_map, demo);
4107+
4108+
if (platform_map.find(demo.wsi_platform) != platform_map.end()) {
4109+
platform_map[demo.wsi_platform]();
4110+
}
4111+
else {
4112+
fprintf(stderr,
4113+
"WSI platform should have already been set, indicating a bug. Please set a WSI platform manually with "
4114+
"--wsi\n");
4115+
exit(1);
41484116
}
41494117

41504118
demo.cleanup();

0 commit comments

Comments
 (0)