2024-03-23 18:41:26 -07:00
|
|
|
#include "dbus.hpp"
|
|
|
|
#include "log.hpp"
|
|
|
|
const char *DBusAPI::serviceName = "com.experimentalcraft.looper";
|
|
|
|
const char *DBusAPI::objectPath = "/com/experimentalcraft/looper";
|
|
|
|
const char *DBusAPI::interfaceName = "com.experimentalcraft.Looper";
|
|
|
|
DBusAPI::DBusAPI(Playback *playback) {
|
|
|
|
this->playback = playback;
|
|
|
|
connection = sdbus::createSessionBusConnection(serviceName);
|
|
|
|
api = sdbus::createObject(*connection, objectPath);
|
|
|
|
api->registerMethod(interfaceName, "open", "s", "", [this](sdbus::MethodCall call) {
|
|
|
|
std::string filePath;
|
|
|
|
call >> filePath;
|
|
|
|
this->playback->Start(filePath);
|
|
|
|
});
|
2024-03-26 18:39:02 -07:00
|
|
|
api->registerSignal(interfaceName, "playbackEngineStarted", "");
|
|
|
|
api->registerSignal(interfaceName, "speedChanged", "d");
|
|
|
|
api->registerSignal(interfaceName, "tempoChanged", "d");
|
|
|
|
api->registerSignal(interfaceName, "pitchChanged", "d");
|
|
|
|
api->registerSignal(interfaceName, "pauseChanged", "b");
|
|
|
|
api->registerSignal(interfaceName, "stopped", "");
|
|
|
|
api->registerSignal(interfaceName, "errorOccurred", "s");
|
|
|
|
api->registerSignal(interfaceName, "seeked", "d");
|
|
|
|
api->registerSignal(interfaceName, "fileChanged", "s");
|
|
|
|
api->registerProperty(interfaceName, "speed", "d", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
reply << this->playback->GetSpeed();
|
|
|
|
}, [this](sdbus::PropertySetCall set_call) {
|
2024-03-23 18:41:26 -07:00
|
|
|
double newValue;
|
2024-03-26 18:39:02 -07:00
|
|
|
set_call >> newValue;
|
|
|
|
this->playback->SetSpeed(newValue);
|
2024-03-23 18:41:26 -07:00
|
|
|
});
|
2024-03-26 18:39:02 -07:00
|
|
|
api->registerProperty(interfaceName, "tempo", "d", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
reply << this->playback->GetTempo();
|
|
|
|
}, [this](sdbus::PropertySetCall set_call) {
|
2024-03-23 18:41:26 -07:00
|
|
|
double newValue;
|
2024-03-26 18:39:02 -07:00
|
|
|
set_call >> newValue;
|
|
|
|
this->playback->SetTempo(newValue);
|
2024-03-23 18:41:26 -07:00
|
|
|
});
|
2024-03-26 18:39:02 -07:00
|
|
|
api->registerProperty(interfaceName, "pitch", "d", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
reply << this->playback->GetPitch();
|
|
|
|
}, [this](sdbus::PropertySetCall set_call) {
|
2024-03-23 18:41:26 -07:00
|
|
|
double newValue;
|
2024-03-26 18:39:02 -07:00
|
|
|
set_call >> newValue;
|
|
|
|
this->playback->SetPitch(newValue);
|
|
|
|
});
|
|
|
|
api->registerProperty(interfaceName, "volume", "d", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
reply << this->playback->GetVolume();
|
|
|
|
}, [this](sdbus::PropertySetCall set_call) {
|
|
|
|
double newValue;
|
|
|
|
set_call >> newValue;
|
|
|
|
this->playback->SetVolume(newValue);
|
|
|
|
});
|
|
|
|
api->registerMethod(interfaceName, "stop", "", "", [this](sdbus::MethodCall call) {
|
|
|
|
this->playback->Stop();
|
|
|
|
});
|
|
|
|
api->registerMethod(interfaceName, "togglePause", "", "", [this](sdbus::MethodCall call) {
|
|
|
|
this->playback->Pause();
|
|
|
|
});
|
|
|
|
api->registerProperty(interfaceName, "paused", "b", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
reply << this->playback->IsPaused();
|
|
|
|
}, [this](sdbus::PropertySetCall call) {
|
|
|
|
bool shouldBePaused;
|
|
|
|
call >> shouldBePaused;
|
|
|
|
this->playback->SetPaused(shouldBePaused);
|
|
|
|
});
|
|
|
|
api->registerProperty(interfaceName, "stopped", "b", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
reply << this->playback->IsStopped();
|
|
|
|
});
|
|
|
|
api->registerMethod(interfaceName, "errorExists", "", "b", [this](sdbus::MethodCall call) {
|
|
|
|
auto reply = call.createReply();
|
|
|
|
reply << this->playback->ErrorExists();
|
|
|
|
});
|
|
|
|
api->registerMethod(interfaceName, "getLastError", "", "s", [this](sdbus::MethodCall call) {
|
|
|
|
auto error = this->playback->GetError();
|
|
|
|
if (error.has_value()) {
|
|
|
|
auto reply = call.createReply();
|
|
|
|
reply << error.value();
|
|
|
|
} else {
|
|
|
|
auto errorReply = call.createErrorReply(sdbus::createError(0, "No error found."));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
api->registerProperty(interfaceName, "position", "d", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
reply << this->playback->GetPosition();
|
|
|
|
}, [this](sdbus::PropertySetCall call) {
|
|
|
|
double value;
|
|
|
|
call >> value;
|
|
|
|
this->playback->Seek(value);
|
|
|
|
});
|
|
|
|
api->registerProperty(interfaceName, "length", "d", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
reply << this->playback->GetLength();
|
|
|
|
});
|
|
|
|
api->registerProperty(interfaceName, "current_file_path", "s", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
auto file_maybe = this->playback->get_current_file();
|
|
|
|
if (file_maybe.has_value()) {
|
|
|
|
reply << file_maybe.value();
|
|
|
|
} else {
|
|
|
|
reply << "";
|
|
|
|
}
|
|
|
|
});
|
|
|
|
api->registerProperty(interfaceName, "current_file_title", "s", [this](sdbus::PropertyGetReply reply) {
|
|
|
|
auto title_maybe = this->playback->get_current_title();
|
|
|
|
if (title_maybe.has_value()) {
|
|
|
|
reply << title_maybe.value();
|
|
|
|
} else {
|
|
|
|
reply << "";
|
|
|
|
}
|
2024-03-23 18:41:26 -07:00
|
|
|
});
|
|
|
|
api->finishRegistration();
|
|
|
|
connection->enterEventLoopAsync();
|
|
|
|
}
|
|
|
|
bool DBusAPISender::isOnlyInstance() {
|
|
|
|
return !connected;
|
|
|
|
}
|
|
|
|
void DBusAPISender::playFile(std::string file) {
|
|
|
|
if (connected) {
|
|
|
|
auto method = proxy->createMethodCall(DBusAPI::interfaceName, "open");
|
|
|
|
method.dontExpectReply();
|
|
|
|
method << file;
|
|
|
|
proxy->callMethod(method);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void DBusAPISender::setPitch(double value) {
|
|
|
|
if (connected) {
|
2024-03-26 18:39:02 -07:00
|
|
|
proxy->setProperty("pitch").onInterface(DBusAPI::interfaceName).toValue(value);
|
2024-03-23 18:41:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
void DBusAPISender::setSpeed(double value) {
|
|
|
|
if (connected) {
|
2024-03-26 18:39:02 -07:00
|
|
|
proxy->setProperty("speed").onInterface(DBusAPI::interfaceName).toValue(value);
|
2024-03-23 18:41:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
void DBusAPISender::setTempo(double value) {
|
|
|
|
if (connected) {
|
2024-03-26 18:39:02 -07:00
|
|
|
proxy->setProperty("tempo").onInterface(DBusAPI::interfaceName).toValue(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
double DBusAPISender::getPitch() {
|
|
|
|
if (connected) {
|
|
|
|
return proxy->getProperty("pitch").onInterface(DBusAPI::interfaceName);
|
|
|
|
} else {
|
|
|
|
return -1.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
double DBusAPISender::getTempo() {
|
|
|
|
if (connected) {
|
|
|
|
return proxy->getProperty("tempo").onInterface(DBusAPI::interfaceName);
|
|
|
|
} else {
|
|
|
|
return -1.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
double DBusAPISender::getSpeed() {
|
|
|
|
if (connected) {
|
|
|
|
return proxy->getProperty("speed").onInterface(DBusAPI::interfaceName);
|
|
|
|
} else {
|
|
|
|
return -1.0;
|
2024-03-23 18:41:26 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
DBusAPISender::DBusAPISender() {
|
|
|
|
DEBUG.writeln("Checking and connecting to main instance...");
|
|
|
|
try {
|
|
|
|
connection = sdbus::createSessionBusConnection();
|
|
|
|
proxy = sdbus::createProxy(*connection, DBusAPI::serviceName, DBusAPI::objectPath);
|
|
|
|
|
|
|
|
proxy->finishRegistration();
|
|
|
|
{
|
|
|
|
auto method = proxy->createMethodCall("org.freedesktop.DBus.Peer", "Ping");
|
|
|
|
proxy->callMethod(method);
|
|
|
|
}
|
|
|
|
DEBUG.writeln("Main instance found.");
|
|
|
|
} catch (sdbus::Error) {
|
|
|
|
connected = false;
|
|
|
|
DEBUG.writeln("Main instance not found.");
|
|
|
|
}
|
|
|
|
}
|