Browse Source

REST server-side messages working, add some stubs

tags/v1.9.11
falkTX 6 years ago
parent
commit
69d3c61bf7
7 changed files with 588 additions and 35 deletions
  1. +2
    -1
      source/carla_backend.py
  2. +332
    -23
      source/carla_backend_qtweb.py
  3. +1
    -1
      source/rest/Makefile
  4. +172
    -6
      source/rest/carla-host.cpp
  5. +2
    -0
      source/rest/common.hpp
  6. +75
    -2
      source/rest/rest-server.cpp
  7. +4
    -2
      source/utils/LinkedList.hpp

+ 2
- 1
source/carla_backend.py View File

@@ -1881,6 +1881,7 @@ class CarlaHostNull(CarlaHostMeta):
CarlaHostMeta.__init__(self)

self.fEngineCallback = None
self.fFileCallback = None
self.fEngineRunning = False

def get_engine_driver_count(self):
@@ -1923,7 +1924,7 @@ class CarlaHostNull(CarlaHostMeta):
return

def set_file_callback(self, func):
return
self.fFileCallback = func

def load_file(self, filename):
return False


+ 332
- 23
source/carla_backend_qtweb.py View File

@@ -26,6 +26,52 @@ import requests

from carla_backend_qt import *

import os
from time import sleep

# ---------------------------------------------------------------------------------------------------------------------
# Iterates over the content of a file-like object line-by-line.
# Based on code by Lars Kellogg-Stedman, see https://github.com/requests/requests/issues/2433

def iterate_stream_nonblock(stream, chunk_size=128):
pending = None

while True:
try:
chunk = os.read(stream.raw.fileno(), chunk_size)
except BlockingIOError:
break
if not chunk:
break

if pending is not None:
chunk = pending + chunk
pending = None

lines = chunk.splitlines()

if lines and lines[-1]:
pending = lines.pop()

for line in lines:
yield line

if not pending:
break

if pending:
yield pending

# ---------------------------------------------------------------------------------------------------------------------

def create_stream(baseurl):
stream = requests.get("{}/stream".format(baseurl), stream=True, timeout=0.1)

if stream.encoding is None:
stream.encoding = 'utf-8'

return stream

# ---------------------------------------------------------------------------------------------------------------------
# Carla Host object for connecting to the REST API

@@ -34,6 +80,7 @@ class CarlaHostQtWeb(CarlaHostQtNull):
CarlaHostQtNull.__init__(self)

self.baseurl = "http://localhost:2228"
self.stream = create_stream(self.baseurl)

def get_engine_driver_count(self):
# FIXME
@@ -49,33 +96,277 @@ class CarlaHostQtWeb(CarlaHostQtNull):
return requests.get("{}/get_engine_driver_device_info/{}/{}".format(self.baseurl, index, name)).json()

def engine_init(self, driverName, clientName):
resp = requests.get("{}/engine_init/{}/{}".format(self.baseurl, driverName, clientName)).status_code

# TESTING
if self.fEngineCallback is not None:
self.fEngineCallback(None, ENGINE_CALLBACK_ENGINE_STARTED, 0, self.processMode, self.transportMode, 0.0, driverName)

return resp == 200
return requests.get("{}/engine_init/{}/{}".format(self.baseurl, driverName, clientName)).status_code == 200

def engine_close(self):
# TESTING
if self.fEngineCallback is not None:
self.fEngineCallback(None, ENGINE_CALLBACK_ENGINE_STOPPED, 0, 0, 0, 0.0, "")

return requests.get("{}/engine_close".format(self.baseurl)).status_code == 200

def engine_idle(self):
requests.get("{}/engine_idle".format(self.baseurl))
closed = False
stream = self.stream

for line in iterate_stream_nonblock(stream):
line = line.decode('utf-8', errors='ignore')

if line.startswith("Carla: "):
if self.fEngineCallback is None:
continue

# split values from line
action, pluginId, value1, value2, value3, valueStr = line[7:].split(" ",5)

# convert to proper types
action = int(action)
pluginId = int(pluginId)
value1 = int(value1)
value2 = int(value2)
value3 = float(value3)

# pass to callback
self.fEngineCallback(None, action, pluginId, value1, value2, value3, valueStr)

elif line == "Connection: close":
closed = True

if closed:
self.stream = create_stream(self.baseurl)
stream.close()

