More flexible error handling, convenience methods
Allow getting solver errors returned rather than raising error. The API allows setting a mask of which error kinds raise vs return. Also add some convenience methods: - `add_to` and `remove_from` constraint methods to solver. - add and remove multiple constraints and edit/suggest variables at once
This commit is contained in:
@@ -343,95 +343,84 @@ int kiwi_constraint_expression(KiwiConstraintRef constraint, KiwiExpression* out
|
|||||||
return n_terms;
|
return n_terms;
|
||||||
}
|
}
|
||||||
|
|
||||||
KiwiSolver* kiwi_solver_new() {
|
struct KiwiSolver {
|
||||||
return reinterpret_cast<KiwiSolver*>(new Solver());
|
unsigned error_mask;
|
||||||
|
Solver solver;
|
||||||
|
};
|
||||||
|
|
||||||
|
KiwiSolver* kiwi_solver_new(unsigned error_mask) {
|
||||||
|
return new KiwiSolver {error_mask};
|
||||||
}
|
}
|
||||||
|
|
||||||
void kiwi_solver_del(KiwiSolver* sp) {
|
void kiwi_solver_del(KiwiSolver* s) {
|
||||||
auto* solver = reinterpret_cast<Solver*>(sp);
|
if (s)
|
||||||
if (solver)
|
delete s;
|
||||||
delete solver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const KiwiErr* kiwi_solver_add_constraint(KiwiSolver* s, KiwiConstraintRef constraint) {
|
const KiwiErr* kiwi_solver_add_constraint(KiwiSolver* s, KiwiConstraintRef constraint) {
|
||||||
return wrap_err(
|
return wrap_err(s, ConstraintRef(constraint), [](auto* s, const auto c) {
|
||||||
reinterpret_cast<Solver*>(s),
|
s->solver.addConstraint(c);
|
||||||
ConstraintRef(constraint),
|
});
|
||||||
[](auto solver, const auto c) { solver->addConstraint(c); }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const KiwiErr* kiwi_solver_remove_constraint(KiwiSolver* s, KiwiConstraintRef constraint) {
|
const KiwiErr* kiwi_solver_remove_constraint(KiwiSolver* s, KiwiConstraintRef constraint) {
|
||||||
return wrap_err(
|
return wrap_err(s, ConstraintRef(constraint), [](auto* s, const auto c) {
|
||||||
reinterpret_cast<Solver*>(s),
|
s->solver.removeConstraint(c);
|
||||||
ConstraintRef(constraint),
|
});
|
||||||
[](auto solver, const auto c) { solver->removeConstraint(c); }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool kiwi_solver_has_constraint(const KiwiSolver* s, KiwiConstraintRef constraint) {
|
bool kiwi_solver_has_constraint(const KiwiSolver* s, KiwiConstraintRef constraint) {
|
||||||
const auto* solver = reinterpret_cast<const Solver*>(s);
|
|
||||||
ConstraintRef c(constraint);
|
ConstraintRef c(constraint);
|
||||||
if (!solver || !c)
|
if (!s || !c)
|
||||||
return 0;
|
return 0;
|
||||||
return solver->hasConstraint(c);
|
return s->solver.hasConstraint(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
const KiwiErr* kiwi_solver_add_edit_var(KiwiSolver* s, KiwiVarRef var, double strength) {
|
const KiwiErr* kiwi_solver_add_edit_var(KiwiSolver* s, KiwiVarRef var, double strength) {
|
||||||
return wrap_err(
|
return wrap_err(s, VariableRef(var), [strength](auto* s, const auto v) {
|
||||||
reinterpret_cast<Solver*>(s),
|
s->solver.addEditVariable(v, strength);
|
||||||
VariableRef(var),
|
});
|
||||||
[strength](auto solver, const auto v) { solver->addEditVariable(v, strength); }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const KiwiErr* kiwi_solver_remove_edit_var(KiwiSolver* s, KiwiVarRef var) {
|
const KiwiErr* kiwi_solver_remove_edit_var(KiwiSolver* s, KiwiVarRef var) {
|
||||||
return wrap_err(reinterpret_cast<Solver*>(s), VariableRef(var), [](auto solver, const auto v) {
|
return wrap_err(s, VariableRef(var), [](auto* s, const auto v) {
|
||||||
solver->removeEditVariable(v);
|
s->solver.removeEditVariable(v);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool kiwi_solver_has_edit_var(const KiwiSolver* s, KiwiVarRef var) {
|
bool kiwi_solver_has_edit_var(const KiwiSolver* s, KiwiVarRef var) {
|
||||||
const auto* solver = reinterpret_cast<const Solver*>(s);
|
|
||||||
VariableRef v(var);
|
VariableRef v(var);
|
||||||
if (!solver || !v)
|
if (!s || !v)
|
||||||
return 0;
|
return 0;
|
||||||
return solver->hasEditVariable(v);
|
return s->solver.hasEditVariable(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
const KiwiErr* kiwi_solver_suggest_value(KiwiSolver* s, KiwiVarRef var, double value) {
|
const KiwiErr* kiwi_solver_suggest_value(KiwiSolver* s, KiwiVarRef var, double value) {
|
||||||
return wrap_err(
|
return wrap_err(s, VariableRef(var), [value](auto* s, const auto v) {
|
||||||
reinterpret_cast<Solver*>(s),
|
s->solver.suggestValue(v, value);
|
||||||
VariableRef(var),
|
});
|
||||||
|
|
||||||
[value](auto solver, const auto v) { solver->suggestValue(v, value); }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kiwi_solver_update_vars(KiwiSolver* s) {
|
void kiwi_solver_update_vars(KiwiSolver* s) {
|
||||||
auto* solver = reinterpret_cast<Solver*>(s);
|
if (s)
|
||||||
if (solver)
|
s->solver.updateVariables();
|
||||||
solver->updateVariables();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kiwi_solver_reset(KiwiSolver* s) {
|
void kiwi_solver_reset(KiwiSolver* s) {
|
||||||
auto* solver = reinterpret_cast<Solver*>(s);
|
if (s)
|
||||||
if (solver)
|
s->solver.reset();
|
||||||
solver->reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kiwi_solver_dump(const KiwiSolver* s) {
|
void kiwi_solver_dump(const KiwiSolver* s) {
|
||||||
auto* solver = reinterpret_cast<const Solver*>(s);
|
if (s)
|
||||||
if (solver)
|
s->solver.dump();
|
||||||
solver->dump();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* kiwi_solver_dumps(const KiwiSolver* s) {
|
char* kiwi_solver_dumps(const KiwiSolver* s) {
|
||||||
auto* solver = reinterpret_cast<const Solver*>(s);
|
if (!s)
|
||||||
if (!solver)
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const auto str = solver->dumps(); // upstream library defect
|
const auto str = s->solver.dumps(); // upstream library defect
|
||||||
const auto buf_size = str.size() + 1;
|
const auto buf_size = str.size() + 1;
|
||||||
auto* buf = static_cast<char*>(std::malloc(buf_size));
|
auto* buf = static_cast<char*>(std::malloc(buf_size));
|
||||||
if (!buf)
|
if (!buf)
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ typedef struct KiwiErr {
|
|||||||
bool must_free;
|
bool must_free;
|
||||||
} KiwiErr;
|
} KiwiErr;
|
||||||
|
|
||||||
typedef struct KiwiSolver KiwiSolver;
|
typedef struct KiwiSolver
|
||||||
|
KiwiSolver; // LuaJIT: typedef struct { unsigned error_mask; } KiwiSolver;
|
||||||
KiwiVarRef kiwi_var_new(const char* name);
|
KiwiVarRef kiwi_var_new(const char* name);
|
||||||
void kiwi_var_del(KiwiVarRef var);
|
void kiwi_var_del(KiwiVarRef var);
|
||||||
KiwiVarRef kiwi_var_clone(KiwiVarRef var);
|
KiwiVarRef kiwi_var_clone(KiwiVarRef var);
|
||||||
@@ -74,8 +74,8 @@ enum KiwiRelOp kiwi_constraint_op(KiwiConstraintRef constraint);
|
|||||||
bool kiwi_constraint_violated(KiwiConstraintRef constraint);
|
bool kiwi_constraint_violated(KiwiConstraintRef constraint);
|
||||||
int kiwi_constraint_expression(KiwiConstraintRef constraint, KiwiExpression* out, int out_size);
|
int kiwi_constraint_expression(KiwiConstraintRef constraint, KiwiExpression* out, int out_size);
|
||||||
|
|
||||||
KiwiSolver* kiwi_solver_new();
|
KiwiSolver* kiwi_solver_new(unsigned error_mask);
|
||||||
void kiwi_solver_del(KiwiSolver* sp);
|
void kiwi_solver_del(KiwiSolver* s);
|
||||||
|
|
||||||
const KiwiErr* kiwi_solver_add_constraint(KiwiSolver* sp, KiwiConstraintRef constraint);
|
const KiwiErr* kiwi_solver_add_constraint(KiwiSolver* sp, KiwiConstraintRef constraint);
|
||||||
const KiwiErr* kiwi_solver_remove_constraint(KiwiSolver* sp, KiwiConstraintRef constraint);
|
const KiwiErr* kiwi_solver_remove_constraint(KiwiSolver* sp, KiwiConstraintRef constraint);
|
||||||
|
|||||||
201
kiwi.lua
201
kiwi.lua
@@ -48,7 +48,7 @@ typedef struct KiwiErr {
|
|||||||
bool must_free;
|
bool must_free;
|
||||||
} KiwiErr;
|
} KiwiErr;
|
||||||
|
|
||||||
typedef struct KiwiSolver KiwiSolver;
|
typedef struct KiwiSolver { unsigned error_mask; } KiwiSolver;
|
||||||
|
|
||||||
KiwiVarRef kiwi_var_new(const char* name);
|
KiwiVarRef kiwi_var_new(const char* name);
|
||||||
void kiwi_var_del(KiwiVarRef var);
|
void kiwi_var_del(KiwiVarRef var);
|
||||||
@@ -76,8 +76,8 @@ enum KiwiRelOp kiwi_constraint_op(KiwiConstraintRef constraint);
|
|||||||
bool kiwi_constraint_violated(KiwiConstraintRef constraint);
|
bool kiwi_constraint_violated(KiwiConstraintRef constraint);
|
||||||
int kiwi_constraint_expression(KiwiConstraintRef constraint, KiwiExpression* out, int out_size);
|
int kiwi_constraint_expression(KiwiConstraintRef constraint, KiwiExpression* out, int out_size);
|
||||||
|
|
||||||
KiwiSolver* kiwi_solver_new();
|
KiwiSolver* kiwi_solver_new(unsigned error_mask);
|
||||||
void kiwi_solver_del(KiwiSolver* sp);
|
void kiwi_solver_del(KiwiSolver* s);
|
||||||
|
|
||||||
const KiwiErr* kiwi_solver_add_constraint(KiwiSolver* sp, KiwiConstraintRef constraint);
|
const KiwiErr* kiwi_solver_add_constraint(KiwiSolver* sp, KiwiConstraintRef constraint);
|
||||||
const KiwiErr* kiwi_solver_remove_constraint(KiwiSolver* sp, KiwiConstraintRef constraint);
|
const KiwiErr* kiwi_solver_remove_constraint(KiwiSolver* sp, KiwiConstraintRef constraint);
|
||||||
@@ -720,6 +720,27 @@ do
|
|||||||
return ffi_gc(expr, ckiwi.kiwi_expression_del_vars) --[[@as kiwi.Expression]]
|
return ffi_gc(expr, ckiwi.kiwi_expression_del_vars) --[[@as kiwi.Expression]]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add the constraint to the solver.
|
||||||
|
--- Raises:
|
||||||
|
--- KiwiErrDuplicateConstraint: The given constraint has already been added to the solver.
|
||||||
|
--- KiwiErrUnsatisfiableConstraint: The given constraint is required and cannot be satisfied.
|
||||||
|
---@param solver kiwi.Solver
|
||||||
|
---@return kiwi.Constraint
|
||||||
|
function Constraint_cls:add_to(solver)
|
||||||
|
solver:add_constraints(self)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove the constraint from the solver.
|
||||||
|
--- Raises:
|
||||||
|
--- KiwiErrUnknownConstraint: The given constraint has not been added to the solver.
|
||||||
|
---@param solver kiwi.Solver
|
||||||
|
---@return kiwi.Constraint
|
||||||
|
function Constraint_cls:remove_from(solver)
|
||||||
|
solver:remove_constraints(self)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
local Constraint_mt = {
|
local Constraint_mt = {
|
||||||
__index = Constraint_cls,
|
__index = Constraint_cls,
|
||||||
}
|
}
|
||||||
@@ -818,8 +839,33 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
|
local bit = require("bit")
|
||||||
|
local band, bor, lshift = bit.band, bit.bor, bit.lshift
|
||||||
local C = ffi.C
|
local C = ffi.C
|
||||||
|
|
||||||
|
--- Produce a custom error raise mask
|
||||||
|
--- Error kinds specified in the mask will not cause a lua
|
||||||
|
--- error to be raised.
|
||||||
|
---@param kinds (kiwi.ErrKind|number)[]
|
||||||
|
---@param invert boolean?
|
||||||
|
---@return integer
|
||||||
|
function kiwi.error_mask(kinds, invert)
|
||||||
|
local mask = 0
|
||||||
|
for _, k in ipairs(kinds) do
|
||||||
|
mask = bor(mask, lshift(1, kiwi.ErrKind(k)))
|
||||||
|
end
|
||||||
|
return invert and bit.bnot(mask) or mask
|
||||||
|
end
|
||||||
|
|
||||||
|
kiwi.ERROR_MASK_ALL = 0xFFFF
|
||||||
|
--- an error mask that raises errors only for fatal conditions
|
||||||
|
kiwi.ERROR_MASK_NON_FATAL = bit.bnot(kiwi.error_mask({
|
||||||
|
"KiwiErrInternalSolverError",
|
||||||
|
"KiwiErrAlloc",
|
||||||
|
"KiwiErrNullObject",
|
||||||
|
"KiwiErrUnknown",
|
||||||
|
}))
|
||||||
|
|
||||||
---@class kiwi.KiwiErr: ffi.cdata*
|
---@class kiwi.KiwiErr: ffi.cdata*
|
||||||
---@field package kind kiwi.ErrKind
|
---@field package kind kiwi.ErrKind
|
||||||
---@field package message ffi.cdata*
|
---@field package message ffi.cdata*
|
||||||
@@ -828,8 +874,10 @@ do
|
|||||||
local KiwiErr = ffi.typeof("struct KiwiErr") --[[@as kiwi.KiwiErr]]
|
local KiwiErr = ffi.typeof("struct KiwiErr") --[[@as kiwi.KiwiErr]]
|
||||||
|
|
||||||
local Error_mt = {
|
local Error_mt = {
|
||||||
|
---@param self kiwi.Error
|
||||||
|
---@return string
|
||||||
__tostring = function(self)
|
__tostring = function(self)
|
||||||
return strformat("%s: (%s, %s)", self.message, self.solver, self.item)
|
return strformat("%s: (%s, %s)", self.message, tostring(self.solver), tostring(self.item))
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -851,9 +899,11 @@ do
|
|||||||
}, Error_mt)
|
}, Error_mt)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param f fun(solver: kiwi.Solver, item: any, ...): kiwi.KiwiErr?
|
---@generic T
|
||||||
|
---@param f fun(solver: kiwi.Solver, item: T, ...): kiwi.KiwiErr?
|
||||||
---@param solver kiwi.Solver
|
---@param solver kiwi.Solver
|
||||||
---@param item any
|
---@param item T
|
||||||
|
---@return T, kiwi.Error?
|
||||||
local function try_solver(f, solver, item, ...)
|
local function try_solver(f, solver, item, ...)
|
||||||
local err = f(solver, item, ...)
|
local err = f(solver, item, ...)
|
||||||
if err ~= nil then
|
if err ~= nil then
|
||||||
@@ -862,12 +912,17 @@ do
|
|||||||
if err.must_free then
|
if err.must_free then
|
||||||
C.free(err)
|
C.free(err)
|
||||||
end
|
end
|
||||||
error(new_error(kind, message, solver, item))
|
local errdata = new_error(kind, message, solver, item)
|
||||||
|
return item,
|
||||||
|
band(solver.error_mask, lshift(1, kind --[[@as integer]])) == 0 and error(errdata)
|
||||||
|
or errdata
|
||||||
end
|
end
|
||||||
|
return item
|
||||||
end
|
end
|
||||||
|
|
||||||
---@class kiwi.Solver: ffi.cdata*
|
---@class kiwi.Solver: ffi.cdata*
|
||||||
---@overload fun(): kiwi.Solver
|
---@field error_mask integer
|
||||||
|
---@overload fun(error_mask: integer?): kiwi.Solver
|
||||||
local Solver_cls = {
|
local Solver_cls = {
|
||||||
--- Test whether a constraint is in the solver.
|
--- Test whether a constraint is in the solver.
|
||||||
---@type fun(self: kiwi.Solver, constraint: kiwi.Constraint): boolean
|
---@type fun(self: kiwi.Solver, constraint: kiwi.Constraint): boolean
|
||||||
@@ -896,54 +951,133 @@ do
|
|||||||
dump = ckiwi.kiwi_solver_dump,
|
dump = ckiwi.kiwi_solver_dump,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Adds a constraint to the solver.
|
---@generic T
|
||||||
--- Raises
|
---@param solver kiwi.Solver
|
||||||
--- KiwiErrDuplicateConstraint: The given constraint has already been added to the solver.
|
---@param items T|T[]
|
||||||
--- KiwiErrUnsatisfiableConstraint: The given constraint is required and cannot be satisfied.
|
---@param f fun(solver: kiwi.Solver, item: T, ...): kiwi.KiwiErr?
|
||||||
|
---@return T|T[], kiwi.Error?
|
||||||
|
local function add_remove_items(solver, items, f, ...)
|
||||||
|
for _, item in ipairs(items) do
|
||||||
|
local _, err = try_solver(f, solver, item, ...)
|
||||||
|
if err ~= nil then
|
||||||
|
return items, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return items
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add a constraint to the solver.
|
||||||
|
--- Errors:
|
||||||
|
--- KiwiErrDuplicateConstraint
|
||||||
|
--- KiwiErrUnsatisfiableConstraint
|
||||||
---@param constraint kiwi.Constraint
|
---@param constraint kiwi.Constraint
|
||||||
|
---@return kiwi.Constraint constraint, kiwi.Error?
|
||||||
function Solver_cls:add_constraint(constraint)
|
function Solver_cls:add_constraint(constraint)
|
||||||
try_solver(ckiwi.kiwi_solver_add_constraint, self, constraint)
|
return try_solver(ckiwi.kiwi_solver_add_constraint, self, constraint)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Removes a constraint from the solver.
|
--- Add constraints to the solver.
|
||||||
--- Raises
|
--- Errors:
|
||||||
--- KiwiErrUnknownConstraint: The given constraint has not been added to the solver.
|
--- KiwiErrDuplicateConstraint
|
||||||
|
--- KiwiErrUnsatisfiableConstraint
|
||||||
|
---@param constraints kiwi.Constraint[]
|
||||||
|
---@return kiwi.Constraint[] constraints, kiwi.Error?
|
||||||
|
function Solver_cls:add_constraints(constraints)
|
||||||
|
return add_remove_items(self, constraints, ckiwi.kiwi_solver_add_constraint)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove a constraint from the solver.
|
||||||
|
--- Errors:
|
||||||
|
--- KiwiErrUnknownConstraint
|
||||||
---@param constraint kiwi.Constraint
|
---@param constraint kiwi.Constraint
|
||||||
|
---@return kiwi.Constraint constraint, kiwi.Error?
|
||||||
function Solver_cls:remove_constraint(constraint)
|
function Solver_cls:remove_constraint(constraint)
|
||||||
try_solver(ckiwi.kiwi_solver_remove_constraint, self, constraint)
|
return try_solver(ckiwi.kiwi_solver_remove_constraint, self, constraint)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Adds an edit variable to the solver.
|
--- Remove constraints from the solver.
|
||||||
|
--- Errors:
|
||||||
|
--- KiwiErrUnknownConstraint
|
||||||
|
---@param constraints kiwi.Constraint[]
|
||||||
|
---@return kiwi.Constraint[] constraints, kiwi.Error?
|
||||||
|
function Solver_cls:remove_constraints(constraints)
|
||||||
|
return add_remove_items(self, constraints, ckiwi.kiwi_solver_remove_constraint)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add an edit variables to the solver.
|
||||||
---
|
---
|
||||||
--- This method should be called before the `suggestValue` method is
|
--- This method should be called before the `suggestValue` method is
|
||||||
--- used to supply a suggested value for the given edit variable.
|
--- used to supply a suggested value for the given edit variable.
|
||||||
--- Raises
|
--- Errors:
|
||||||
--- KiwiErrDuplicateEditVariable: The given edit variable has already been added to the solver.
|
--- KiwiErrDuplicateEditVariable
|
||||||
--- KiwiErrBadRequiredStrength: The given strength is >= required.
|
--- KiwiErrBadRequiredStrength: The given strength is >= required.
|
||||||
---@param var kiwi.Var the variable to add as an edit variable
|
---@param var kiwi.Var the variable to add as an edit variable
|
||||||
---@param strength number the strength of the edit variable (must be less than `Strength.REQUIRED`)
|
---@param strength number the strength of the edit variable (must be less than `Strength.REQUIRED`)
|
||||||
|
---@return kiwi.Var var, kiwi.Error?
|
||||||
function Solver_cls:add_edit_var(var, strength)
|
function Solver_cls:add_edit_var(var, strength)
|
||||||
try_solver(ckiwi.kiwi_solver_add_edit_var, self, var, strength)
|
return try_solver(ckiwi.kiwi_solver_add_edit_var, self, var, strength)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add edit variables to the solver.
|
||||||
|
---
|
||||||
|
--- This method should be called before the `suggestValue` method is
|
||||||
|
--- used to supply a suggested value for the given edit variable.
|
||||||
|
--- Errors:
|
||||||
|
--- KiwiErrDuplicateEditVariable
|
||||||
|
--- KiwiErrBadRequiredStrength: The given strength is >= required.
|
||||||
|
---@param vars kiwi.Var[] the variables to add as an edit variable
|
||||||
|
---@param strength number the strength of the edit variables (must be less than `Strength.REQUIRED`)
|
||||||
|
---@return kiwi.Var[] vars, kiwi.Error?
|
||||||
|
function Solver_cls:add_edit_vars(vars, strength)
|
||||||
|
return add_remove_items(self, vars, ckiwi.kiwi_solver_add_edit_var, strength)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Remove an edit variable from the solver.
|
--- Remove an edit variable from the solver.
|
||||||
--- Raises
|
--- Raises:
|
||||||
--- KiwiErrUnknownEditVariable: The given edit variable has not been added to the solver
|
--- KiwiErrUnknownEditVariable
|
||||||
---@param var kiwi.Var the edit variable to remove
|
---@param var kiwi.Var the edit variable to remove
|
||||||
|
---@return kiwi.Var var, kiwi.Error?
|
||||||
function Solver_cls:remove_edit_var(var)
|
function Solver_cls:remove_edit_var(var)
|
||||||
try_solver(ckiwi.kiwi_solver_remove_edit_var, self, var)
|
return try_solver(ckiwi.kiwi_solver_remove_edit_var, self, var)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Removes edit variables from the solver.
|
||||||
|
--- Raises:
|
||||||
|
--- KiwiErrUnknownEditVariable
|
||||||
|
---@param vars kiwi.Var[] the edit variables to remove
|
||||||
|
---@return kiwi.Var[] vars, kiwi.Error?
|
||||||
|
function Solver_cls:remove_edit_vars(vars)
|
||||||
|
return add_remove_items(self, vars, ckiwi.kiwi_solver_remove_edit_var)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Suggest a value for the given edit variable.
|
--- Suggest a value for the given edit variable.
|
||||||
--- This method should be used after an edit variable has been added to the solver in order
|
--- This method should be used after an edit variable has been added to the solver in order
|
||||||
--- to suggest the value for that variable. After all suggestions have been made,
|
--- to suggest the value for that variable. After all suggestions have been made,
|
||||||
--- the `update_vars` methods can be used to update the values of the external solver variables.
|
--- the `update_vars` methods can be used to update the values of the external solver variables.
|
||||||
--- Raises
|
--- Raises:
|
||||||
--- KiwiErrUnknownEditVariable: The given edit variable has not been added to the solver.
|
--- KiwiErrUnknownEditVariable
|
||||||
---@param var kiwi.Var the edit variable to suggest a value for
|
---@param var kiwi.Var the edit variable to suggest a value for
|
||||||
---@param value number the suggested value
|
---@param value number the suggested value
|
||||||
|
---@return kiwi.Var var, kiwi.Error?
|
||||||
function Solver_cls:suggest_value(var, value)
|
function Solver_cls:suggest_value(var, value)
|
||||||
try_solver(ckiwi.kiwi_solver_suggest_value, self, var, value)
|
return try_solver(ckiwi.kiwi_solver_suggest_value, self, var, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Suggest values for the given edit variables.
|
||||||
|
--- Convenience wrapper of `suggest_value` that takes tables of `kiwi.Var` and number pairs.
|
||||||
|
--- Raises:
|
||||||
|
--- KiwiErrUnknownEditVariable: The given edit variable has not been added to the solver.
|
||||||
|
---@param vars kiwi.Var[] edit variables to suggest
|
||||||
|
---@param values number[] suggested values
|
||||||
|
---@return kiwi.Var[] vars, number[] values, kiwi.Error?
|
||||||
|
function Solver_cls:suggest_values(vars, values)
|
||||||
|
for i, var in ipairs(vars) do
|
||||||
|
local _, err = try_solver(ckiwi.kiwi_solver_suggest_value, self, var, values[i])
|
||||||
|
if err ~= nil then
|
||||||
|
return vars, values, err
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return vars, values
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Dump a representation of the solver to a string.
|
--- Dump a representation of the solver to a string.
|
||||||
@@ -956,12 +1090,15 @@ do
|
|||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
|
|
||||||
kiwi.Solver = ffi.metatype("struct KiwiSolver", {
|
local Solver_mt = {
|
||||||
__index = Solver_cls,
|
__index = Solver_cls,
|
||||||
__new = function(_)
|
}
|
||||||
return ffi_gc(ckiwi.kiwi_solver_new(), ckiwi.kiwi_solver_del)
|
|
||||||
end,
|
function Solver_mt:__new(error_mask)
|
||||||
}) --[[@as kiwi.Solver]]
|
return ffi_gc(ckiwi.kiwi_solver_new(error_mask or 0), ckiwi.kiwi_solver_del)
|
||||||
|
end
|
||||||
|
|
||||||
|
kiwi.Solver = ffi.metatype("struct KiwiSolver", Solver_mt) --[[@as kiwi.Solver]]
|
||||||
end
|
end
|
||||||
|
|
||||||
return kiwi
|
return kiwi
|
||||||
|
|||||||
Reference in New Issue
Block a user