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;
|
||||
}
|
||||
|
||||
KiwiSolver* kiwi_solver_new() {
|
||||
return reinterpret_cast<KiwiSolver*>(new Solver());
|
||||
struct KiwiSolver {
|
||||
unsigned error_mask;
|
||||
Solver solver;
|
||||
};
|
||||
|
||||
KiwiSolver* kiwi_solver_new(unsigned error_mask) {
|
||||
return new KiwiSolver {error_mask};
|
||||
}
|
||||
|
||||
void kiwi_solver_del(KiwiSolver* sp) {
|
||||
auto* solver = reinterpret_cast<Solver*>(sp);
|
||||
if (solver)
|
||||
delete solver;
|
||||
void kiwi_solver_del(KiwiSolver* s) {
|
||||
if (s)
|
||||
delete s;
|
||||
}
|
||||
|
||||
const KiwiErr* kiwi_solver_add_constraint(KiwiSolver* s, KiwiConstraintRef constraint) {
|
||||
return wrap_err(
|
||||
reinterpret_cast<Solver*>(s),
|
||||
ConstraintRef(constraint),
|
||||
[](auto solver, const auto c) { solver->addConstraint(c); }
|
||||
);
|
||||
return wrap_err(s, ConstraintRef(constraint), [](auto* s, const auto c) {
|
||||
s->solver.addConstraint(c);
|
||||
});
|
||||
}
|
||||
|
||||
const KiwiErr* kiwi_solver_remove_constraint(KiwiSolver* s, KiwiConstraintRef constraint) {
|
||||
return wrap_err(
|
||||
reinterpret_cast<Solver*>(s),
|
||||
ConstraintRef(constraint),
|
||||
[](auto solver, const auto c) { solver->removeConstraint(c); }
|
||||
);
|
||||
return wrap_err(s, ConstraintRef(constraint), [](auto* s, const auto c) {
|
||||
s->solver.removeConstraint(c);
|
||||
});
|
||||
}
|
||||
|
||||
bool kiwi_solver_has_constraint(const KiwiSolver* s, KiwiConstraintRef constraint) {
|
||||
const auto* solver = reinterpret_cast<const Solver*>(s);
|
||||
ConstraintRef c(constraint);
|
||||
if (!solver || !c)
|
||||
if (!s || !c)
|
||||
return 0;
|
||||
return solver->hasConstraint(c);
|
||||
return s->solver.hasConstraint(c);
|
||||
}
|
||||
|
||||
const KiwiErr* kiwi_solver_add_edit_var(KiwiSolver* s, KiwiVarRef var, double strength) {
|
||||
return wrap_err(
|
||||
reinterpret_cast<Solver*>(s),
|
||||
VariableRef(var),
|
||||
[strength](auto solver, const auto v) { solver->addEditVariable(v, strength); }
|
||||
);
|
||||
return wrap_err(s, VariableRef(var), [strength](auto* s, const auto v) {
|
||||
s->solver.addEditVariable(v, strength);
|
||||
});
|
||||
}
|
||||
|
||||
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) {
|
||||
solver->removeEditVariable(v);
|
||||
return wrap_err(s, VariableRef(var), [](auto* s, const auto v) {
|
||||
s->solver.removeEditVariable(v);
|
||||
});
|
||||
}
|
||||
|
||||
bool kiwi_solver_has_edit_var(const KiwiSolver* s, KiwiVarRef var) {
|
||||
const auto* solver = reinterpret_cast<const Solver*>(s);
|
||||
VariableRef v(var);
|
||||
if (!solver || !v)
|
||||
if (!s || !v)
|
||||
return 0;
|
||||
return solver->hasEditVariable(v);
|
||||
return s->solver.hasEditVariable(v);
|
||||
}
|
||||
|
||||
const KiwiErr* kiwi_solver_suggest_value(KiwiSolver* s, KiwiVarRef var, double value) {
|
||||
return wrap_err(
|
||||
reinterpret_cast<Solver*>(s),
|
||||
VariableRef(var),
|
||||
|
||||
[value](auto solver, const auto v) { solver->suggestValue(v, value); }
|
||||
);
|
||||
return wrap_err(s, VariableRef(var), [value](auto* s, const auto v) {
|
||||
s->solver.suggestValue(v, value);
|
||||
});
|
||||
}
|
||||
|
||||
void kiwi_solver_update_vars(KiwiSolver* s) {
|
||||
auto* solver = reinterpret_cast<Solver*>(s);
|
||||
if (solver)
|
||||
solver->updateVariables();
|
||||
if (s)
|
||||
s->solver.updateVariables();
|
||||
}
|
||||
|
||||
void kiwi_solver_reset(KiwiSolver* s) {
|
||||
auto* solver = reinterpret_cast<Solver*>(s);
|
||||
if (solver)
|
||||
solver->reset();
|
||||
if (s)
|
||||
s->solver.reset();
|
||||
}
|
||||
|
||||
void kiwi_solver_dump(const KiwiSolver* s) {
|
||||
auto* solver = reinterpret_cast<const Solver*>(s);
|
||||
if (solver)
|
||||
solver->dump();
|
||||
if (s)
|
||||
s->solver.dump();
|
||||
}
|
||||
|
||||
char* kiwi_solver_dumps(const KiwiSolver* s) {
|
||||
auto* solver = reinterpret_cast<const Solver*>(s);
|
||||
if (!solver)
|
||||
if (!s)
|
||||
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;
|
||||
auto* buf = static_cast<char*>(std::malloc(buf_size));
|
||||
if (!buf)
|
||||
|
||||
Reference in New Issue
Block a user