Slightly more robust resource management
This commit is contained in:
@@ -1,10 +1,9 @@
|
|||||||
#include "ljkiwi.hpp"
|
|
||||||
#include "ckiwi.h"
|
#include "ckiwi.h"
|
||||||
|
|
||||||
#include <kiwi/kiwi.h>
|
#include <kiwi/kiwi.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -38,15 +37,18 @@ const KiwiErr* new_error(const KiwiErr* base, const std::exception& ex) {
|
|||||||
|
|
||||||
static const constexpr KiwiErr kKiwiErrUnhandledCxxException {
|
static const constexpr KiwiErr kKiwiErrUnhandledCxxException {
|
||||||
KiwiErrUnknown,
|
KiwiErrUnknown,
|
||||||
"An unhandled C++ exception occurred."};
|
"An unhandled C++ exception occurred."
|
||||||
|
};
|
||||||
|
|
||||||
static const constexpr KiwiErr kKiwiErrNullObjectArg0 {
|
static const constexpr KiwiErr kKiwiErrNullObjectArg0 {
|
||||||
KiwiErrNullObject,
|
KiwiErrNullObject,
|
||||||
"null object passed as argument #0 (self)"};
|
"null object passed as argument #0 (self)"
|
||||||
|
};
|
||||||
|
|
||||||
static const constexpr KiwiErr kKiwiErrNullObjectArg1 {
|
static const constexpr KiwiErr kKiwiErrNullObjectArg1 {
|
||||||
KiwiErrNullObject,
|
KiwiErrNullObject,
|
||||||
"null object passed as argument #1"};
|
"null object passed as argument #1"
|
||||||
|
};
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
const KiwiErr* wrap_err(F&& f) {
|
const KiwiErr* wrap_err(F&& f) {
|
||||||
@@ -55,42 +57,49 @@ const KiwiErr* wrap_err(F&& f) {
|
|||||||
} catch (const UnsatisfiableConstraint& ex) {
|
} catch (const UnsatisfiableConstraint& ex) {
|
||||||
static const constexpr KiwiErr err {
|
static const constexpr KiwiErr err {
|
||||||
KiwiErrUnsatisfiableConstraint,
|
KiwiErrUnsatisfiableConstraint,
|
||||||
"The constraint cannot be satisfied."};
|
"The constraint cannot be satisfied."
|
||||||
|
};
|
||||||
return &err;
|
return &err;
|
||||||
} catch (const UnknownConstraint& ex) {
|
} catch (const UnknownConstraint& ex) {
|
||||||
static const constexpr KiwiErr err {
|
static const constexpr KiwiErr err {
|
||||||
KiwiErrUnknownConstraint,
|
KiwiErrUnknownConstraint,
|
||||||
"The constraint has not been added to the solver."};
|
"The constraint has not been added to the solver."
|
||||||
|
};
|
||||||
return &err;
|
return &err;
|
||||||
|
|
||||||
} catch (const DuplicateConstraint& ex) {
|
} catch (const DuplicateConstraint& ex) {
|
||||||
static const constexpr KiwiErr err {
|
static const constexpr KiwiErr err {
|
||||||
KiwiErrDuplicateConstraint,
|
KiwiErrDuplicateConstraint,
|
||||||
"The constraint has already been added to the solver."};
|
"The constraint has already been added to the solver."
|
||||||
|
};
|
||||||
return &err;
|
return &err;
|
||||||
|
|
||||||
} catch (const UnknownEditVariable& ex) {
|
} catch (const UnknownEditVariable& ex) {
|
||||||
static const constexpr KiwiErr err {
|
static const constexpr KiwiErr err {
|
||||||
KiwiErrUnknownEditVariable,
|
KiwiErrUnknownEditVariable,
|
||||||
"The edit variable has not been added to the solver."};
|
"The edit variable has not been added to the solver."
|
||||||
|
};
|
||||||
return &err;
|
return &err;
|
||||||
|
|
||||||
} catch (const DuplicateEditVariable& ex) {
|
} catch (const DuplicateEditVariable& ex) {
|
||||||
static const constexpr KiwiErr err {
|
static const constexpr KiwiErr err {
|
||||||
KiwiErrDuplicateEditVariable,
|
KiwiErrDuplicateEditVariable,
|
||||||
"The edit variable has already been added to the solver."};
|
"The edit variable has already been added to the solver."
|
||||||
|
};
|
||||||
return &err;
|
return &err;
|
||||||
|
|
||||||
} catch (const BadRequiredStrength& ex) {
|
} catch (const BadRequiredStrength& ex) {
|
||||||
static const constexpr KiwiErr err {
|
static const constexpr KiwiErr err {
|
||||||
KiwiErrBadRequiredStrength,
|
KiwiErrBadRequiredStrength,
|
||||||
"A required strength cannot be used in this context."};
|
"A required strength cannot be used in this context."
|
||||||
|
};
|
||||||
return &err;
|
return &err;
|
||||||
|
|
||||||
} catch (const InternalSolverError& ex) {
|
} catch (const InternalSolverError& ex) {
|
||||||
static const constexpr KiwiErr base {
|
static const constexpr KiwiErr base {
|
||||||
KiwiErrInternalSolverError,
|
KiwiErrInternalSolverError,
|
||||||
"An internal solver error occurred."};
|
"An internal solver error occurred."
|
||||||
|
};
|
||||||
return new_error(&base, ex);
|
return new_error(&base, ex);
|
||||||
} catch (std::bad_alloc&) {
|
} catch (std::bad_alloc&) {
|
||||||
static const constexpr KiwiErr err {KiwiErrAlloc, "A memory allocation failed."};
|
static const constexpr KiwiErr err {KiwiErrAlloc, "A memory allocation failed."};
|
||||||
@@ -183,18 +192,19 @@ void kiwi_expression_retain(KiwiExpression* expr) {
|
|||||||
for (auto* t = expr->terms_; t != expr->terms_ + expr->term_count; ++t) {
|
for (auto* t = expr->terms_; t != expr->terms_ + expr->term_count; ++t) {
|
||||||
retain_unmanaged(t->var);
|
retain_unmanaged(t->var);
|
||||||
}
|
}
|
||||||
|
expr->owner = expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kiwi_expression_destroy(KiwiExpression* expr) {
|
void kiwi_expression_destroy(KiwiExpression* expr) {
|
||||||
if (lk_unlikely(!expr))
|
if (lk_unlikely(!expr || !expr->owner))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (expr->owner) {
|
if (expr->owner == expr) {
|
||||||
release_unmanaged(expr->owner);
|
|
||||||
} else {
|
|
||||||
for (auto* t = expr->terms_; t != expr->terms_ + expr->term_count; ++t) {
|
for (auto* t = expr->terms_; t != expr->terms_ + expr->term_count; ++t) {
|
||||||
release_unmanaged(t->var);
|
release_unmanaged(t->var);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
release_unmanaged(static_cast<ConstraintData*>(expr->owner));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +219,7 @@ KiwiConstraint* kiwi_constraint_construct(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Term> terms;
|
std::vector<Term> terms;
|
||||||
terms.reserve(static_cast<std::size_t>(
|
terms.reserve(static_cast<decltype(terms)::size_type>(
|
||||||
(lhs && lhs->term_count > 0 ? lhs->term_count : 0)
|
(lhs && lhs->term_count > 0 ? lhs->term_count : 0)
|
||||||
+ (rhs && rhs->term_count > 0 ? rhs->term_count : 0)
|
+ (rhs && rhs->term_count > 0 ? rhs->term_count : 0)
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ typedef struct KiwiTerm {
|
|||||||
typedef struct KiwiExpression {
|
typedef struct KiwiExpression {
|
||||||
double constant;
|
double constant;
|
||||||
int term_count;
|
int term_count;
|
||||||
KiwiConstraint* owner;
|
void* owner;
|
||||||
|
|
||||||
#if defined(LJKIWI_LUAJIT_DEF)
|
#if defined(LJKIWI_LUAJIT_DEF)
|
||||||
KiwiTerm terms_[?];
|
KiwiTerm terms_[?];
|
||||||
|
|||||||
10
kiwi.lua
10
kiwi.lua
@@ -53,7 +53,7 @@ typedef struct KiwiTerm {
|
|||||||
typedef struct KiwiExpression {
|
typedef struct KiwiExpression {
|
||||||
double constant;
|
double constant;
|
||||||
int term_count;
|
int term_count;
|
||||||
KiwiConstraint* owner;
|
void* owner;
|
||||||
|
|
||||||
KiwiTerm terms_[?];
|
KiwiTerm terms_[?];
|
||||||
} KiwiExpression;
|
} KiwiExpression;
|
||||||
@@ -227,7 +227,7 @@ local function new_expr_one(constant, var, coeff)
|
|||||||
dt.coefficient = coeff or 1.0
|
dt.coefficient = coeff or 1.0
|
||||||
ret.constant = constant
|
ret.constant = constant
|
||||||
ret.term_count = 1
|
ret.term_count = 1
|
||||||
ljkiwi.kiwi_var_retain(var)
|
ljkiwi.kiwi_expression_retain(ret)
|
||||||
return ret
|
return ret
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -500,9 +500,11 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
function Term_mt.__new(T, var, coefficient)
|
function Term_mt.__new(T, var, coefficient)
|
||||||
local t = ffi_new(T, var, coefficient or 1.0)
|
local t = ffi_gc(ffi_new(T), term_gc) --[[@as kiwi.Term]]
|
||||||
ljkiwi.kiwi_var_retain(var)
|
ljkiwi.kiwi_var_retain(var)
|
||||||
return ffi_gc(t, term_gc)
|
t.var = var
|
||||||
|
t.coefficient = coefficient or 1.0
|
||||||
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
function Term_mt.__mul(a, b)
|
function Term_mt.__mul(a, b)
|
||||||
|
|||||||
Reference in New Issue
Block a user