Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions jni/exported_symbols.lds
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,25 @@ _SolveBoardPBN
_dds_c_calc_dd_table
_dds_c_calc_dd_table_pbn
_dds_c_calc_par
_dds_c_calc_par_pbn
_dds_c_clear_tt
_dds_c_configure_tt
_dds_c_convert_to_dealer_text_format
_dds_c_convert_to_sides_text_format
_dds_c_create_solvercontext
_dds_c_create_solvercontext_default
_dds_c_dealer_par
_dds_c_dealer_par_bin
_dds_c_destroy_solvercontext
_dds_c_error_message
_dds_c_get_dds_info
_dds_c_log_append
_dds_c_log_clear
_dds_c_par_from_table
_dds_c_reset_best_moves_lite
_dds_c_reset_for_solve
_dds_c_resize_tt
_dds_c_sides_par
_dds_c_sides_par_bin
_dds_c_solve_board
_dds_c_solve_board_pbn
11 changes: 11 additions & 0 deletions jni/version_script.lds
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,28 @@
dds_c_calc_dd_table;
dds_c_calc_dd_table_pbn;
dds_c_calc_par;
dds_c_calc_par_pbn;
dds_c_clear_tt;
dds_c_configure_tt;
dds_c_convert_to_dealer_text_format;
dds_c_convert_to_sides_text_format;
dds_c_create_solvercontext;
dds_c_create_solvercontext_default;
dds_c_dealer_par;
dds_c_dealer_par_bin;
dds_c_destroy_solvercontext;
dds_c_error_message;
dds_c_get_dds_info;
dds_c_log_append;
dds_c_log_clear;
dds_c_par_from_table;
dds_c_reset_best_moves_lite;
dds_c_reset_for_solve;
dds_c_resize_tt;
dds_c_sides_par;
dds_c_sides_par_bin;
dds_c_solve_board;
dds_c_solve_board_pbn;
local:
*;
};
21 changes: 21 additions & 0 deletions library/src/api/calc_par.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,27 @@ auto calc_par(
DdTableResults* table_results,
ParResults* par_results) -> int;

/**
* @brief Calculate par score and contracts for a PBN-format deal table with
* explicit solver context.
*
* Converts the PBN deal to binary format and delegates to
* calc_par(SolverContext&, ...).
*
* @param ctx Solver context for resource management and TT reuse
* @param table_deal_pbn Deal in PBN format
* @param vulnerable Vulnerability (0=None, 1=Both, 2=NS, 3=EW)
* @param table_results Output: double dummy table results
* @param par_results Output: par score and contract strings
* @return Error code (RETURN_NO_FAULT on success, RETURN_PBN_FAULT on parse error)
*/
auto calc_par_pbn(
SolverContext& ctx,
const DdTableDealPBN& table_deal_pbn,
int vulnerable,
DdTableResults* table_results,
ParResults* par_results) -> int;

/**
* @brief Calculate par from pre-computed double dummy table.
*
Expand Down
16 changes: 15 additions & 1 deletion library/src/api/dds_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ extern "C" {
int mode,
FutureTricks* futp) -> int;

EXTERN_C DLLEXPORT auto dds_solve_board_pbn(DDS_SOLVER_CTX ctx,
const DealPBN& dlpbn,
int target,
int solutions,
int mode,
FutureTricks* futp) -> int;

EXTERN_C DLLEXPORT auto dds_calc_dd_table(
DDS_SOLVER_CTX ctx,
const DdTableDeal& table_deal,
Expand All @@ -63,6 +70,13 @@ extern "C" {
int vulnerable,
DdTableResults* table_results,
ParResults* par_results) -> int;


EXTERN_C DLLEXPORT auto dds_calc_par_pbn(
DDS_SOLVER_CTX ctx,
const DdTableDealPBN& table_deal_pbn,
int vulnerable,
DdTableResults* table_results,
ParResults* par_results) -> int;


}
167 changes: 165 additions & 2 deletions library/src/api/dds_c_api.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
/*
DDS, a bridge double dummy solver.

Implementation of the pure-C ABI shim. Each function casts the opaque
void* handle back to SolverContext* and forwards to the reference-taking
Implementation of the pure-C ABI shim. Most functions cast the opaque
void* handle back to SolverContext* and forward to the reference-taking
dds_* functions declared in dds_api.hpp. SolverConfig / TTKind stay internal
to this translation unit and never cross the shim boundary.

A second, smaller group of functions needs no SolverContext at all: they
operate on already-produced data (a DdTableResults/ParResultsMaster) or
static library info. Those take no handle and forward straight to the
corresponding legacy dll.h function, which is already POD-only and
extern "C" — there is no C++ type to keep off the ABI boundary, so no
dds_api.hpp intermediate is needed for them.

See LICENSE and README.
*/

