Skip to content

Commit

Permalink
controller zone support
Browse files Browse the repository at this point in the history
  • Loading branch information
ngwese committed Oct 3, 2021
1 parent 262a123 commit d370a3f
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 17 deletions.
2 changes: 1 addition & 1 deletion dep/soundplaneclient
Submodule soundplaneclient updated 5 files
+1 −1 src/Client.cpp
+11 −5 src/Zone.cpp
+1 −0 src/Zone.h
+32 −12 src/ZoneSpec.cpp
+17 −10 src/ZoneSpec.h
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ include_directories(${LIBLUA_INCLUDE_DIRS})
#
set(SOURCE_FILES
lua_common.cpp
SPNControlPool.cpp
SPNTouchPool.cpp
SPNOutput.cpp
spn_touch.cpp
Expand Down
16 changes: 16 additions & 0 deletions src/SPNControl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <MLSymbol.h>

struct SPNControl {
ml::Symbol name;
float x;
float y;
float z;
int n1;
int n2;

SPNControl(const ml::Symbol &name, float x, float y, float z, int n1,
int n2 = 0)
: name(name), x(x), y(y), z(z), n1(n1), n2(n2) {}
};
19 changes: 19 additions & 0 deletions src/SPNControlPool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "SPNControlPool.h"

#include <boost/pool/object_pool.hpp>
#include <mutex>

static std::mutex sPoolMutex;
static boost::object_pool<SPNControl> sPool{128 /* initial segment */,
512 /* max segment size */};

SPNControl *SPNControlPool::construct(const ml::Symbol &name, float x, float y,
float z, int n1, int n2) {
std::lock_guard<std::mutex> guard(sPoolMutex);
return sPool.construct(SPNControl(name, x, y, z, n1, n2));
}

void SPNControlPool::destroy(SPNControl *c) {
std::lock_guard<std::mutex> guard(sPoolMutex);
sPool.destroy(c);
}
10 changes: 10 additions & 0 deletions src/SPNControlPool.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include "SPNControl.h"

class SPNControlPool {
public:
static SPNControl *construct(const ml::Symbol &name, float x, float y,
float z, int n1, int n2 = 0);
static void destroy(SPNControl *c);
};
29 changes: 28 additions & 1 deletion src/SPNOutput.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@

#include "SPNOutput.h"
#include "SPNControl.h"
#include "SPNControlPool.h"
#include "SPNFrame.h"
#include "SPNTouch.h"
#include "SPNTouchPool.h"
Expand Down Expand Up @@ -64,6 +66,20 @@ static void spn_touch_weave_op(lua_State *lvm, void *value, void *context) {
SPNTouchPool::destroy(t);
}

static void spn_control_weave_op(lua_State *lvm, void *value, void *context) {
SPNControl *c = static_cast<SPNControl *>(value);
_push_module_func(lvm, "spn", "handlers", "control");
lua_pushstring(lvm, c->name.getUTF8Ptr());
lua_pushnumber(lvm, c->x);
lua_pushnumber(lvm, c->y);
lua_pushnumber(lvm, c->z);
lua_pushinteger(lvm, c->n1);
lua_pushinteger(lvm, c->n2);
lua_pcall(lvm, 6, 0,
0); // one argument, zero results, default error message
SPNControlPool::destroy(c);
}

static void spn_null_free_op(void *value, void *context) {}

static struct event_custom_ops spn_touch_ops = {
Expand All @@ -72,6 +88,12 @@ static struct event_custom_ops spn_touch_ops = {
.free = &spn_null_free_op,
};

static struct event_custom_ops spn_control_ops = {
.type_name = "spn_control",
.weave = &spn_control_weave_op,
.free = &spn_null_free_op,
};

static struct event_custom_ops spn_frame_begin_ops = {
.type_name = "spn_frame_begin",
.weave = &spn_frame_begin_weave_op,
Expand Down Expand Up @@ -108,7 +130,12 @@ void SPNOutput::processTouch(int i, int offset, const Touch &t) {

void SPNOutput::processController(int zoneID, int offset,
const ZoneMessage &m) {
// TODO:
if (m.active) {
SPNControl *value = SPNControlPool::construct(m.name, m.x, m.y, m.z,
m.number1, m.number2);
union event_data *ev = event_custom_new(&spn_control_ops, value, NULL);
event_post(ev);
}
}

void SPNOutput::endOutputFrame() {
Expand Down
127 changes: 112 additions & 15 deletions src/spn_zone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ static int spn_zone_name(lua_State *L);
static int spn_zone_base_note(lua_State *L);
static int spn_zone_bounds(lua_State *L);
static int spn_zone_type(lua_State *L);
static int spn_zone_control_numbers(lua_State *L);

static int spn_zone_build(lua_State *L);

Expand All @@ -30,6 +31,7 @@ static luaL_Reg spn_zone_methods[] = {
{"base_note", spn_zone_base_note},
{"bounds", spn_zone_bounds},
{"type", spn_zone_type},
{"control_numbers", spn_zone_control_numbers},
{NULL, NULL}
};

Expand Down Expand Up @@ -101,7 +103,7 @@ static int spn_zone_base_note(lua_State *L) {

static int spn_zone_bounds(lua_State *L) {
spn_zone_t *z = spn_zone_check(L, 1);
MLRect bounds = z->spec->getBounds();
const MLRect &bounds = z->spec->getBounds();
lua_newtable(L);
// x1
lua_pushnumber(L, bounds.left());
Expand All @@ -124,6 +126,20 @@ static int spn_zone_type(lua_State *L) {
return 1;
}

static int spn_zone_control_numbers(lua_State *L) {
spn_zone_t *z = spn_zone_check(L, 1);
lua_newtable(L);
lua_pushnumber(L, z->spec->getController1());
lua_seti(L, -2, 1);
// y1
lua_pushnumber(L, z->spec->getController2());
lua_seti(L, -2, 2);
// width
lua_pushnumber(L, z->spec->getController3());
lua_seti(L, -2, 3);
return 1;
}

//
// {
// name = "something",
Expand All @@ -136,7 +152,7 @@ static int spn_zone_build(lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);

// bounds
lua_getfield(L, -1, "bounds");
lua_getfield(L, 1, "bounds");
luaL_checktype(L, -1, LUA_TTABLE);

// x1
Expand All @@ -157,47 +173,128 @@ static int spn_zone_build(lua_State *L) {
uint8_t width = lua_tointeger(L, -1);
lua_pop(L, 1);

// y1
// height
lua_geti(L, -1, 4);
luaL_checktype(L, -1, LUA_TNUMBER);
uint8_t height = lua_tointeger(L, -1);
lua_pop(L, 1);

lua_pop(L, 1); // bounds table

// start_note (optional)
lua_getfield(L, -1, "start_note");
uint8_t start_note = 60;
if (lua_isinteger(L, -1)) {
start_note = lua_tointeger(L, -1);
}
lua_pop(L, 1);

// name
lua_getfield(L, -1, "name");
lua_getfield(L, 1, "name");
luaL_checktype(L, -1, LUA_TSTRING);
const char *zone_name = lua_tostring(L, -1);
// don't pop so name will remain valid

// type
lua_getfield(L, -2, "type");
lua_getfield(L, 1, "type");
luaL_checktype(L, -1, LUA_TSTRING);
const char *zone_type = lua_tostring(L, -1);

if (strcmp(zone_type, "note_row") == 0) {
// start_note (optional)
lua_getfield(L, 1, "start_note");
uint8_t start_note = 60;
if (lua_isinteger(L, -1)) {
start_note = lua_tointeger(L, -1);
}
lua_pop(L, 1);

// FIXME: this is ugly, first build the zone (copy 1) so that zone_name
// remains valid
auto spec = new soundplane::ZoneSpec();
*spec = soundplane::ZoneSpec::buildNoteRow(zone_name, x1, y1, width,
height, start_note);
// pop off type, name, and table arg
lua_pop(L, 3);
spn_zone_new(L, spec, true /* is_owner */);
return 1;

} else if (strcmp(zone_type, "toggle") == 0) {
uint8_t ctrl1 = 0;
lua_getfield(L, 1, "ctrl1");
if (lua_isinteger(L, -1)) {
ctrl1 = lua_tointeger(L, -1);
} else {
return luaL_error(L, "expected 'ctrl1' to be an integer");
}
lua_pop(L, 1);

auto spec = new soundplane::ZoneSpec();
*spec = soundplane::ZoneSpec::buildToggle(zone_name, x1, y1, width,
height, ctrl1);
// pop off type, name, and table arg
lua_pop(L, 3);
// push on new user data (copy 2)
spn_zone_new(L, spec, true /* is_owner */);
return 1;
}

// unhandled or unknown zone type
} else if (strcmp(zone_type, "xy") == 0) {
uint8_t ctrl1 = 0;
uint8_t ctrl2 = 0;

lua_getfield(L, 1, "ctrl1");
if (lua_isinteger(L, -1)) {
ctrl1 = lua_tointeger(L, -1);
} else {
return luaL_error(L, "expected 'ctrl1' to be an integer");
}
lua_pop(L, 1);

lua_getfield(L, 1, "ctrl2");
if (lua_isinteger(L, -1)) {
ctrl2 = lua_tointeger(L, -1);
} else {
return luaL_error(L, "expected 'ctrl2' to be an integer");
}
lua_pop(L, 1);

auto spec = new soundplane::ZoneSpec();
*spec = soundplane::ZoneSpec::buildXY(zone_name, x1, y1, width, height,
ctrl1, ctrl2);
// pop off type, name, and table arg
lua_pop(L, 3);
spn_zone_new(L, spec, true /* is_owner */);
return 1;

} else if (strcmp(zone_type, "x") == 0) {
uint8_t ctrl1 = 0;

lua_getfield(L, 1, "ctrl1");
if (lua_isinteger(L, -1)) {
ctrl1 = lua_tointeger(L, -1);
} else {
return luaL_error(L, "expected 'ctrl1' to be an integer");
}
lua_pop(L, 1);

auto spec = new soundplane::ZoneSpec();
*spec = soundplane::ZoneSpec::buildX(zone_name, x1, y1, width, height,
ctrl1);
// pop off type, name, and table arg
lua_pop(L, 3);
spn_zone_new(L, spec, true /* is_owner */);
return 1;
} else if (strcmp(zone_type, "y") == 0) {
uint8_t ctrl1 = 0;

lua_getfield(L, 1, "ctrl1");
if (lua_isinteger(L, -1)) {
ctrl1 = lua_tointeger(L, -1);
} else {
return luaL_error(L, "expected 'ctrl1' to be an integer");
}
lua_pop(L, 1);

auto spec = new soundplane::ZoneSpec();
*spec = soundplane::ZoneSpec::buildY(zone_name, x1, y1, width, height,
ctrl1);
// pop off type, name, and table arg
lua_pop(L, 3);
spn_zone_new(L, spec, true /* is_owner */);
return 1;
}

// pop off type, name, and table arg
lua_pop(L, 3);
Expand Down

0 comments on commit d370a3f

Please sign in to comment.