def is_engine_running(self):
return requests.get("{}/is_engine_running".format(self.baseurl)).status_code == 200
try:
return requests.get("{}/is_engine_running".format(self.baseurl)).status_code == 200
except requests.exceptions.ConnectionError:
if self.fEngineCallback is None:
self.fEngineCallback(None, ENGINE_CALLBACK_QUIT, 0, 0, 0, 0.0, "")

def set_engine_about_to_close(self):
return requests.get("{}/set_engine_about_to_close".format(self.baseurl)).status_code == 200

def set_engine_option(self, option, value, valueStr):
return

def load_file(self, filename):
return False

def load_project(self, filename):
return False

def save_project(self, filename):
return False

def patchbay_connect(self, groupIdA, portIdA, groupIdB, portIdB):
return False

def patchbay_disconnect(self, connectionId):
return False

def patchbay_refresh(self, external):
return False

def transport_play(self):
return

def transport_pause(self):
return

def transport_bpm(self, bpm):
return

def transport_relocate(self, frame):
return

def get_current_transport_frame(self):
return 0

def get_transport_info(self):
return PyCarlaTransportInfo

def get_current_plugin_count(self):
return 0

def get_max_plugin_number(self):
return 0

def add_plugin(self, btype, ptype, filename, name, label, uniqueId, extraPtr, options):
return False

def remove_plugin(self, pluginId):
return False

def remove_all_plugins(self):
return False

def rename_plugin(self, pluginId, newName):
return ""

def clone_plugin(self, pluginId):
return False

def replace_plugin(self, pluginId):
return False

def switch_plugins(self, pluginIdA, pluginIdB):
return False

def load_plugin_state(self, pluginId, filename):
return False

def save_plugin_state(self, pluginId, filename):
return False

def export_plugin_lv2(self, pluginId, lv2path):
return False

def get_plugin_info(self, pluginId):
return PyCarlaPluginInfo

def get_audio_port_count_info(self, pluginId):
return PyCarlaPortCountInfo

def get_midi_port_count_info(self, pluginId):
return PyCarlaPortCountInfo

def get_parameter_count_info(self, pluginId):
return PyCarlaPortCountInfo

def get_parameter_info(self, pluginId, parameterId):
return PyCarlaParameterInfo

def get_parameter_scalepoint_info(self, pluginId, parameterId, scalePointId):
return PyCarlaScalePointInfo

def get_parameter_data(self, pluginId, parameterId):
return PyParameterData

def get_parameter_ranges(self, pluginId, parameterId):
return PyParameterRanges

def get_midi_program_data(self, pluginId, midiProgramId):
return PyMidiProgramData

def get_custom_data(self, pluginId, customDataId):
return PyCustomData

def get_chunk_data(self, pluginId):
return ""

def get_parameter_count(self, pluginId):
return 0

def get_program_count(self, pluginId):
return 0

def get_midi_program_count(self, pluginId):
return 0

def get_custom_data_count(self, pluginId):
return 0

def get_parameter_text(self, pluginId, parameterId):
return ""

def get_program_name(self, pluginId, programId):
return ""

def get_midi_program_name(self, pluginId, midiProgramId):
return ""

def get_real_plugin_name(self, pluginId):
return ""

def get_current_program_index(self, pluginId):
return 0

def get_current_midi_program_index(self, pluginId):
return 0

def get_default_parameter_value(self, pluginId, parameterId):
return 0.0

def get_current_parameter_value(self, pluginId, parameterId):
return 0.0

def get_internal_parameter_value(self, pluginId, parameterId):
return 0.0

def get_input_peak_value(self, pluginId, isLeft):
return 0.0

def get_output_peak_value(self, pluginId, isLeft):
return 0.0

def set_option(self, pluginId, option, yesNo):
return

def set_active(self, pluginId, onOff):
return

def set_drywet(self, pluginId, value):
return

def set_volume(self, pluginId, value):
return

def set_balance_left(self, pluginId, value):
return

def set_balance_right(self, pluginId, value):
return

def set_panning(self, pluginId, value):
return

def set_ctrl_channel(self, pluginId, channel):
return

def set_parameter_value(self, pluginId, parameterId, value):
return

def set_parameter_midi_channel(self, pluginId, parameterId, channel):
return

def set_parameter_midi_cc(self, pluginId, parameterId, cc):
return

def set_program(self, pluginId, programId):
return

def set_midi_program(self, pluginId, midiProgramId):
return

def set_custom_data(self, pluginId, type_, key, value):
return

