diff --git a/src/core/c_context.cpp b/src/core/c_context.cpp index fb454b3b6..899e0da38 100644 --- a/src/core/c_context.cpp +++ b/src/core/c_context.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -57,48 +58,49 @@ using namespace musik::core::audio; using namespace musik::core::sdk; using namespace musik::core::runtime; -class internal_message_queue: public MessageQueue { - public: - internal_message_queue(): MessageQueue() { - this->quit = false; - } - void Quit() { - { - LockT lock(this->mutex); - this->quit = true; - } - this->Post(Message::Create(0, 0, 0, 0)); - } - void Run() { - while (true) { - this->WaitAndDispatch(); - { - LockT lock(this->mutex); - if (this->quit) { - return; - } - } - } - } - private: - using LockT = std::unique_lock; - bool quit; - std::mutex mutex; -}; - -struct mcsdk_context_internal { - internal_message_queue message_queue; - std::thread thread; - ILibraryPtr library; - LocalMetadataProxy* metadata; - PlaybackService* playback; - std::shared_ptr preferences; -}; +/* + * globals + */ static std::mutex global_mutex; static bool environment_initialized = false; static mcsdk_context* plugin_context = nullptr; +/* + * mcsdk_context_message_queue + */ + +mcsdk_context_message_queue::mcsdk_context_message_queue(): MessageQueue() { + this->quit = false; +} + +mcsdk_context_message_queue::~mcsdk_context_message_queue() { +} + +void mcsdk_context_message_queue::Quit() { + { + LockT lock(this->mutex); + this->quit = true; + } + this->Post(Message::Create(0, 0, 0, 0)); +} + +void mcsdk_context_message_queue::Run() { + while (true) { + this->WaitAndDispatch(); + { + LockT lock(this->mutex); + if (this->quit) { + return; + } + } + } +} + +/* + * mcsdk_context_* + */ + mcsdk_export void mcsdk_context_init(mcsdk_context** context) { std::unique_lock lock(global_mutex); diff --git a/src/core/c_context.h b/src/core/c_context.h new file mode 100644 index 000000000..278a94efd --- /dev/null +++ b/src/core/c_context.h @@ -0,0 +1,69 @@ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) 2004-2019 musikcube team +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the author nor the names of other contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +#include + +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; + +class mcsdk_context_message_queue: public MessageQueue { + public: + mcsdk_context_message_queue(); + virtual ~mcsdk_context_message_queue(); + void Quit(); + void Run(); + private: + using LockT = std::unique_lock; + bool quit; + std::mutex mutex; +}; + +struct mcsdk_context_internal { + mcsdk_context_message_queue message_queue; + std::thread thread; + ILibraryPtr library; + LocalMetadataProxy* metadata; + PlaybackService* playback; + std::shared_ptr preferences; +}; \ No newline at end of file diff --git a/src/core/c_interface_wrappers.cpp b/src/core/c_interface_wrappers.cpp index 95ec8c3cf..80f160353 100644 --- a/src/core/c_interface_wrappers.cpp +++ b/src/core/c_interface_wrappers.cpp @@ -35,6 +35,8 @@ #include #include +#include + #include #include #include @@ -57,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -195,6 +198,25 @@ mcsdk_export void mcsdk_track_release(mcsdk_track t) { RELEASE(t, TRACK); } +/* + * TrackList + */ + +mcsdk_export mcsdk_track_list mcsdk_track_list_create(mcsdk_context* context) { + auto internal = (mcsdk_context_internal*) context->internal.opaque; + return mcsdk_track_list { new TrackList(internal->library) }; +} + +mcsdk_export bool mcsdk_track_list_can_edit(mcsdk_track_list tl) { + return dynamic_cast(TRACKLIST(tl)) != nullptr; +} + +mcsdk_export mcsdk_track_list_editor mcsdk_track_list_edit(mcsdk_track_list tl) { + auto trackList = reinterpret_cast(tl.opaque); + auto trackListPtr = std::shared_ptr(trackList, [](TrackList*){}); + return mcsdk_track_list_editor { new TrackListEditor(trackListPtr) }; +} + /* * ITrackList */ diff --git a/src/core/musikcore_c.h b/src/core/musikcore_c.h index 93757b642..6880f3715 100644 --- a/src/core/musikcore_c.h +++ b/src/core/musikcore_c.h @@ -96,11 +96,11 @@ typedef enum mcsdk_time_change_mode { } mcsdk_time_change_mode; typedef enum mcsdk_path_type { - mcsdk_path_user_home = 0, - mcsdk_path_data = 1, - mcsdk_path_application = 2, - mcsdk_path_plugins = 3, - mcsdk_path_library = 4 + mcsdk_path_type_user_home = 0, + mcsdk_path_type_data = 1, + mcsdk_path_type_application = 2, + mcsdk_path_type_plugins = 3, + mcsdk_path_type_library = 4 } mcsdk_path_type; typedef enum mcsdk_stream_capability { @@ -320,6 +320,14 @@ mcsdk_export int64_t mcsdk_track_list_index_of(mcsdk_track_list tl, int64_t id); mcsdk_export mcsdk_track mcsdk_track_list_get_track_at(mcsdk_track_list tl, size_t index); mcsdk_export void mcsdk_track_list_release(mcsdk_track_list tl); +/* + * TrackList + */ + +mcsdk_export mcsdk_track_list mcsdk_track_list_create(mcsdk_context* context); +mcsdk_export bool mcsdk_track_list_can_edit(mcsdk_track_list tl); +mcsdk_export mcsdk_track_list_editor mcsdk_track_list_edit(mcsdk_track_list tl); + /* * ITrackListEditor */ diff --git a/src/core_c_demo/main.c b/src/core_c_demo/main.c index 982ff4880..f26ea7d29 100644 --- a/src/core_c_demo/main.c +++ b/src/core_c_demo/main.c @@ -95,6 +95,10 @@ static void test_high_level_playback(mcsdk_context* context) { printf("test_playback: loading 'a day in the life' tracks\n"); mcsdk_track_list tl = mcsdk_svc_metadata_query_tracks( context->metadata, "a day in the life", mcsdk_no_limit, mcsdk_no_offset); + // mcsdk_track_list tl = mcsdk_track_list_create(context); + // mcsdk_track_list_editor tle = mcsdk_track_list_edit(tl); + // mcsdk_track_list_editor_add(tle, 4132LL); + // mcsdk_track_list_editor_release(tle); mcsdk_svc_playback_play(context->playback, tl, 0); mcsdk_track_list_release(tl); printf("test_high_level_playback: playing for 5 seconds...\n"); @@ -122,7 +126,20 @@ static void test_metadata(mcsdk_context* context) { printf("test_metadata: done.\n"); } +static void configure_environment() { + const char* suffix = "stderr.log"; + char* dest_path = NULL; + int length = mcsdk_env_get_path(mcsdk_path_type_data, NULL, 0) + strlen(suffix); + dest_path = malloc(length); + mcsdk_env_get_path(mcsdk_path_type_data, dest_path, length); + strncat(dest_path, suffix, length); + freopen(dest_path, "w", stderr); + printf("stderr will be written to %s", dest_path); + free(dest_path); +} + int main(int argc, char** argv) { + configure_environment(); mcsdk_context* context = NULL; mcsdk_context_init(&context); if (context) {