Compare commits
5 Commits
2a71914ed8
...
lua-api-cp
| Author | SHA1 | Date | |
|---|---|---|---|
| 579d671a77 | |||
| 61ba76c5a3 | |||
| 8854c0edbe | |||
| 00a9fda814 | |||
| a8c1a10cab |
6
Makefile
6
Makefile
@@ -1,9 +1,9 @@
|
||||
SRCDIR := .
|
||||
CC := $(CROSS)gcc
|
||||
CFLAGS := -fPIC -Os
|
||||
CFLAGS := -fPIC -O3
|
||||
CXXFLAGS := -I$(SRCDIR)/kiwi -fno-rtti
|
||||
F_LTO := -flto=auto
|
||||
CXXFLAGS_EXTRA := -pedantic -std=c++14 -Wall $(F_LTO)
|
||||
#F_LTO := -flto=auto
|
||||
CXXFLAGS_EXTRA := -std=c++14 -Wall $(F_LTO) -fstrict-flex-arrays=3
|
||||
CFLAGS_EXTRA := -pedantic -std=c99 -Wall $(F_LTO)
|
||||
LIBFLAG := -shared
|
||||
LIB_EXT := so
|
||||
|
||||
2
build.bat
Normal file
2
build.bat
Normal file
@@ -0,0 +1,2 @@
|
||||
cl /nologo /O2 /W4 /wd4200 /c /D_CRT_SECURE_NO_DEPRECATE /I "C:\Program Files\luarocks\include" /EHs /I kiwi luakiwi\luakiwi.cpp
|
||||
link /DLL /out:ckiwi.dll /def:luakiwi.def /LIBPATH:"C:\Program Files\luarocks\lib" luakiwi.obj lua54.lib
|
||||
@@ -1,15 +1,15 @@
|
||||
rockspec_format = "3.0"
|
||||
package = "ljkiwi"
|
||||
package = "kiwi"
|
||||
version = "scm-1"
|
||||
source = {
|
||||
url = "git+https://github.com/jkl1337/ljkiwi",
|
||||
}
|
||||
description = {
|
||||
summary = "A LuaJIT FFI binding for the Kiwi constraint solver.",
|
||||
summary = "LuaJIT FFI and Lua binding for the Kiwi constraint solver.",
|
||||
detailed = [[
|
||||
ljkiwi is a LuaJIT FFI binding for the Kiwi constraint solver. Kiwi is a fast
|
||||
implementation of the Cassowary constraint solving algorithm. ljkiwi provides
|
||||
reasonably efficient bindings using the LuaJIT FFI.]],
|
||||
kiwi is a LuaJIT FFI and Lua binding for the Kiwi constraint solver. Kiwi is a fast
|
||||
implementation of the Cassowary constraint solving algorithm. kiwi provides
|
||||
reasonably efficient bindings using the LuaJIT FFI and convential Lua C bindings.]],
|
||||
license = "MIT",
|
||||
issues_url = "https://github.com/jkl1337/ljkiwi/issues",
|
||||
maintainer = "John Luebs",
|
||||
2
luakiwi.def
Normal file
2
luakiwi.def
Normal file
@@ -0,0 +1,2 @@
|
||||
EXPORTS
|
||||
luaopen_ckiwi
|
||||
@@ -4,21 +4,24 @@
|
||||
#include <kiwi/kiwi.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
|
||||
#include "luacompat.h"
|
||||
|
||||
#define ARR_COUNT(x) ((int)(sizeof(x) / sizeof((x)[0])))
|
||||
|
||||
#if defined(__GNUC__) && !defined(LKIWI_NO_BUILTIN)
|
||||
#define l_likely(x) (__builtin_expect(((x) != 0), 1))
|
||||
#define l_unlikely(x) (__builtin_expect(((x) != 0), 0))
|
||||
#define lk_likely(x) (__builtin_expect(((x) != 0), 1))
|
||||
#define lk_unlikely(x) (__builtin_expect(((x) != 0), 0))
|
||||
#else
|
||||
#define l_likely(x) (x)
|
||||
#define l_unlikely(x) (x)
|
||||
#define lk_likely(x) (x)
|
||||
#define lk_unlikely(x) (x)
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace kiwi;
|
||||
|
||||
// Lua 5.1 compatibility for missing lua_arith.
|
||||
static void compat_arith_unm(lua_State* L) {
|
||||
inline void compat_arith_unm(lua_State* L) {
|
||||
#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501
|
||||
lua_Number n = lua_tonumber(L, -1);
|
||||
if (n != 0 || lua_isnumber(L, -1)) {
|
||||
@@ -35,14 +38,13 @@ static void compat_arith_unm(lua_State* L) {
|
||||
}
|
||||
|
||||
// This version supports placeholders.
|
||||
static void setfuncs(lua_State* L, const luaL_Reg* l, int nup) {
|
||||
inline void setfuncs(lua_State* L, const luaL_Reg* l, int nup) {
|
||||
luaL_checkstack(L, nup, "too many upvalues");
|
||||
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
||||
if (l->func == NULL) /* place holder? */
|
||||
lua_pushboolean(L, 0);
|
||||
else {
|
||||
int i;
|
||||
for (i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||
for (int i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||
lua_pushvalue(L, -nup);
|
||||
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
|
||||
}
|
||||
@@ -51,11 +53,15 @@ static void setfuncs(lua_State* L, const luaL_Reg* l, int nup) {
|
||||
lua_pop(L, nup); /* remove upvalues */
|
||||
}
|
||||
|
||||
#define newlib(L, l) (lua_newtable((L)), setfuncs((L), (l), 0))
|
||||
template<typename T, std::size_t N>
|
||||
constexpr int array_count(T (&)[N]) {
|
||||
return static_cast<int>(N);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace kiwi;
|
||||
void newlib(lua_State* L, const luaL_Reg* l) {
|
||||
lua_newtable(L);
|
||||
setfuncs(L, l, 0);
|
||||
}
|
||||
|
||||
enum KiwiErrKind {
|
||||
KiwiErrNone,
|
||||
@@ -80,15 +86,32 @@ struct KiwiExpression {
|
||||
double constant;
|
||||
int term_count;
|
||||
Constraint* owner;
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
KiwiTerm terms[];
|
||||
|
||||
static constexpr std::size_t sz(int count) {
|
||||
return sizeof(KiwiExpression) + sizeof(KiwiTerm) * (count > 0 ? count : 0);
|
||||
}
|
||||
#else
|
||||
KiwiTerm terms[1];
|
||||
|
||||
static constexpr std::size_t sz(int count) {
|
||||
return sizeof(KiwiExpression) + sizeof(KiwiTerm) * (count > 1 ? count - 1 : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
KiwiExpression() = delete;
|
||||
KiwiExpression(const KiwiExpression&) = delete;
|
||||
KiwiExpression& operator=(const KiwiExpression&) = delete;
|
||||
~KiwiExpression() = delete;
|
||||
};
|
||||
|
||||
// This structure was initially designed for LuaJIT FFI. It works OK for C++
|
||||
// though it certainly isn't idiomatic.
|
||||
// This mechanism was initially designed for LuaJIT FFI.
|
||||
struct KiwiErr {
|
||||
enum KiwiErrKind kind;
|
||||
const char* message;
|
||||
bool must_free;
|
||||
bool must_delete;
|
||||
};
|
||||
|
||||
struct KiwiSolver {
|
||||
@@ -96,60 +119,59 @@ struct KiwiSolver {
|
||||
Solver solver;
|
||||
};
|
||||
|
||||
const KiwiErr* new_error(const KiwiErr* base, const std::exception& ex) {
|
||||
inline const KiwiErr* new_error(const KiwiErr* base, const std::exception& ex) {
|
||||
if (!std::strcmp(ex.what(), base->message))
|
||||
return base;
|
||||
|
||||
const auto msg_n = std::strlen(ex.what()) + 1;
|
||||
|
||||
auto* mem = static_cast<char*>(std::malloc(sizeof(KiwiErr) + msg_n));
|
||||
auto* mem = static_cast<char*>(::operator new(sizeof(KiwiErr) + msg_n, std::nothrow));
|
||||
if (!mem) {
|
||||
return base;
|
||||
}
|
||||
|
||||
const auto* err = new (mem) KiwiErr {base->kind, mem + sizeof(KiwiErr), true};
|
||||
std::memcpy(const_cast<char*>(err->message), ex.what(), msg_n);
|
||||
return err;
|
||||
auto* msg = mem + sizeof(KiwiErr);
|
||||
std::memcpy(msg, ex.what(), msg_n);
|
||||
return new (mem) KiwiErr {base->kind, msg, true};
|
||||
}
|
||||
|
||||
const constexpr KiwiErr kKiwiErrUnhandledCxxException {
|
||||
KiwiErrUnknown,
|
||||
"An unhandled C++ exception occurred."};
|
||||
|
||||
template<typename F>
|
||||
inline const KiwiErr* wrap_err(F&& f) {
|
||||
static const constexpr KiwiErr kKiwiErrUnhandledCxxException {
|
||||
KiwiErrUnknown,
|
||||
"An unhandled C++ exception occurred."};
|
||||
|
||||
try {
|
||||
f();
|
||||
} catch (const UnsatisfiableConstraint& ex) {
|
||||
} catch (const UnsatisfiableConstraint&) {
|
||||
static const constexpr KiwiErr err {
|
||||
KiwiErrUnsatisfiableConstraint,
|
||||
"The constraint cannot be satisfied."};
|
||||
return &err;
|
||||
} catch (const UnknownConstraint& ex) {
|
||||
} catch (const UnknownConstraint&) {
|
||||
static const constexpr KiwiErr err {
|
||||
KiwiErrUnknownConstraint,
|
||||
"The constraint has not been added to the solver."};
|
||||
return &err;
|
||||
|
||||
} catch (const DuplicateConstraint& ex) {
|
||||
} catch (const DuplicateConstraint&) {
|
||||
static const constexpr KiwiErr err {
|
||||
KiwiErrDuplicateConstraint,
|
||||
"The constraint has already been added to the solver."};
|
||||
return &err;
|
||||
|
||||
} catch (const UnknownEditVariable& ex) {
|
||||
} catch (const UnknownEditVariable&) {
|
||||
static const constexpr KiwiErr err {
|
||||
KiwiErrUnknownEditVariable,
|
||||
"The edit variable has not been added to the solver."};
|
||||
return &err;
|
||||
|
||||
} catch (const DuplicateEditVariable& ex) {
|
||||
} catch (const DuplicateEditVariable&) {
|
||||
static const constexpr KiwiErr err {
|
||||
KiwiErrDuplicateEditVariable,
|
||||
"The edit variable has already been added to the solver."};
|
||||
return &err;
|
||||
|
||||
} catch (const BadRequiredStrength& ex) {
|
||||
} catch (const BadRequiredStrength&) {
|
||||
static const constexpr KiwiErr err {
|
||||
KiwiErrBadRequiredStrength,
|
||||
"A required strength cannot be used in this context."};
|
||||
@@ -193,12 +215,12 @@ inline Constraint* kiwi_constraint_retain(Constraint* c) {
|
||||
return c;
|
||||
}
|
||||
|
||||
inline void kiwi_constraint_new(
|
||||
inline Constraint* kiwi_constraint_new(
|
||||
const KiwiExpression* lhs,
|
||||
const KiwiExpression* rhs,
|
||||
RelationalOperator op,
|
||||
double strength,
|
||||
Constraint* mem
|
||||
void* mem
|
||||
) {
|
||||
if (strength < 0.0) {
|
||||
strength = kiwi::strength::required;
|
||||
@@ -217,7 +239,7 @@ inline void kiwi_constraint_new(
|
||||
terms.emplace_back(*t->var, -t->coefficient);
|
||||
}
|
||||
}
|
||||
new (mem) Constraint(
|
||||
return new (mem) Constraint(
|
||||
Expression(std::move(terms), (lhs ? lhs->constant : 0.0) - (rhs ? rhs->constant : 0.0)),
|
||||
static_cast<RelationalOperator>(op),
|
||||
strength
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
12
t.lua
12
t.lua
@@ -8,14 +8,16 @@ do
|
||||
local v3 = kiwi.Var("v3")
|
||||
local v4 = kiwi.Var("v4")
|
||||
local v5 = kiwi.Var("v5")
|
||||
local c = (3 * v1 + 4 * v2 + 6 * v3):eq(0)
|
||||
local c1 = (3 * v1 + 4 * v2 + 6 * v3):eq(0)
|
||||
local c2 = (6 * v4 + 4 * v5 + 2 * v1 + 1.4 * v1 / 0.3):le(1000)
|
||||
|
||||
local e = c:expression()
|
||||
print(e)
|
||||
local e = c1:expression()
|
||||
local s = kiwi.Solver()
|
||||
|
||||
s:add_constraints({ c1, c2, c1 })
|
||||
print(s:dumps())
|
||||
end
|
||||
|
||||
collectgarbage("collect")
|
||||
collectgarbage("collect")
|
||||
-- c = (3 * v1 + 4 * v2 + 6 * v3):eq(0)
|
||||
|
||||
-- local t = c:expression():terms()
|
||||
|
||||
Reference in New Issue
Block a user