mirror of
https://github.com/clangen/musikcube.git
synced 2025-01-30 06:32:36 +00:00
Untested environment initialization.
This commit is contained in:
parent
79d3244799
commit
149ee87dca
@ -13,4 +13,9 @@ add_library(musikcore_c SHARED ${CORE_C_SOURCES})
|
|||||||
set_target_properties(musikcore_c PROPERTIES
|
set_target_properties(musikcore_c PROPERTIES
|
||||||
LIBRARY_OUTPUT_DIRECTORY ${musikcube_SOURCE_DIR}/bin)
|
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()
|
||||||
|
@ -34,32 +34,181 @@
|
|||||||
|
|
||||||
#include "musikcore_c.h"
|
#include "musikcore_c.h"
|
||||||
|
|
||||||
// #include <core/sdk/IResource.h>
|
#include <ev++.h>
|
||||||
// #include <core/sdk/IValue.h>
|
#include <thread>
|
||||||
// #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>
|
|
||||||
|
|
||||||
// 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)
|
#include <boost/locale.hpp>
|
||||||
// #define V(x) reinterpret_cast<IValue*>(x)
|
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
|
||||||
// #define M(x) reinterpret_cast<IMap*>(x)
|
#include <boost/filesystem.hpp>
|
||||||
// #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)
|
|
||||||
|
|
||||||
mcsdk_export bool mcsdk_context_init(mcsdk_context* context) {
|
using namespace musik;
|
||||||
return false;
|
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) {
|
mcsdk_export void mcsdk_context_release(mcsdk_context** context) {
|
||||||
return false;
|
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;
|
||||||
|
}
|
@ -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_track_list_editor;
|
||||||
mcsdk_export typedef mcsdk_handle mcsdk_svc_metadata;
|
mcsdk_export typedef mcsdk_handle mcsdk_svc_metadata;
|
||||||
mcsdk_export typedef mcsdk_handle mcsdk_svc_playback;
|
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 {
|
struct mcsdk_context {
|
||||||
mcsdk_svc_metadata metadata;
|
mcsdk_svc_metadata metadata;
|
||||||
mcsdk_svc_playback playback;
|
mcsdk_svc_playback playback;
|
||||||
|
mcsdk_preferences preferences;
|
||||||
|
mcsdk_handle internal;
|
||||||
};
|
};
|
||||||
|
|
||||||
mcsdk_export bool mcsdk_context_init(mcsdk_context* context);
|
mcsdk_export void mcsdk_context_init(mcsdk_context** context);
|
||||||
mcsdk_export bool mcsdk_context_release(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);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user