Expand Down Expand Up @@ -61,6 +68,22 @@ DLLEXPORT int dds_c_solve_board(DDS_C_SOLVER_CTX ctx,
}
}

DLLEXPORT int dds_c_solve_board_pbn(DDS_C_SOLVER_CTX ctx,
const struct DealPBN* dlpbn,
int target, int solutions, int mode,
struct FutureTricks* futp)
{
if (ctx == nullptr || dlpbn == nullptr || futp == nullptr)
return RETURN_UNKNOWN_FAULT;

try {
return dds_solve_board_pbn(static_cast<SolverContext*>(ctx),
*dlpbn, target, solutions, mode, futp);
} catch (...) {
return RETURN_UNKNOWN_FAULT;
}
}

DLLEXPORT int dds_c_calc_dd_table(DDS_C_SOLVER_CTX ctx,
const struct DdTableDeal* deal,
struct DdTableResults* results)
Expand Down Expand Up @@ -92,6 +115,23 @@ DLLEXPORT int dds_c_calc_par(DDS_C_SOLVER_CTX ctx,
}
}

DLLEXPORT int dds_c_calc_par_pbn(DDS_C_SOLVER_CTX ctx,
const struct DdTableDealPBN* deal,
int vulnerable,
struct DdTableResults* results,
struct ParResults* par)
{
if (ctx == nullptr || deal == nullptr || results == nullptr || par == nullptr)
return RETURN_UNKNOWN_FAULT;

try {
return dds_calc_par_pbn(static_cast<SolverContext*>(ctx),
*deal, vulnerable, results, par);
} catch (...) {
return RETURN_UNKNOWN_FAULT;
}
}

DLLEXPORT DDS_C_SOLVER_CTX dds_c_create_solvercontext(int tt_kind,
int def_mb, int max_mb)
{
Expand Down Expand Up @@ -207,4 +247,127 @@ DLLEXPORT void dds_c_log_clear(DDS_C_SOLVER_CTX ctx)
}
}

/* --- Context-free utilities: no SolverContext, forward straight to the
legacy dll.h function. --- */

DLLEXPORT int dds_c_par_from_table(const struct DdTableResults* table,
int vulnerable,
struct ParResults* par)
{
if (table == nullptr || par == nullptr)
return RETURN_UNKNOWN_FAULT;

try {
return Par(table, par, vulnerable);
} catch (...) {
return RETURN_UNKNOWN_FAULT;
}
}

DLLEXPORT int dds_c_sides_par(const struct DdTableResults* table,
struct ParResultsDealer sides_res[2],
int vulnerable)
{
if (table == nullptr || sides_res == nullptr)
return RETURN_UNKNOWN_FAULT;

try {
return SidesPar(table, sides_res, vulnerable);
} catch (...) {
return RETURN_UNKNOWN_FAULT;
}
}

DLLEXPORT int dds_c_dealer_par(const struct DdTableResults* table,
struct ParResultsDealer* par,
int dealer, int vulnerable)
{
if (table == nullptr || par == nullptr)
return RETURN_UNKNOWN_FAULT;

try {
return DealerPar(table, par, dealer, vulnerable);
} catch (...) {
return RETURN_UNKNOWN_FAULT;
}
}

DLLEXPORT int dds_c_dealer_par_bin(const struct DdTableResults* table,
struct ParResultsMaster* par,
int dealer, int vulnerable)
{
if (table == nullptr || par == nullptr)
return RETURN_UNKNOWN_FAULT;

try {
return DealerParBin(table, par, dealer, vulnerable);
} catch (...) {
return RETURN_UNKNOWN_FAULT;
}
}

DLLEXPORT int dds_c_sides_par_bin(const struct DdTableResults* table,
struct ParResultsMaster sides_res[2],
int vulnerable)
{
if (table == nullptr || sides_res == nullptr)
return RETURN_UNKNOWN_FAULT;

try {
return SidesParBin(table, sides_res, vulnerable);
} catch (...) {
return RETURN_UNKNOWN_FAULT;
}
}

DLLEXPORT int dds_c_convert_to_dealer_text_format(const struct ParResultsMaster* par,
char* resp)
{
if (par == nullptr || resp == nullptr)
return RETURN_UNKNOWN_FAULT;

try {
return ConvertToDealerTextFormat(par, resp);
} catch (...) {
return RETURN_UNKNOWN_FAULT;
}
}

