From 035ee24cc6f73ff0f7309cbefeeb0e9cdae4f489 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Sat, 4 May 2024 16:17:31 +0800 Subject: [PATCH] update: c-wrapper of klotski core --- src/core_ffi/all_cases.cc | 62 ++++++++++++++++++++-------------- src/core_ffi/include/klotski.h | 35 ++++++++++--------- 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/src/core_ffi/all_cases.cc b/src/core_ffi/all_cases.cc index a89a258..946f75a 100644 --- a/src/core_ffi/all_cases.cc +++ b/src/core_ffi/all_cases.cc @@ -1,73 +1,85 @@ #include "klotski.h" -#include "all_cases.h" +#include "all_cases/all_cases.h" using klotski::cases::AllCases; using klotski::cases::BasicRanges; using klotski::cases::ALL_CASES_NUM; +typedef std::function Runner; + +// ------------------------------------------------------------------------------------- // + void all_cases_prebuild() { BasicRanges::instance().build(); } -void all_cases_prebuild_async(executor_t executor, notifier_t callback) { - executor([](void *fn) { +void all_cases_prebuild_async(const executor_t executor, const notifier_t callback) { + const auto func = [](void *arg) { all_cases_prebuild(); - ((notifier_t)fn)(); - }, (void*)callback); + reinterpret_cast(arg)(); + }; + executor(func, reinterpret_cast(callback)); } int all_cases_prebuild_available() { - return BasicRanges::instance().is_available() ? KLOTSKI_TRUE : KLOTSKI_FALSE; + return BasicRanges::instance().is_available() ? KLSK_TRUE : KLSK_FALSE; } +// ------------------------------------------------------------------------------------- // + void all_cases_build() { AllCases::instance().build(); } -void all_cases_build_async(executor_t executor, notifier_t callback) { - executor([](void *fn) { +void all_cases_build_async(const executor_t executor, const notifier_t callback) { + const auto func = [](void *arg) { all_cases_build(); - ((notifier_t)fn)(); - }, (void*)callback); + reinterpret_cast(arg)(); + }; + executor(func, reinterpret_cast(callback)); } void all_cases_build_parallel(executor_t executor) { - typedef std::function Runner; AllCases::instance().build_parallel([executor](Runner &&runner) { - executor([](void *fn) { - (*(Runner*)fn)(); - delete (Runner*)fn; - }, (void*)new Runner{std::move(runner)}); + const auto func = [](void *arg) { + (*static_cast(arg))(); + delete static_cast(arg); + }; + executor(func, new Runner {std::move(runner)}); }); } void all_cases_build_parallel_async(executor_t executor, notifier_t callback) { - typedef std::function Runner; - auto all_done = [callback]() { + auto all_done = [callback] { callback(); }; AllCases::instance().build_parallel_async([executor](Runner &&runner) { - executor([](void *fn) { - (*(Runner*)fn)(); - delete (Runner*)fn; - }, (void*)new Runner{std::move(runner)}); + const auto func = [](void *arg) { + (*static_cast(arg))(); + delete static_cast(arg); + }; + executor(func, new Runner {std::move(runner)}); }, std::move(all_done)); } int all_cases_available() { - return AllCases::instance().is_available() ? KLOTSKI_TRUE : KLOTSKI_FALSE; + return AllCases::instance().is_available() ? KLSK_TRUE : KLSK_FALSE; } -int all_cases_num(int head) { - if (head < 0 || head >= (int)ALL_CASES_NUM.size()) { +// ------------------------------------------------------------------------------------- // + +int all_cases_num(const int head) { + if (head < 0 || head >= static_cast(ALL_CASES_NUM.size())) { return -1; } return ALL_CASES_NUM[head]; } -const klotski_u32* all_cases_export(int head) { +const uint32_t* all_cases_export(const int head) { if (all_cases_num(head) < 0) { return nullptr; } return AllCases::instance().fetch()[head].data(); } + +// ------------------------------------------------------------------------------------- // diff --git a/src/core_ffi/include/klotski.h b/src/core_ffi/include/klotski.h index 8488a76..394afc9 100644 --- a/src/core_ffi/include/klotski.h +++ b/src/core_ffi/include/klotski.h @@ -1,5 +1,5 @@ -#ifndef KLOTSKI_H_ -#define KLOTSKI_H_ +#ifndef KLSK_H_ +#define KLSK_H_ #ifdef __cplusplus #include @@ -7,16 +7,15 @@ #include #endif -#define KLOTSKI_TRUE 1 -#define KLOTSKI_FALSE 0 +#define KLSK_TRUE 1 +#define KLSK_FALSE 0 -#define EXTERN extern +// TODO: export c interface +#define KLSK_EXPORT extern typedef void (*notifier_t)(); typedef void (*executor_t)(void (*fn)(void*), void *arg); -typedef uint32_t klotski_u32; - // -------------------------------- klotski all cases --------------------------------- #ifdef __cplusplus @@ -25,54 +24,54 @@ extern "C" { /// Execute all_cases pre-build work, blocking until the end of the build. If /// the build has been completed, the function will return directly. -EXTERN void all_cases_prebuild(); +KLSK_EXPORT void all_cases_prebuild(); /// Execute all_cases pre-build work, the function will return directly without /// blocking, and will be notified with callback when completed. If the build /// has been completed, the parameter function will still be called. -EXTERN void all_cases_prebuild_async(executor_t executor, notifier_t callback); +KLSK_EXPORT void all_cases_prebuild_async(executor_t executor, notifier_t callback); /// Returns the pre-build status of all_cases without any block, value is 0 if /// not completed, non-0 otherwise. -EXTERN int all_cases_prebuild_available(); +KLSK_EXPORT int all_cases_prebuild_available(); /// Perform the build of all_cases, it is blocking, and will return directly /// if completed. -EXTERN void all_cases_build(); +KLSK_EXPORT void all_cases_build(); /// Execute the asynchronous build of all_cases, the task will be sent to the /// executor, and the callback will be called after completion. Even if the /// data is ready, the callback will still be triggered. -EXTERN void all_cases_build_async(executor_t executor, notifier_t callback); +KLSK_EXPORT void all_cases_build_async(executor_t executor, notifier_t callback); /// Build all_cases in parallel, the tasks will be split and sent to the /// executor, you can put them on different threads to work, but note that the /// task can only be executed once, otherwise it will lead to unknown /// consequences, the function will be blocked until all mission completed. -EXTERN void all_cases_build_parallel(executor_t executor); +KLSK_EXPORT void all_cases_build_parallel(executor_t executor); /// Similar to `all_cases_build_parallel`, but it is non-blocking. The callback /// will be triggered after the build is completed. Note that the callback will /// still be triggered even if the data is ready. -EXTERN void all_cases_build_parallel_async(executor_t executor, notifier_t callback); +KLSK_EXPORT void all_cases_build_parallel_async(executor_t executor, notifier_t callback); /// Returns whether the all_cases is ready, 0 means not completed, non-0 means /// the data is ready. -EXTERN int all_cases_available(); +KLSK_EXPORT int all_cases_available(); /// Returns the number of all_cases corresponding to head. Head is an integer /// between 0 and 15. When head is invalid, a value less than 0 is returned. /// Note that when head is `4n-1`, 0 will be returned. -EXTERN int all_cases_num(int head); +KLSK_EXPORT int all_cases_num(int head); /// Returns the starting pointer of all_cases data corresponding to head, the /// number of data is obtained by all_cases_num. When head is invalid, a NULL /// pointer will be returned. Note that when head is `4n-1`, since the number /// is 0, the returned pointer is still a NULL pointer. -EXTERN const klotski_u32* all_cases_export(int head); +KLSK_EXPORT const uint32_t* all_cases_export(int head); #ifdef __cplusplus } #endif -#endif /* KLOTSKI_H_ */ +#endif /* KLSK_H_ */