def set_chunk_data(self, pluginId, chunkData):
return

def prepare_for_save(self, pluginId):
return

def reset_parameters(self, pluginId):
return

def randomize_parameters(self, pluginId):
return

def send_midi_note(self, pluginId, channel, note, velocity):
return

def get_buffer_size(self):
return 0

def get_sample_rate(self):
return 0.0

def get_last_error(self):
return requests.get("{}/get_last_error".format(self.baseurl)).text

def get_host_osc_url_tcp(self):
return ""

def get_host_osc_url_udp(self):
return ""

# ---------------------------------------------------------------------------------------------------------------------
# TESTING

@@ -83,18 +374,36 @@ if __name__ == '__main__':

baseurl = "http://localhost:2228"

driver_count = int(requests.get("{}/get_engine_driver_count".format(baseurl)).text)
#driver_count = int(requests.get("{}/get_engine_driver_count".format(baseurl)).text)

## FIXME
#driver_count -= 1

#print("Driver names:")
#for index in range(driver_count):
#print("\t -", requests.get("{}/get_engine_driver_name/{}".format(baseurl, index)).text)

#print("Driver device names:")
#for index in range(driver_count):
#for name in requests.get("{}/get_engine_driver_device_names/{}".format(baseurl, index)).text.split("\n"):
#print("\t {}:".format(name), requests.get("{}/get_engine_driver_device_info/{}/{}".format(baseurl, index, name)).json())

requests.get("{}/engine_close".format(baseurl)).status_code

if requests.get("{}/engine_init/{}/{}".format(baseurl, "JACK", "test")).status_code == 200:
stream = requests.get("{}/stream".format(baseurl), stream=True, timeout=0.25)
#stream.add_done_callback(cb)
#print(stream, dir(stream))

# FIXME
driver_count -= 1
#for line in stream.iter_lines():
#print("line", stream, line)

print("Driver names:")
for index in range(driver_count):
print("\t -", requests.get("{}/get_engine_driver_name/{}".format(baseurl, index)).text)
while True:
print("idle")
for line in iterate_stream_nonblock(stream):
print("line", line)
sleep(0.5)

print("Driver device names:")
for index in range(driver_count):
for name in requests.get("{}/get_engine_driver_device_names/{}".format(baseurl, index)).text.split("\n"):
print("\t {}:".format(name), requests.get("{}/get_engine_driver_device_info/{}/{}".format(baseurl, index, name)).json())
requests.get("{}/engine_close".format(baseurl)).status_code

# ---------------------------------------------------------------------------------------------------------------------

+ 1
- 1
source/rest/Makefile View File

@@ -23,7 +23,7 @@ endif

BUILD_CXX_FLAGS += -I$(CWD) -I$(CWD)/backend -I$(CWD)/includes -I$(CWD)/modules -I$(CWD)/utils

LINK_FLAGS += -L$(BINDIR) -lcarla_standalone2 -lcarla_utils -lrestbed -Wl,-rpath=$(shell realpath $(CWD)/../bin)
LINK_FLAGS += -L$(BINDIR) -lcarla_standalone2 -lcarla_utils -lrestbed -lpthread -Wl,-rpath=$(shell realpath $(CWD)/../bin)

# ----------------------------------------------------------------------------------------------------------------------



+ 172
- 6
source/rest/carla-host.cpp View File

@@ -18,6 +18,59 @@
#include "common.hpp"

#include "CarlaHost.h"
#include "CarlaBackendUtils.hpp"

// -------------------------------------------------------------------------------------------------------------------

static bool gEngineRunning = false;

void engine_idle_handler()
{
if (gEngineRunning)
carla_engine_idle();
}

// -------------------------------------------------------------------------------------------------------------------

static void EngineCallback(void* ptr, EngineCallbackOpcode action, uint pluginId, int value1, int value2, float value3, const char* valueStr)
{
carla_stdout("EngineCallback(%p, %u:%s, %u, %i, %i, %f, %s)",
ptr, (uint)action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valueStr);

char msgBuf[1024];
std::snprintf(msgBuf, 1023, "Carla: %u %u %i %i %f %s\n", action, pluginId, value1, value2, value3, valueStr);
msgBuf[1023] = '\0';

switch (action)
{
case ENGINE_CALLBACK_ENGINE_STARTED:
gEngineRunning = true;
break;
case ENGINE_CALLBACK_ENGINE_STOPPED:
case ENGINE_CALLBACK_QUIT:
gEngineRunning = false;
break;
default:
break;
}

send_server_side_message(msgBuf);
}

