diff options
Diffstat (limited to 'CommonAPI-Examples/E07Mainloop/src')
4 files changed, 393 insertions, 0 deletions
diff --git a/CommonAPI-Examples/E07Mainloop/src/E07MainloopClient.cpp b/CommonAPI-Examples/E07Mainloop/src/E07MainloopClient.cpp new file mode 100644 index 0000000..02954be --- /dev/null +++ b/CommonAPI-Examples/E07Mainloop/src/E07MainloopClient.cpp @@ -0,0 +1,196 @@ +/* Copyright (C) 2015 BMW Group + * Author: Lutz Bichler (lutz.bichler@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <iostream> +#include <unistd.h> +#include <sstream> + +#include <glib.h> + +#include <CommonAPI/CommonAPI.hpp> +#include <v1_0/commonapi/examples/E07MainloopProxy.hpp> + +using namespace v1_0::commonapi::examples; + +GIOChannel* channel; + +std::future<CommonAPI::CallStatus> gFutureCallStatus; +std::future<CommonAPI::CallStatus> gFutureCallStatusISIA; +std::future<CommonAPI::CallStatus> gFutureCallStatusGetAttrX; + +int32_t gValueForX = 428394; + +void myAttrXCallback(const CommonAPI::CallStatus& callStatus, const int32_t& val) { + std::cout << "Receive callback for Attribute x: " << val << std::endl; +} + +void mySayHelloCallback(const CommonAPI::CallStatus& _callStatus, const std::string& _returnMessage) { + + if (_callStatus != CommonAPI::CallStatus::SUCCESS) { + std::cerr << "Remote call failed!\n"; + return; + } + std::cout << "Got message: '" << _returnMessage << "'\n"; + +} + +gboolean callSetAttrX(void* proxy) { + + std::cout << "callSetAttrX called ..." << std::endl; + + E07MainloopProxy<>* myProxy = static_cast<E07MainloopProxy<>*>(proxy); + myProxy->getXAttribute().setValueAsync(gValueForX , myAttrXCallback); + + return false; +} + +gboolean callGetAttrX(void* proxy) { + + std::cout << "callGetAttrX called ..." << std::endl; + + E07MainloopProxy<>* myProxy = static_cast<E07MainloopProxy<>*>(proxy); + myProxy->getXAttribute().getValueAsync(myAttrXCallback); + + return false; +} + +gboolean callSayHello(void* proxy) { + + std::cout << "callSayHello called ..." << std::endl; + + static int number = 1; + + std::stringstream stream; + stream << "World (" << number << ")"; + const std::string name = stream.str(); + + E07MainloopProxy<>* myProxy = static_cast<E07MainloopProxy<>*>(proxy); + gFutureCallStatus = myProxy->sayHelloAsync(name, mySayHelloCallback); + + number++; + + return true; +} + +class GDispatchWrapper: public GSource { + public: + GDispatchWrapper(CommonAPI::DispatchSource* dispatchSource): dispatchSource_(dispatchSource) {} + CommonAPI::DispatchSource* dispatchSource_; +}; + +gboolean dispatchPrepare ( GSource* source, gint* timeout ) { + + bool result = false; + int64_t eventTimeout; + + result = static_cast<GDispatchWrapper*>(source)->dispatchSource_->prepare(eventTimeout); + + *timeout = eventTimeout; + + return result; +} + +gboolean dispatchCheck ( GSource* source ) { + + return static_cast<GDispatchWrapper*>(source)->dispatchSource_->check(); +} + +gboolean dispatchExecute ( GSource* source, GSourceFunc callback, gpointer userData ) { + + static_cast<GDispatchWrapper*>(source)->dispatchSource_->dispatch(); + return true; +} + +static GSourceFuncs standardGLibSourceCallbackFuncs = { + dispatchPrepare, + dispatchCheck, + dispatchExecute, + NULL +}; + +gboolean gWatchDispatcher ( GIOChannel *source, GIOCondition condition, gpointer userData ) { + + CommonAPI::Watch* watch = static_cast<CommonAPI::Watch*>(userData); + watch->dispatch(condition); + return true; +} + +gboolean gTimeoutDispatcher ( void* userData ) { + + return static_cast<CommonAPI::DispatchSource*>(userData)->dispatch(); +} + +void watchAddedCallback ( CommonAPI::Watch* watch, const CommonAPI::DispatchPriority dispatchPriority ) { + + const pollfd& fileDesc = watch->getAssociatedFileDescriptor(); + channel = g_io_channel_unix_new(fileDesc.fd); + + GSource* gWatch = g_io_create_watch(channel, static_cast<GIOCondition>(fileDesc.events)); + g_source_set_callback(gWatch, reinterpret_cast<GSourceFunc>(&gWatchDispatcher), watch, NULL); + + const auto& dependentSources = watch->getDependentDispatchSources(); + for (auto dependentSourceIterator = dependentSources.begin(); + dependentSourceIterator != dependentSources.end(); + dependentSourceIterator++) { + GSource* gDispatchSource = g_source_new(&standardGLibSourceCallbackFuncs, sizeof(GDispatchWrapper)); + static_cast<GDispatchWrapper*>(gDispatchSource)->dispatchSource_ = *dependentSourceIterator; + + g_source_add_child_source(gWatch, gDispatchSource); + + } + g_source_attach(gWatch, NULL); +} + +void watchRemovedCallback ( CommonAPI::Watch* watch ) { + + g_source_remove_by_user_data(watch); + + if(channel) { + g_io_channel_unref(channel); + channel = NULL; + } +} + +int main() { + std::shared_ptr < CommonAPI::Runtime > runtime = CommonAPI::Runtime::get(); + + std::string domain = "local"; + std::string instance = "commonapi.examples.Mainloop"; + std::string connection = "client-sample"; + + std::shared_ptr<CommonAPI::MainLoopContext> mainloopContext = std::make_shared<CommonAPI::MainLoopContext>(connection); + + std::function<void(CommonAPI::Watch*, const CommonAPI::DispatchPriority)> f_watchAddedCallback = watchAddedCallback; + std::function<void(CommonAPI::Watch*)> f_watchRemovedCallback = watchRemovedCallback; + mainloopContext->subscribeForWatches(f_watchAddedCallback, f_watchRemovedCallback); + + std::shared_ptr<E07MainloopProxyDefault> myProxy = runtime->buildProxy<E07MainloopProxy>(domain, + instance, mainloopContext); + + std::cout << "Checking availability" << std::flush; + static constexpr bool mayBlock = false; + int count = 0; + while (!myProxy->isAvailable()) { + if (count % 10 == 0) + std::cout << "." << std::flush; + g_main_context_iteration(NULL, mayBlock); + usleep(50000); + } + std::cout << "done." << std::endl; + + GMainLoop* mainloop = NULL; + mainloop = g_main_loop_new(NULL, FALSE); + + void *proxyPtr = (void*)myProxy.get(); + g_timeout_add(100, callSayHello, proxyPtr); + g_timeout_add(5000, callGetAttrX, proxyPtr); + g_timeout_add(9000, callSetAttrX, proxyPtr); + + g_main_loop_run (mainloop); + g_main_loop_unref (mainloop); + + return 0; +} diff --git a/CommonAPI-Examples/E07Mainloop/src/E07MainloopService.cpp b/CommonAPI-Examples/E07Mainloop/src/E07MainloopService.cpp new file mode 100644 index 0000000..e57f192 --- /dev/null +++ b/CommonAPI-Examples/E07Mainloop/src/E07MainloopService.cpp @@ -0,0 +1,140 @@ +/* Copyright (C) 2015 BMW Group + * Author: Lutz Bichler (lutz.bichler@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <iostream> +#include <thread> + +#include <glib.h> + +#include <CommonAPI/CommonAPI.hpp> +#include "E07MainloopStubImpl.hpp" + +using namespace std; + +GIOChannel* channel; + +gboolean callIncCounter(void* service) { + + E07MainloopStubImpl* myService = static_cast<E07MainloopStubImpl*>(service); + myService->incAttrX(); + + return true; +} + +gboolean callWaitingInfo(void* service) { + std::cout << "Waiting for calls... (Abort with CTRL+C)" << std::endl; + + return true; +} + +class GDispatchWrapper: public GSource { + public: + GDispatchWrapper(CommonAPI::DispatchSource* dispatchSource): dispatchSource_(dispatchSource) {} + CommonAPI::DispatchSource* dispatchSource_; +}; + +gboolean dispatchPrepare ( GSource* source, gint* timeout ) { + + bool result = false; + int64_t eventTimeout; + + result = static_cast<GDispatchWrapper*>(source)->dispatchSource_->prepare(eventTimeout); + + *timeout = eventTimeout; + + return result; +} + +gboolean dispatchCheck ( GSource* source ) { + + return static_cast<GDispatchWrapper*>(source)->dispatchSource_->check(); +} + +gboolean dispatchExecute ( GSource* source, GSourceFunc callback, gpointer userData ) { + + static_cast<GDispatchWrapper*>(source)->dispatchSource_->dispatch(); + return true; +} + +static GSourceFuncs standardGLibSourceCallbackFuncs = { + dispatchPrepare, + dispatchCheck, + dispatchExecute, + NULL +}; + +gboolean gWatchDispatcher ( GIOChannel *source, GIOCondition condition, gpointer userData ) { + + CommonAPI::Watch* watch = static_cast<CommonAPI::Watch*>(userData); + watch->dispatch(condition); + return true; +} + +gboolean gTimeoutDispatcher ( void* userData ) { + + return static_cast<CommonAPI::DispatchSource*>(userData)->dispatch(); +} + +void watchAddedCallback ( CommonAPI::Watch* watch, const CommonAPI::DispatchPriority dispatchPriority ) { + + const pollfd& fileDesc = watch->getAssociatedFileDescriptor(); + channel = g_io_channel_unix_new(fileDesc.fd); + + GSource* gWatch = g_io_create_watch(channel, static_cast<GIOCondition>(fileDesc.events)); + g_source_set_callback(gWatch, reinterpret_cast<GSourceFunc>(&gWatchDispatcher), watch, NULL); + + const auto& dependentSources = watch->getDependentDispatchSources(); + for (auto dependentSourceIterator = dependentSources.begin(); + dependentSourceIterator != dependentSources.end(); + dependentSourceIterator++) { + GSource* gDispatchSource = g_source_new(&standardGLibSourceCallbackFuncs, sizeof(GDispatchWrapper)); + static_cast<GDispatchWrapper*>(gDispatchSource)->dispatchSource_ = *dependentSourceIterator; + + g_source_add_child_source(gWatch, gDispatchSource); + + } + g_source_attach(gWatch, NULL); +} + +void watchRemovedCallback ( CommonAPI::Watch* watch ) { + + g_source_remove_by_user_data(watch); + + if(channel) { + g_io_channel_unref(channel); + channel = NULL; + } +} + +int main() { + std::shared_ptr<CommonAPI::Runtime> runtime = CommonAPI::Runtime::get(); + + std::string domain = "local"; + std::string instance = "commonapi.examples.Mainloop"; + std::string connection = "service-sample"; + + std::shared_ptr<CommonAPI::MainLoopContext> mainloopContext = std::make_shared<CommonAPI::MainLoopContext>(connection); + + std::function<void(CommonAPI::Watch*, const CommonAPI::DispatchPriority)> f_watchAddedCallback = watchAddedCallback; + std::function<void(CommonAPI::Watch*)> f_watchRemovedCallback = watchRemovedCallback; + mainloopContext->subscribeForWatches(f_watchAddedCallback, f_watchRemovedCallback); + + std::shared_ptr<E07MainloopStubImpl> myService = std::make_shared<E07MainloopStubImpl>(); + runtime->registerService(domain, instance, myService, mainloopContext); + + GMainLoop* mainloop = NULL; + mainloop = g_main_loop_new(NULL, FALSE); + + void *servicePtr = (void*)myService.get(); + g_timeout_add_seconds(10, callWaitingInfo, servicePtr); + + g_timeout_add(2500, callIncCounter, servicePtr); + + g_main_loop_run (mainloop); + g_main_loop_unref (mainloop); + + return 0; +} diff --git a/CommonAPI-Examples/E07Mainloop/src/E07MainloopStubImpl.cpp b/CommonAPI-Examples/E07Mainloop/src/E07MainloopStubImpl.cpp new file mode 100644 index 0000000..53a2cd0 --- /dev/null +++ b/CommonAPI-Examples/E07Mainloop/src/E07MainloopStubImpl.cpp @@ -0,0 +1,33 @@ +/* Copyright (C) 2015 BMW Group + * Author: Lutz Bichler (lutz.bichler@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "E07MainloopStubImpl.hpp" + +E07MainloopStubImpl::E07MainloopStubImpl() { + setXAttribute(0); +} + +E07MainloopStubImpl::~E07MainloopStubImpl() { +} + +void E07MainloopStubImpl::sayHello(const std::shared_ptr<CommonAPI::ClientId> _client, + std::string _name, + sayHelloReply_t _reply) { + + std::stringstream messageStream; + + messageStream << "Hello " << _name << "!"; + std::cout << "sayHello('" << _name << "'): '" << messageStream.str() << "'\n"; + + _reply(messageStream.str()); +} + +void E07MainloopStubImpl::incAttrX() { + int32_t xValue = getXAttribute(); + xValue++; + setXAttribute((int32_t)xValue); + std::cout << "New counter value = " << xValue << "!" << std::endl; +} diff --git a/CommonAPI-Examples/E07Mainloop/src/E07MainloopStubImpl.hpp b/CommonAPI-Examples/E07Mainloop/src/E07MainloopStubImpl.hpp new file mode 100644 index 0000000..1cd82b1 --- /dev/null +++ b/CommonAPI-Examples/E07Mainloop/src/E07MainloopStubImpl.hpp @@ -0,0 +1,24 @@ +/* Copyright (C) 2015 BMW Group + * Author: Lutz Bichler (lutz.bichler@bmw.de) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef E07MAINLOOPSTUBIMPL_H_ +#define E07MAINLOOPSTUBIMPL_H_ + +#include <CommonAPI/CommonAPI.hpp> +#include <v1_0/commonapi/examples/E07MainloopStubDefault.hpp> + +class E07MainloopStubImpl: public v1_0::commonapi::examples::E07MainloopStubDefault { + +public: + E07MainloopStubImpl(); + virtual ~E07MainloopStubImpl(); + + virtual void sayHello(const std::shared_ptr<CommonAPI::ClientId> _client, std::string _name, sayHelloReply_t _return); + virtual void incAttrX(); + +}; + +#endif /* E07MAINLOOPSTUBIMPL_H_ */ |