From eac6811cef64d24b1971420ada35592094b48f80 Mon Sep 17 00:00:00 2001 From: Yavor Georgiev Date: Wed, 5 Jul 2017 16:48:49 +0200 Subject: [PATCH] Implement `Realm.Sync.setLogger` --- src/js_sync.hpp | 14 ++++++- src/js_sync_logger.hpp | 89 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/js_sync_logger.hpp diff --git a/src/js_sync.hpp b/src/js_sync.hpp index fd24b96b..5f175e6f 100644 --- a/src/js_sync.hpp +++ b/src/js_sync.hpp @@ -26,6 +26,7 @@ #include "platform.hpp" #include "js_class.hpp" #include "js_collection.hpp" +#include "js_sync_logger.hpp" #include "sync/sync_manager.hpp" #include "sync/sync_config.hpp" #include "sync/sync_session.hpp" @@ -325,6 +326,7 @@ public: static FunctionType create_constructor(ContextType); static void set_sync_log_level(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &); + static void set_sync_logger(ContextType, FunctionType, ObjectType, size_t, const ValueType[], ReturnValue &); // private static void populate_sync_config(ContextType, ObjectType realm_constructor, ObjectType config_object, Realm::Config&); @@ -334,6 +336,7 @@ public: MethodMap const static_methods = { {"setLogLevel", wrap}, + {"setLogger", wrap}, }; }; @@ -366,6 +369,15 @@ void SyncClass::set_sync_log_level(ContextType ctx, FunctionType, ObjectType realm::SyncManager::shared().set_log_level(log_level_2); } +template +void SyncClass::set_sync_logger(ContextType ctx, FunctionType, ObjectType this_object, size_t argc, const ValueType arguments[], ReturnValue &return_value) { + validate_argument_count(argc, 1); + FunctionType callback = Value::validated_to_function(ctx, arguments[0], "loggerCallback"); + + auto* factory = new JSLoggerFactory(ctx, callback); + realm::SyncManager::shared().set_logger_factory(*factory); +} + template void SyncClass::populate_sync_config(ContextType ctx, ObjectType realm_constructor, ObjectType config_object, Realm::Config& config) { @@ -377,7 +389,7 @@ void SyncClass::populate_sync_config(ContextType ctx, ObjectType realm_constr ObjectType sync_constructor = Object::validated_get_object(ctx, realm_constructor, std::string("Sync")); Protected protected_sync(ctx, sync_constructor); - Protected protected_ctx(Context::get_global_context(ctx)); + Protected protected_ctx(Context::get_global_context(ctx)); EventLoopDispatcher bind([protected_ctx, protected_sync](const std::string& path, const realm::SyncConfig& config, std::shared_ptr) { HANDLESCOPE diff --git a/src/js_sync_logger.hpp b/src/js_sync_logger.hpp new file mode 100644 index 00000000..953974ff --- /dev/null +++ b/src/js_sync_logger.hpp @@ -0,0 +1,89 @@ +//////////////////////////////////////////////////////////////////////////// +// +// Copyright 2017 Realm Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include + +#include "sync/sync_manager.hpp" +#include "event_loop_dispatcher.hpp" + +namespace realm { +namespace js { + +template +class JSLogger : public realm::util::RootLogger { + using GlobalContextType = typename JSEngine::GlobalContext; + using ValueType = typename JSEngine::Value; + using ObjectType = typename JSEngine::Object; + using FunctionType = typename JSEngine::Function; +public: + JSLogger(Protected ctx, Protected callback) + : m_ctx(ctx) + , m_callback(callback) + , m_log_dispatcher(std::bind(&JSLogger::do_log_in_js, this,std::placeholders::_1, std::placeholders::_2)) + { + } + +protected: + void do_log(realm::util::Logger::Level level, std::string message) override final + { + m_log_dispatcher(level, std::move(message)); + } + +private: + void do_log_in_js(realm::util::Logger::Level level, std::string message) + { + HANDLESCOPE + ValueType arguments[2]; + arguments[0] = Value::from_number(m_ctx, static_cast(level)); + arguments[1] = Value::from_string(m_ctx, message); + Function::callback(m_ctx, m_callback, ObjectType(), 2, arguments); + } + + Protected m_ctx; + Protected m_callback; + EventLoopDispatcher m_log_dispatcher; +}; + +template +class JSLoggerFactory : public SyncLoggerFactory { + using GlobalContextType = typename JSEngine::GlobalContext; + using ContextType = typename JSEngine::Context; + using FunctionType = typename JSEngine::Function; +public: + JSLoggerFactory(ContextType ctx, FunctionType callback) + : m_ctx(Context::get_global_context(ctx)) + , m_callback(ctx, callback) + { + } + + virtual std::unique_ptr make_logger(util::Logger::Level level) + { + auto* logger = new JSLogger(m_ctx, m_callback); + logger->set_level_threshold(level); + + return std::unique_ptr(logger); + } +private: + Protected m_ctx; + Protected m_callback; +}; + +} // js +} // realm \ No newline at end of file