static const char* FileCallback(void* ptr, FileCallbackOpcode action, bool isDir, const char* title, const char* filter)
{
carla_stdout("FileCallback(%p, %u:%s, %s, %s, %s)",
ptr, (uint)action, FileCallbackOpcode(action), bool2str(isDir), title, filter);

char msgBuf[1024];
std::snprintf(msgBuf, 1023, "fc %u %i \"%s\" \"%s\"", action, isDir, title, filter);
msgBuf[1023] = '\0';

send_server_side_message(msgBuf);

// FIXME, need to wait for response!
return nullptr;
}

// -------------------------------------------------------------------------------------------------------------------

@@ -74,6 +127,11 @@ void handle_carla_get_engine_driver_device_info(const std::shared_ptr<Session> s

void handle_carla_engine_init(const std::shared_ptr<Session> session)
{
// setup callbacks
carla_set_engine_callback(EngineCallback, nullptr);
carla_set_file_callback(FileCallback, nullptr);

// handle request now
const std::shared_ptr<const Request> request = session->get_request();

const std::string driverName = request->get_path_parameter("driverName");
@@ -89,12 +147,6 @@ void handle_carla_engine_close(const std::shared_ptr<Session> session)
session->close(resp ? OK : BAD_REQUEST);
}

void handle_carla_engine_idle(const std::shared_ptr<Session> session)
{
carla_engine_idle();
session->close(OK);
}

void handle_carla_is_engine_running(const std::shared_ptr<Session> session)
{
const bool resp = carla_is_engine_running();
@@ -109,10 +161,124 @@ void handle_carla_set_engine_about_to_close(const std::shared_ptr<Session> sessi

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT void carla_set_engine_option(EngineOption option, int value, const char* valueStr);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT bool carla_load_file(const char* filename);
CARLA_EXPORT bool carla_load_project(const char* filename);
CARLA_EXPORT bool carla_save_project(const char* filename);
CARLA_EXPORT bool carla_patchbay_connect(uint groupIdA, uint portIdA, uint groupIdB, uint portIdB);
CARLA_EXPORT bool carla_patchbay_disconnect(uint connectionId);
CARLA_EXPORT bool carla_patchbay_refresh(bool external);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT void carla_transport_play();
CARLA_EXPORT void carla_transport_pause();
CARLA_EXPORT void carla_transport_bpm(double bpm);
CARLA_EXPORT void carla_transport_relocate(uint64_t frame);
CARLA_EXPORT uint64_t carla_get_current_transport_frame();
CARLA_EXPORT const CarlaTransportInfo* carla_get_transport_info();

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT uint32_t carla_get_current_plugin_count();
CARLA_EXPORT uint32_t carla_get_max_plugin_number();
CARLA_EXPORT bool carla_add_plugin(BinaryType btype, PluginType ptype,
const char* filename, const char* name, const char* label, int64_t uniqueId,
const void* extraPtr, uint options);
CARLA_EXPORT bool carla_remove_plugin(uint pluginId);
CARLA_EXPORT bool carla_remove_all_plugins();

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT const char* carla_rename_plugin(uint pluginId, const char* newName);
CARLA_EXPORT bool carla_clone_plugin(uint pluginId);
CARLA_EXPORT bool carla_replace_plugin(uint pluginId);
CARLA_EXPORT bool carla_switch_plugins(uint pluginIdA, uint pluginIdB);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT bool carla_load_plugin_state(uint pluginId, const char* filename);
CARLA_EXPORT bool carla_save_plugin_state(uint pluginId, const char* filename);
CARLA_EXPORT bool carla_export_plugin_lv2(uint pluginId, const char* lv2path);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT const CarlaPluginInfo* carla_get_plugin_info(uint pluginId);
CARLA_EXPORT const CarlaPortCountInfo* carla_get_audio_port_count_info(uint pluginId);
CARLA_EXPORT const CarlaPortCountInfo* carla_get_midi_port_count_info(uint pluginId);
CARLA_EXPORT const CarlaPortCountInfo* carla_get_parameter_count_info(uint pluginId);
CARLA_EXPORT const CarlaParameterInfo* carla_get_parameter_info(uint pluginId, uint32_t parameterId);
CARLA_EXPORT const CarlaScalePointInfo* carla_get_parameter_scalepoint_info(uint pluginId, uint32_t parameterId, uint32_t scalePointId);
CARLA_EXPORT const ParameterData* carla_get_parameter_data(uint pluginId, uint32_t parameterId);
CARLA_EXPORT const ParameterRanges* carla_get_parameter_ranges(uint pluginId, uint32_t parameterId);
CARLA_EXPORT const MidiProgramData* carla_get_midi_program_data(uint pluginId, uint32_t midiProgramId);
CARLA_EXPORT const CustomData* carla_get_custom_data(uint pluginId, uint32_t customDataId);
CARLA_EXPORT const char* carla_get_chunk_data(uint pluginId);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT uint32_t carla_get_parameter_count(uint pluginId);
CARLA_EXPORT uint32_t carla_get_program_count(uint pluginId);
CARLA_EXPORT uint32_t carla_get_midi_program_count(uint pluginId);
CARLA_EXPORT uint32_t carla_get_custom_data_count(uint pluginId);
CARLA_EXPORT const char* carla_get_parameter_text(uint pluginId, uint32_t parameterId);
CARLA_EXPORT const char* carla_get_program_name(uint pluginId, uint32_t programId);
CARLA_EXPORT const char* carla_get_midi_program_name(uint pluginId, uint32_t midiProgramId);
CARLA_EXPORT const char* carla_get_real_plugin_name(uint pluginId);
CARLA_EXPORT int32_t carla_get_current_program_index(uint pluginId);
CARLA_EXPORT int32_t carla_get_current_midi_program_index(uint pluginId);
CARLA_EXPORT float carla_get_default_parameter_value(uint pluginId, uint32_t parameterId);
CARLA_EXPORT float carla_get_current_parameter_value(uint pluginId, uint32_t parameterId);
CARLA_EXPORT float carla_get_internal_parameter_value(uint pluginId, int32_t parameterId);
CARLA_EXPORT float carla_get_input_peak_value(uint pluginId, bool isLeft);
CARLA_EXPORT float carla_get_output_peak_value(uint pluginId, bool isLeft);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT void carla_set_active(uint pluginId, bool onOff);
CARLA_EXPORT void carla_set_drywet(uint pluginId, float value);
CARLA_EXPORT void carla_set_volume(uint pluginId, float value);
CARLA_EXPORT void carla_set_balance_left(uint pluginId, float value);
CARLA_EXPORT void carla_set_balance_right(uint pluginId, float value);
CARLA_EXPORT void carla_set_panning(uint pluginId, float value);
CARLA_EXPORT void carla_set_ctrl_channel(uint pluginId, int8_t channel);
CARLA_EXPORT void carla_set_option(uint pluginId, uint option, bool yesNo);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT void carla_set_parameter_value(uint pluginId, uint32_t parameterId, float value);
CARLA_EXPORT void carla_set_parameter_midi_channel(uint pluginId, uint32_t parameterId, uint8_t channel);
CARLA_EXPORT void carla_set_parameter_midi_cc(uint pluginId, uint32_t parameterId, int16_t cc);
CARLA_EXPORT void carla_set_program(uint pluginId, uint32_t programId);
CARLA_EXPORT void carla_set_midi_program(uint pluginId, uint32_t midiProgramId);
CARLA_EXPORT void carla_set_custom_data(uint pluginId, const char* type, const char* key, const char* value);
CARLA_EXPORT void carla_set_chunk_data(uint pluginId, const char* chunkData);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT void carla_prepare_for_save(uint pluginId);
CARLA_EXPORT void carla_reset_parameters(uint pluginId);
CARLA_EXPORT void carla_randomize_parameters(uint pluginId);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT void carla_send_midi_note(uint pluginId, uint8_t channel, uint8_t note, uint8_t velocity);

// -------------------------------------------------------------------------------------------------------------------

CARLA_EXPORT uint32_t carla_get_buffer_size();
CARLA_EXPORT double carla_get_sample_rate();

void handle_carla_get_last_error(const std::shared_ptr<Session> session)
{
const char* const buf = carla_get_last_error();
session->close(OK, buf, { { "Content-Length", size_buf(buf) } } );
}

CARLA_EXPORT const char* carla_get_host_osc_url_tcp();
CARLA_EXPORT const char* carla_get_host_osc_url_udp();

// -------------------------------------------------------------------------------------------------------------------

+ 2
- 0
source/rest/common.hpp View File

@@ -35,4 +35,6 @@ using restbed::OK;

CARLA_BACKEND_USE_NAMESPACE;

void send_server_side_message(const char* const message);

#endif // REST_COMMON_HPP_INCLUDED

+ 75
- 2
source/rest/rest-server.cpp View File

@@ -26,9 +26,71 @@
#include "carla-host.cpp"
#include "carla-utils.cpp"

#include "CarlaMutex.hpp"
#include "CarlaStringList.hpp"

// -------------------------------------------------------------------------------------------------------------------

std::vector<std::shared_ptr<Session>> gSessions;

CarlaStringList gSessionMessages;
CarlaMutex gSessionMessagesMutex;

// -------------------------------------------------------------------------------------------------------------------

void send_server_side_message(const char* const message)
{
const CarlaMutexLocker cml(gSessionMessagesMutex);

gSessionMessages.append(message);
}

// -------------------------------------------------------------------------------------------------------------------

void make_resource(Service& service,
static void register_server_side_handler(const std::shared_ptr<Session> session)
{
const auto headers = std::multimap<std::string, std::string> {
{ "Connection", "keep-alive" },
{ "Cache-Control", "no-cache" },
{ "Content-Type", "text/event-stream" },
{ "Access-Control-Allow-Origin", "*" } //Only required for demo purposes.
};

session->yield(OK, headers, [](const std::shared_ptr<Session> rsession) {
gSessions.push_back(rsession);
});
}

static void event_stream_handler(void)
{
gSessions.erase(
std::remove_if(gSessions.begin(), gSessions.end(),
[](const std::shared_ptr<Session> &a) {
return a->is_closed();
}),
gSessions.end());

CarlaStringList messages;

{
const CarlaMutexLocker cml(gSessionMessagesMutex);

if (gSessionMessages.count() > 0)
gSessionMessages.moveTo(messages);
}

for (auto message : messages)
{
std::puts(message);

for (auto session : gSessions)
session->yield(OK, message);
}
}

// -------------------------------------------------------------------------------------------------------------------

static void make_resource(Service& service,
const char* const path,
const std::function<void (const std::shared_ptr<Session>)>& callback)
{
@@ -44,6 +106,14 @@ int main(int, const char**)
{
Service service;

// server-side messages
{
std::shared_ptr<Resource> resource = std::make_shared<Resource>();
resource->set_path("/stream");
resource->set_method_handler("GET", register_server_side_handler);
service.publish(resource);
}

// carla-host
make_resource(service, "/get_engine_driver_count", handle_carla_get_engine_driver_count);
make_resource(service, "/get_engine_driver_name/{index: .*}", handle_carla_get_engine_driver_name);
@@ -52,7 +122,6 @@ int main(int, const char**)

make_resource(service, "/engine_init/{driverName: .*}/{clientName: .*}", handle_carla_engine_init);
make_resource(service, "/engine_close", handle_carla_engine_close);
make_resource(service, "/engine_idle", handle_carla_engine_idle);
make_resource(service, "/is_engine_running", handle_carla_is_engine_running);
make_resource(service, "/set_engine_about_to_close", handle_carla_set_engine_about_to_close);

@@ -66,6 +135,10 @@ int main(int, const char**)
make_resource(service, "/get_cached_plugin_count/{ptype: .*}/{pluginPath: .*}", handle_carla_get_cached_plugin_count);
make_resource(service, "/get_cached_plugin_info/{ptype: .*}/{index: .*}", handle_carla_get_cached_plugin_info);

// schedule events
service.schedule(engine_idle_handler, std::chrono::milliseconds(33)); // ~30Hz
service.schedule(event_stream_handler, std::chrono::milliseconds(500));

std::shared_ptr<Settings> settings = std::make_shared<Settings>();
settings->set_port(2228);
settings->set_default_header("Connection", "close");


+ 4
- 2
source/utils/LinkedList.hpp View File

@@ -159,6 +159,7 @@ public:
return *this;
}

#if 0
T& operator*() noexcept
{
static T& fallback(_getFallback());
@@ -168,6 +169,7 @@ public:

return data->value;
}
#endif

const T& operator*() const noexcept
{
@@ -180,8 +182,8 @@ public:
}

private:
ListHead* fEntry;
ListHead* fEntry2;
const ListHead* fEntry;
const ListHead* fEntry2;

static T& _getFallback()
{


Loading…
Cancel
Save