DLLEXPORT int dds_c_convert_to_sides_text_format(const struct ParResultsMaster par[2],
struct ParTextResults* resp)
{
if (par == nullptr || resp == nullptr)
return RETURN_UNKNOWN_FAULT;

try {
return ConvertToSidesTextFormat(par, resp);
} catch (...) {
return RETURN_UNKNOWN_FAULT;
}
}

DLLEXPORT void dds_c_get_dds_info(struct DDSInfo* info)
{
if (info == nullptr)
return;

try {
GetDDSInfo(info);
} catch (...) {
// Must not unwind through the C ABI boundary.
}
}

DLLEXPORT void dds_c_error_message(int code, char line[80])
{
if (line == nullptr)
return;

try {
ErrorMessage(code, line);
} catch (...) {
// Must not unwind through the C ABI boundary.
}
}

} // extern "C"
59 changes: 59 additions & 0 deletions library/src/api/dds_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ DLLEXPORT int dds_c_solve_board(DDS_C_SOLVER_CTX ctx,
int target, int solutions, int mode,
struct FutureTricks* futp);

/* Solve a single board in PBN format. Returns a RETURN_* status code. */
DLLEXPORT int dds_c_solve_board_pbn(DDS_C_SOLVER_CTX ctx,
const struct DealPBN* dlpbn,
int target, int solutions, int mode,
struct FutureTricks* futp);

/* Compute the double dummy table for a deal. */
DLLEXPORT int dds_c_calc_dd_table(DDS_C_SOLVER_CTX ctx,
const struct DdTableDeal* deal,
Expand All @@ -54,6 +60,14 @@ DLLEXPORT int dds_c_calc_par(DDS_C_SOLVER_CTX ctx,
struct DdTableResults* results,
struct ParResults* par);

/* Compute the par result for a PBN-format deal (computes the DD table
internally). */
DLLEXPORT int dds_c_calc_par_pbn(DDS_C_SOLVER_CTX ctx,
const struct DdTableDealPBN* deal,
int vulnerable,
struct DdTableResults* results,
struct ParResults* par);

/* Creation with explicit transposition-table configuration. The C++ SolverConfig
is decomposed into scalars rather than mirrored as a struct: passing a struct
by value is exactly the ABI question this shim exists to avoid, and a mirror
Expand Down Expand Up @@ -81,6 +95,51 @@ DLLEXPORT void dds_c_reset_best_moves_lite(DDS_C_SOLVER_CTX ctx);
DLLEXPORT void dds_c_log_append(DDS_C_SOLVER_CTX ctx, const char* msg);
DLLEXPORT void dds_c_log_clear(DDS_C_SOLVER_CTX ctx);

/* Context-free utilities. These operate on already-produced data (a
DdTableResults/ParResultsMaster) or static library info; they need no
SolverContext and so take no handle. */

/* Compute par from an already-computed double dummy table. */
DLLEXPORT int dds_c_par_from_table(const struct DdTableResults* table,
int vulnerable,
struct ParResults* par);

/* Compute par from both the NS and EW dealing sides' viewpoints. */
DLLEXPORT int dds_c_sides_par(const struct DdTableResults* table,
struct ParResultsDealer sides_res[2],
int vulnerable);

/* Compute par for a specific dealer. */
DLLEXPORT int dds_c_dealer_par(const struct DdTableResults* table,
struct ParResultsDealer* par,
int dealer, int vulnerable);

/* Binary (ContractType) variant of dds_c_dealer_par. */
DLLEXPORT int dds_c_dealer_par_bin(const struct DdTableResults* table,
struct ParResultsMaster* par,
int dealer, int vulnerable);

/* Binary (ContractType) variant of dds_c_sides_par. */
DLLEXPORT int dds_c_sides_par_bin(const struct DdTableResults* table,
struct ParResultsMaster sides_res[2],
int vulnerable);

/* Format a dds_c_dealer_par_bin() result as dealer-oriented text. */
DLLEXPORT int dds_c_convert_to_dealer_text_format(const struct ParResultsMaster* par,
char* resp);

/* Format a dds_c_sides_par_bin() result (both sides) as sides-oriented text.
par must point to a 2-element array, one entry per side, matching
dds_c_sides_par_bin's output -- not a single dds_c_dealer_par_bin() result. */
DLLEXPORT int dds_c_convert_to_sides_text_format(const struct ParResultsMaster par[2],
struct ParTextResults* resp);

/* Query library version/build information. */
DLLEXPORT void dds_c_get_dds_info(struct DDSInfo* info);

/* Map a RETURN_* status code to its human-readable text. */
DLLEXPORT void dds_c_error_message(int code, char line[80]);

#ifdef __cplusplus
}
#endif
Loading