Browse Source

update: c-wrapper of klotski core

master
Dnomd343 2 months ago
parent
commit
035ee24cc6
  1. 62
      src/core_ffi/all_cases.cc
  2. 35
      src/core_ffi/include/klotski.h

62
src/core_ffi/all_cases.cc

@ -1,73 +1,85 @@
#include "klotski.h" #include "klotski.h"
#include "all_cases.h" #include "all_cases/all_cases.h"
using klotski::cases::AllCases; using klotski::cases::AllCases;
using klotski::cases::BasicRanges; using klotski::cases::BasicRanges;
using klotski::cases::ALL_CASES_NUM; using klotski::cases::ALL_CASES_NUM;
typedef std::function<void()> Runner;
// ------------------------------------------------------------------------------------- //
void all_cases_prebuild() { void all_cases_prebuild() {
BasicRanges::instance().build(); BasicRanges::instance().build();
} }
void all_cases_prebuild_async(executor_t executor, notifier_t callback) { void all_cases_prebuild_async(const executor_t executor, const notifier_t callback) {
executor([](void *fn) { const auto func = [](void *arg) {
all_cases_prebuild(); all_cases_prebuild();
((notifier_t)fn)(); reinterpret_cast<notifier_t>(arg)();
}, (void*)callback); };
executor(func, reinterpret_cast<void*>(callback));
} }
int all_cases_prebuild_available() { 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() { void all_cases_build() {
AllCases::instance().build(); AllCases::instance().build();
} }
void all_cases_build_async(executor_t executor, notifier_t callback) { void all_cases_build_async(const executor_t executor, const notifier_t callback) {
executor([](void *fn) { const auto func = [](void *arg) {
all_cases_build(); all_cases_build();
((notifier_t)fn)(); reinterpret_cast<notifier_t>(arg)();
}, (void*)callback); };
executor(func, reinterpret_cast<void*>(callback));
} }
void all_cases_build_parallel(executor_t executor) { void all_cases_build_parallel(executor_t executor) {
typedef std::function<void()> Runner;
AllCases::instance().build_parallel([executor](Runner &&runner) { AllCases::instance().build_parallel([executor](Runner &&runner) {
executor([](void *fn) { const auto func = [](void *arg) {
(*(Runner*)fn)(); (*static_cast<Runner*>(arg))();
delete (Runner*)fn; delete static_cast<Runner*>(arg);
}, (void*)new Runner{std::move(runner)}); };
executor(func, new Runner {std::move(runner)});
}); });
} }
void all_cases_build_parallel_async(executor_t executor, notifier_t callback) { void all_cases_build_parallel_async(executor_t executor, notifier_t callback) {
typedef std::function<void()> Runner; auto all_done = [callback] {
auto all_done = [callback]() {
callback(); callback();
}; };
AllCases::instance().build_parallel_async([executor](Runner &&runner) { AllCases::instance().build_parallel_async([executor](Runner &&runner) {
executor([](void *fn) { const auto func = [](void *arg) {
(*(Runner*)fn)(); (*static_cast<Runner*>(arg))();
delete (Runner*)fn; delete static_cast<Runner*>(arg);
}, (void*)new Runner{std::move(runner)}); };
executor(func, new Runner {std::move(runner)});
}, std::move(all_done)); }, std::move(all_done));
} }
int all_cases_available() { 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<int>(ALL_CASES_NUM.size())) {
return -1; return -1;
} }
return ALL_CASES_NUM[head]; 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) { if (all_cases_num(head) < 0) {
return nullptr; return nullptr;
} }
return AllCases::instance().fetch()[head].data(); return AllCases::instance().fetch()[head].data();
} }
// ------------------------------------------------------------------------------------- //

35
src/core_ffi/include/klotski.h

@ -1,5 +1,5 @@
#ifndef KLOTSKI_H_ #ifndef KLSK_H_
#define KLOTSKI_H_ #define KLSK_H_
#ifdef __cplusplus #ifdef __cplusplus
#include <cstdint> #include <cstdint>
@ -7,16 +7,15 @@
#include <stdint.h> #include <stdint.h>
#endif #endif
#define KLOTSKI_TRUE 1 #define KLSK_TRUE 1
#define KLOTSKI_FALSE 0 #define KLSK_FALSE 0
#define EXTERN extern // TODO: export c interface
#define KLSK_EXPORT extern
typedef void (*notifier_t)(); typedef void (*notifier_t)();
typedef void (*executor_t)(void (*fn)(void*), void *arg); typedef void (*executor_t)(void (*fn)(void*), void *arg);
typedef uint32_t klotski_u32;
// -------------------------------- klotski all cases --------------------------------- // -------------------------------- klotski all cases ---------------------------------
#ifdef __cplusplus #ifdef __cplusplus
@ -25,54 +24,54 @@ extern "C" {
/// Execute all_cases pre-build work, blocking until the end of the build. If /// Execute all_cases pre-build work, blocking until the end of the build. If
/// the build has been completed, the function will return directly. /// 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 /// Execute all_cases pre-build work, the function will return directly without
/// blocking, and will be notified with callback when completed. If the build /// blocking, and will be notified with callback when completed. If the build
/// has been completed, the parameter function will still be called. /// 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 /// Returns the pre-build status of all_cases without any block, value is 0 if
/// not completed, non-0 otherwise. /// 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 /// Perform the build of all_cases, it is blocking, and will return directly
/// if completed. /// 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 /// 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 /// executor, and the callback will be called after completion. Even if the
/// data is ready, the callback will still be triggered. /// 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 /// 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 /// 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 /// task can only be executed once, otherwise it will lead to unknown
/// consequences, the function will be blocked until all mission completed. /// 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 /// 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 /// will be triggered after the build is completed. Note that the callback will
/// still be triggered even if the data is ready. /// 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 /// Returns whether the all_cases is ready, 0 means not completed, non-0 means
/// the data is ready. /// 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 /// 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. /// 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. /// 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 /// 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 /// 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 /// pointer will be returned. Note that when head is `4n-1`, since the number
/// is 0, the returned pointer is still a NULL pointer. /// 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 #ifdef __cplusplus
} }
#endif #endif
#endif /* KLOTSKI_H_ */ #endif /* KLSK_H_ */

Loading…
Cancel
Save