Untested environment initialization.

This commit is contained in:
casey langen 2020-01-26 15:34:26 -08:00
parent 79d3244799
commit 149ee87dca
3 changed files with 185 additions and 26 deletions

View File

@ -13,4 +13,9 @@ add_library(musikcore_c SHARED ${CORE_C_SOURCES})
set_target_properties(musikcore_c PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${musikcube_SOURCE_DIR}/bin)
target_link_libraries(musikcore_c ${musikcube_LINK_LIBS})
if (${LINK_STATICALLY} MATCHES "true")
find_library(EVLIB NAMES libev.a ev)
target_link_libraries(musikcore_c ${musikcube_LINK_LIBS} ${EVLIB})
else()
target_link_libraries(musikcore_c ${musikcube_LINK_LIBS} ev)
endif()

View File

@ -34,32 +34,181 @@
#include "musikcore_c.h"
// #include <core/sdk/IResource.h>
// #include <core/sdk/IValue.h>
// #include <core/sdk/IValueList.h>
// #include <core/sdk/IMap.h>
// #include <core/sdk/IMapList.h>
// #include <core/sdk/ITrack.h>
// #include <core/sdk/ITrackList.h>
// #include <core/sdk/ITrackListEditor.h>
// #include <core/sdk/IMetadataProxy.h>
#include <ev++.h>
#include <thread>
// using namespace musik::core::sdk;
#include <core/runtime/MessageQueue.h>
#include <core/runtime/Message.h>
#include <core/library/LibraryFactory.h>
#include <core/audio/PlaybackService.h>
#include <core/plugin/Plugins.h>
#include <core/library/LocalMetadataProxy.h>
#include <core/support/PreferenceKeys.h>
// #define R(x) reinterpret_cast<IResource*>(x)
// #define V(x) reinterpret_cast<IValue*>(x)
// #define M(x) reinterpret_cast<IMap*>(x)
// #define VL(x) reinterpret_cast<IValueList*>(x)
// #define ML(x) reinterpret_cast<IMapList*>(x)
// #define TRACK(x) reinterpret_cast<ITrack*>(x)
// #define TRACKLIST(x) reinterpret_cast<ITrackList*>(x)
// #define TRACKLISTEDITOR(x) reinterpret_cast<ITrackListEditor*>(x)
// #define METADATA(x) reinterpret_cast<IMetadataProxy*>(x)
#include <boost/locale.hpp>
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
#include <boost/filesystem.hpp>
mcsdk_export bool mcsdk_context_init(mcsdk_context* context) {
return false;
using namespace musik;
using namespace musik::core;
using namespace musik::core::db::local;
using namespace musik::core::audio;
using namespace musik::core::sdk;
using namespace musik::core::runtime;
/*
*
* ev_message_queue
*
*/
static const short EVENT_DISPATCH = 1;
static const short EVENT_QUIT = 2;
class ev_message_queue: public MessageQueue {
public:
ev_message_queue(): MessageQueue() {
if (pipe(pipeFd) != 0) {
std::cerr << "\n ERROR! couldn't create pipe\n\n";
exit(EXIT_FAILURE);
}
}
virtual ~ev_message_queue() {
if (pipeFd[0]) {
close(pipeFd[0]);
}
if (pipeFd[1]) {
close(pipeFd[1]);
}
}
void Post(IMessagePtr message, int64_t delayMs) {
MessageQueue::Post(message, delayMs);
if (delayMs <= 0) {
write(pipeFd[1], &EVENT_DISPATCH, sizeof(EVENT_DISPATCH));
}
else {
double delayTs = (double) delayMs / 1000.0;
loop.once<
ev_message_queue,
&ev_message_queue::DelayedDispatch
>(-1, ev::TIMER, (ev::tstamp) delayTs, this);
}
}
void DelayedDispatch(int revents) {
this->Dispatch();
}
void SignalQuit() {
write(pipeFd[1], &EVENT_QUIT, sizeof(EVENT_QUIT));
}
void ReadCallback(ev::io& watcher, int revents) {
short type;
if (read(pipeFd[0], &type, sizeof(type)) == 0) {
std::cerr << "read() failed.\n";
exit(EXIT_FAILURE);
}
switch (type) {
case EVENT_DISPATCH: this->Dispatch(); break;
case EVENT_QUIT: loop.break_loop(ev::ALL); break;
}
}
void Run() {
io.set(loop);
io.set(pipeFd[0], ev::READ);
io.set<ev_message_queue, &ev_message_queue::ReadCallback>(this);
io.start();
sio.set(loop);
write(pipeFd[1], &EVENT_DISPATCH, sizeof(EVENT_DISPATCH));
loop.run(0);
}
private:
int pipeFd[2];
ev::dynamic_loop loop;
ev::io io;
ev::sig sio;
};
/*
*
* instance context
*
*/
struct mcsdk_context_internal {
ev_message_queue message_queue;
std::thread thread;
ILibraryPtr library;
LocalMetadataProxy* metadata;
PlaybackService* playback;
std::shared_ptr<Preferences> preferences;
};
static mcsdk_context* plugin_context = nullptr;
mcsdk_export void mcsdk_context_init(mcsdk_context** context) {
std::locale locale = std::locale();
std::locale utf8Locale(locale, new boost::filesystem::detail::utf8_codecvt_facet);
boost::filesystem::path::imbue(utf8Locale);
auto c = new mcsdk_context();
memset(c, 0, sizeof(mcsdk_context));
auto internal = new mcsdk_context_internal();
internal->library = LibraryFactory::Default();
internal->library->SetMessageQueue(internal->message_queue);
internal->playback = new PlaybackService(internal->message_queue, internal->library);
internal->metadata = new LocalMetadataProxy(internal->library);
internal->preferences = Preferences::ForComponent(prefs::components::Settings);
c->internal = internal;
c->metadata = (mcsdk_svc_metadata) internal->metadata;
c->preferences = (mcsdk_preferences) internal->preferences.get();
internal->thread = std::thread([internal] {
internal->message_queue.Run();
});
if (!plugin_context) {
mcsdk_set_plugin_context(c);
}
*context = c;
}
mcsdk_export bool mcsdk_context_release(mcsdk_context* context) {
return false;
mcsdk_export void mcsdk_context_release(mcsdk_context** context) {
auto c = *context;
auto internal = static_cast<mcsdk_context_internal*>(c->internal);
delete internal->playback;
internal->playback = nullptr;
internal->library->Indexer()->Stop();
internal->message_queue.SignalQuit();
internal->thread.join();
internal->library.reset();
internal->preferences.reset();
delete internal->metadata;
delete internal;
delete c;
if (plugin_context == c) {
mcsdk_set_plugin_context(nullptr);
}
*context = 0;
}
mcsdk_export void mcsdk_set_plugin_context(mcsdk_context* context) {
if (plugin_context && plugin_context != context) {
plugin::Deinit();
}
plugin_context = context;
if (plugin_context) {
auto internal = static_cast<mcsdk_context_internal*>(context->internal);
plugin::Init(&internal->message_queue, internal->playback, internal->library);
}
}
mcsdk_export bool mcsdk_is_plugin_context(mcsdk_context* context) {
return context && context == plugin_context;
}

View File

@ -188,6 +188,7 @@ mcsdk_export typedef mcsdk_handle mcsdk_track_list;
mcsdk_export typedef mcsdk_handle mcsdk_track_list_editor;
mcsdk_export typedef mcsdk_handle mcsdk_svc_metadata;
mcsdk_export typedef mcsdk_handle mcsdk_svc_playback;
mcsdk_export typedef mcsdk_handle mcsdk_preferences;
/*
*
@ -198,10 +199,14 @@ mcsdk_export typedef mcsdk_handle mcsdk_svc_playback;
struct mcsdk_context {
mcsdk_svc_metadata metadata;
mcsdk_svc_playback playback;
mcsdk_preferences preferences;
mcsdk_handle internal;
};
mcsdk_export bool mcsdk_context_init(mcsdk_context* context);
mcsdk_export bool mcsdk_context_release(mcsdk_context* context);
mcsdk_export void mcsdk_context_init(mcsdk_context** context);
mcsdk_export void mcsdk_context_release(mcsdk_context** context);
mcsdk_export void mcsdk_set_plugin_context(mcsdk_context* context);
mcsdk_export bool mcsdk_is_plugin_context(mcsdk_context* context);
/*
*