diff options
author | Johannes Schanda <schanda@itestra.de> | 2013-09-17 14:08:26 +0200 |
---|---|---|
committer | Philip Rauwolf <rauwolf@itestra.de> | 2013-09-18 18:16:43 +0200 |
commit | f351f3415cc5fe1bd3e70eded698274abdeb0e52 (patch) | |
tree | f495aafaa77e38873e85a44571667e9fe53916f5 | |
parent | 774d43c5791f69093a233f0c4d1fe217105401fd (diff) | |
download | genivi-common-api-runtime-f351f3415cc5fe1bd3e70eded698274abdeb0e52.tar.gz |
Add managed services generation and test updates
- Fix some issues with selective
- Add selective and managed to tutorial
- Add api for management on stub and proxy side
- Add isAvailableBlocking to public proxy api
Change-Id: Icb1fd6ef200f59ff889042c386edc3125a82acb2
14 files changed, 412 insertions, 36 deletions
diff --git a/CommonAPI-Examples/Makefile.am b/CommonAPI-Examples/Makefile.am index 30ec01a..a30fd8b 100644 --- a/CommonAPI-Examples/Makefile.am +++ b/CommonAPI-Examples/Makefile.am @@ -26,7 +26,12 @@ helloworld_proxy_SOURCES = \ src-gen/commonapi/examples/HelloWorldInterfaceProxyBase.h \ src-gen/commonapi/examples/HelloWorldInterfaceProxy.h \ src-gen/commonapi/examples/HelloWorldInterfaceDBusProxy.h \ - src-gen/commonapi/examples/HelloWorldInterfaceDBusProxy.cpp + src-gen/commonapi/examples/HelloWorldInterfaceDBusProxy.cpp \ + src-gen/commonapi/examples/HelloWorldLeaf.h \ + src-gen/commonapi/examples/HelloWorldLeafProxyBase.h \ + src-gen/commonapi/examples/HelloWorldLeafProxy.h \ + src-gen/commonapi/examples/HelloWorldLeafDBusProxy.h \ + src-gen/commonapi/examples/HelloWorldLeafDBusProxy.cpp helloworld_stub_SOURCES = \ src/helloworld-stub.cpp \ @@ -35,7 +40,13 @@ helloworld_stub_SOURCES = \ src-gen/commonapi/examples/HelloWorldInterfaceStubDefault.h \ src-gen/commonapi/examples/HelloWorldInterfaceStubDefault.cpp \ src-gen/commonapi/examples/HelloWorldInterfaceDBusStubAdapter.h \ - src-gen/commonapi/examples/HelloWorldInterfaceDBusStubAdapter.cpp + src-gen/commonapi/examples/HelloWorldInterfaceDBusStubAdapter.cpp \ + src-gen/commonapi/examples/HelloWorldLeaf.h \ + src-gen/commonapi/examples/HelloWorldLeafStub.h \ + src-gen/commonapi/examples/HelloWorldLeafStubDefault.h \ + src-gen/commonapi/examples/HelloWorldLeafStubDefault.cpp \ + src-gen/commonapi/examples/HelloWorldLeafDBusStubAdapter.h \ + src-gen/commonapi/examples/HelloWorldLeafDBusStubAdapter.cpp # ------------------------------------------------------------------------------ MAINTAINERCLEANFILES = \ diff --git a/CommonAPI-Examples/configure.ac b/CommonAPI-Examples/configure.ac index ffc2645..2e196ff 100644 --- a/CommonAPI-Examples/configure.ac +++ b/CommonAPI-Examples/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.61]) AC_INIT([GENIVI Common API C++ Examples], - [2.0], + [2.1], [], [CommonAPI-Examples]) diff --git a/CommonAPI-Examples/src/helloworld-proxy.cpp b/CommonAPI-Examples/src/helloworld-proxy.cpp index a55d1b8..4a017fc 100644 --- a/CommonAPI-Examples/src/helloworld-proxy.cpp +++ b/CommonAPI-Examples/src/helloworld-proxy.cpp @@ -5,6 +5,7 @@ * 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 <commonapi/examples/HelloWorldInterfaceProxy.h> +#include <commonapi/examples/HelloWorldLeafProxy.h> #include <CommonAPI/CommonAPI.h> #include <iostream> #include <future> @@ -30,7 +31,7 @@ int main(int argc, char** argv) { std::cout << "Factory created!\n"; - const std::string& commonApiAddress = "local:commonapi.examples.HelloWorld:commonapi.examples.HelloWorld"; + const std::string commonApiAddress = "local:commonapi.examples.HelloWorld:commonapi.examples.HelloWorld"; auto helloWorldProxy = factory->buildProxy<commonapi::examples::HelloWorldInterfaceProxy>(commonApiAddress); if (!helloWorldProxy) { std::cerr << "Error: Unable to build proxy!\n"; @@ -57,7 +58,11 @@ int main(int argc, char** argv) { std::cout << "Proxy available!\n"; - const std::string& name = "World"; + helloWorldProxy->getSaySomethingSelectiveEvent().subscribe([&](const std::string& message) { + std::cout << "Received broadcast message: " << message << "\n"; + }); + + const std::string name = "World"; CommonAPI::CallStatus callStatus; std::string helloWorldMessage; @@ -70,5 +75,32 @@ int main(int argc, char** argv) { std::cout << "Got message: '" << helloWorldMessage << "'\n"; + const std::string leafInstance = "commonapi.examples.HelloWorld.Leaf"; + CommonAPI::CallStatus callStatusAv; + CommonAPI::AvailabilityStatus availabilityStatus; + helloWorldProxy->getProxyManagerHelloWorldLeaf().getInstanceAvailabilityStatus(leafInstance, callStatusAv, availabilityStatus); + + if (callStatusAv == CommonAPI::CallStatus::SUCCESS && availabilityStatus == CommonAPI::AvailabilityStatus::AVAILABLE) { + auto helloWorldLeafProxy = helloWorldProxy->getProxyManagerHelloWorldLeaf().buildProxy<commonapi::examples::HelloWorldLeafProxy>(leafInstance); + + const std::string nameLeaf = "WorldLeaf"; + CommonAPI::CallStatus callStatusLeaf; + std::string helloWorldLeafMessage; + + std::cout << "Sending name: '" << nameLeaf << "'\n"; + helloWorldLeafProxy->sayHelloLeaf("World", callStatusLeaf, helloWorldLeafMessage); + if (callStatusLeaf != CommonAPI::CallStatus::SUCCESS) { + std::cerr << "Remote call failed!\n"; + return -1; + } + + std::cout << "Got message: '" << helloWorldLeafMessage << "'\n"; + + } else { + std::cout << "Leaf Proxy not available\n"; + sleep(5); + return -1; + } + return 0; } diff --git a/CommonAPI-Examples/src/helloworld-stub.cpp b/CommonAPI-Examples/src/helloworld-stub.cpp index 68330fa..3a856f1 100644 --- a/CommonAPI-Examples/src/helloworld-stub.cpp +++ b/CommonAPI-Examples/src/helloworld-stub.cpp @@ -5,6 +5,7 @@ * 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 <commonapi/examples/HelloWorldInterfaceStubDefault.h> +#include <commonapi/examples/HelloWorldLeafStubDefault.h> #include <CommonAPI/CommonAPI.h> #include <iostream> #include <sstream> @@ -12,18 +13,51 @@ class MyHelloWorldStub: public commonapi::examples::HelloWorldInterfaceStubDefault { - public: - virtual void sayHello(std::string name, std::string& message) { + private: + std::shared_ptr<CommonAPI::ClientId> lastId; + +public: + virtual void onSaySomethingSelectiveSubscriptionChanged(const std::shared_ptr<CommonAPI::ClientId> clientId, + const CommonAPI::SelectiveBroadcastSubscriptionEvent event) { + if (event == CommonAPI::SelectiveBroadcastSubscriptionEvent::SUBSCRIBED) { + lastId = clientId; + } + } + + virtual void sayHello(std::string name, std::string& message) { std::stringstream messageStream; messageStream << "Hello " << name << "!"; message = messageStream.str(); std::cout << "sayHello('" << name << "'): '" << message << "'\n"; + + std::shared_ptr<CommonAPI::ClientIdList> receivers = std::make_shared<CommonAPI::ClientIdList>(); + + + if (lastId) { + receivers->insert(lastId); + } + this->fireSaySomethingSelective("Broadcast to last ID", receivers); + + //delete receivers; } }; +class MyHelloWorldLeafStub: public commonapi::examples::HelloWorldLeafStubDefault { + public: + virtual void sayHelloLeaf(std::string name, std::string& message) { + std::stringstream messageStream; + + messageStream << "Hello Leaf " << name << "!"; + message = messageStream.str(); + + std::cout << "sayHelloLeaf('" << name << "'): '" << message << "'\n"; + } +}; + + int main(int argc, char** argv) { CommonAPI::Runtime::LoadState loadState; auto runtime = CommonAPI::Runtime::load(loadState); @@ -54,7 +88,7 @@ int main(int argc, char** argv) { auto helloWorldStub = std::make_shared<MyHelloWorldStub>(); - const std::string& commonApiAddress = "local:commonapi.examples.HelloWorld:commonapi.examples.HelloWorld"; + const std::string commonApiAddress = "local:commonapi.examples.HelloWorld:commonapi.examples.HelloWorld"; const bool isStubRegistrationSuccessful = servicePublisher->registerService(helloWorldStub, commonApiAddress, factory); if (!isStubRegistrationSuccessful) { std::cerr << "Error: Unable to register service!\n"; @@ -64,6 +98,14 @@ int main(int argc, char** argv) { std::cout << "Service registration successful!\n"; + auto helloWorldLeafStub = std::make_shared<MyHelloWorldLeafStub>(); + const std::string leafInstance = "commonapi.examples.HelloWorld.Leaf"; + const bool leafOk = helloWorldStub->registerManagedStubHelloWorldLeaf(helloWorldLeafStub, leafInstance); + if (!leafOk) { + std::cerr << "Error: Unable to register leaf service!\n"; + return -1; + } + while(true) { std::cout << "Waiting for calls... (Abort with CTRL+C)\n"; std::this_thread::sleep_for(std::chrono::seconds(60)); diff --git a/CommonAPI-Examples/src/helloworld.fidl b/CommonAPI-Examples/src/helloworld.fidl index cd915d3..9830289 100644 --- a/CommonAPI-Examples/src/helloworld.fidl +++ b/CommonAPI-Examples/src/helloworld.fidl @@ -6,7 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package commonapi.examples -interface HelloWorldInterface { +interface HelloWorldInterface manages HelloWorldLeaf { version { major 1 minor 0 } method sayHello { @@ -17,5 +17,23 @@ interface HelloWorldInterface { String message } } + + broadcast saySomething selective { + out { + String message + } + } } +interface HelloWorldLeaf { + version { major 1 minor 0 } + + method sayHelloLeaf { + in { + String name + } + out { + String message + } + } +}
\ No newline at end of file @@ -366,7 +366,149 @@ and you should get output from your client once, saying "Got Message: 'Hello World'". ---- +== Advanced Features +=== Selective + +Selective broadcasts, indicated with the selective keword after the name of the broadcast in Franca can be sent to individual clients rather +than all participants. This is accomplished with the use of a ClientID parameter which can serve to identify the targets. Note if you wish to +identify clients absolutely you must do this on the application level. + +We can add a block to our interface for the selective broadcast: + +---- +broadcast saySomething selective { + out { + String message + } +} +---- + +We can the add some code to our stub implementation to handle this: +---- +virtual void onSaySomethingSelectiveSubscriptionChanged(const std::shared_ptr<CommonAPI::ClientId> clientId, + const CommonAPI::SelectiveBroadcastSubscriptionEvent event) { + if (event == CommonAPI::SelectiveBroadcastSubscriptionEvent::SUBSCRIBED) { + lastId = clientId; + } +} +---- +and to the sayHello method: +---- +std::shared_ptr<CommonAPI::ClientIdList> receivers = std::make_shared<CommonAPI::ClientIdList>(); +if (lastId) { + receivers->insert(lastId); +} +this->fireSaySomethingSelective("Broadcast to last ID", receivers); +---- +and finally a member to the stub: +---- +private: + std::shared_ptr<CommonAPI::ClientId> lastId; +---- + +The onSaySomethingSelectiveSubscriptionChanged method is called when a subscription for this boroadcast changes. Is added, we set the +memeber lastId to this value. Whenever sayHello is called we now also send a broadcast only to the last client which registered. +The ClientIdList contains all the intended recipients, and the middleware will send the message to all memeber of this list who are +registered for the broadcast. If NULL is passed instead the broadcast is sent to all clients. + +On the client side we can add this before the const std::string name = "World"; line: +---- +helloWorldProxy->getSaySomethingSelectiveEvent().subscribe([&](const std::string& message) { + std::cout << "Received broadcast message: " << message << "\n"; +}); +---- +This casues a subscription to the broadcast, and the lambda function will be called whenever we receive a message. + +=== Managed Stubs + +In franca a relationship between two interfaces can be declared in the form "x manages y". This indicates that x has a number of y as +childeren whose lifecycle is tied to and managed by x. This allows a an application to activare y stubs on an instance of x stubs. +Similarily on the proxy side a manager for y interfaces is available on the x proxy, where we can be informed of appearing and disappearing +instances, and interrogate the network about the state of instances. + +In our franca change the defenition of the HelloWorldInterface to: +---- +interface HelloWorldInterface manages HelloWorldLeaf { +---- + +and after this interface block add: +---- +interface HelloWorldLeaf { + version { major 1 minor 0 } + + method sayHelloLeaf { + in { + String name + } + out { + String message + } + } +} +---- + +This causes HelloWorldInterface to be able to manage HelloWorldLeaf instances. Note that HelloWorldLeaf instances can still be registered +and accessed in the normal way via the service publisher and facotry. + +To the stub application add to the top as a new class defenition: + +---- +class MyHelloWorldLeafStub: public commonapi::examples::HelloWorldLeafStubDefault { + public: + virtual void sayHelloLeaf(std::string name, std::string& message) { + std::stringstream messageStream; + + messageStream << "Hello Leaf " << name << "!"; + message = messageStream.str(); + + std::cout << "sayHelloLeaf('" << name << "'): '" << message << "'\n"; + } +}; +---- + +To the bottom of the main function before the while loop add: +---- +auto helloWorldLeafStub = std::make_shared<MyHelloWorldLeafStub>(); +const std::string leafInstance = "commonapi.examples.HelloWorld.Leaf"; +const bool leafOk = helloWorldStub->registerManagedStubHelloWorldLeaf(helloWorldLeafStub, leafInstance); +if (!leafOk) { + std::cerr << "Error: Unable to register leaf service!\n"; + return -1; +} +---- + +To the client programm add to the bottom of the main function just before return 0: +---- +const std::string leafInstance = "commonapi.examples.HelloWorld.Leaf"; +CommonAPI::CallStatus callStatusAv; +CommonAPI::AvailabilityStatus availabilityStatus; +helloWorldProxy->getProxyManagerHelloWorldLeaf().getInstanceAvailabilityStatus(leafInstance, callStatusAv, availabilityStatus); + +if (callStatusAv == CommonAPI::CallStatus::SUCCESS && availabilityStatus == CommonAPI::AvailabilityStatus::AVAILABLE) { + auto helloWorldLeafProxy = helloWorldProxy->getProxyManagerHelloWorldLeaf().buildProxy<commonapi::examples::HelloWorldLeafProxy>(leafInstance); + + const std::string nameLeaf = "WorldLeaf"; + CommonAPI::CallStatus callStatusLeaf; + std::string helloWorldLeafMessage; + + std::cout << "Sending name: '" << nameLeaf << "'\n"; + helloWorldLeafProxy->sayHelloLeaf("World", callStatusLeaf, helloWorldLeafMessage); + if (callStatusLeaf != CommonAPI::CallStatus::SUCCESS) { + std::cerr << "Remote call failed!\n"; + return -1; + } + + std::cout << "Got message: '" << helloWorldLeafMessage << "'\n"; + +} else { + std::cout << "Leaf Proxy not available\n"; + sleep(5); + return -1; +} +---- +This instantiates and calls a managed leaf stub and proxy respectively. + == Further reading Aside from the README files of Common API and the specific bindings. diff --git a/org.genivi.commonapi.core.verification/src/VerificationTestStub.cpp b/org.genivi.commonapi.core.verification/src/VerificationTestStub.cpp index 59b23f2..f03416d 100644 --- a/org.genivi.commonapi.core.verification/src/VerificationTestStub.cpp +++ b/org.genivi.commonapi.core.verification/src/VerificationTestStub.cpp @@ -24,8 +24,7 @@ VerificationTestStub::VerificationTestStub() : TestInterfaceStubDefault(), calledTestDerivedTypeMethod(0) { } -void VerificationTestStub::testPredefinedTypeMethod(const CommonAPI::ClientId& clientId, - uint32_t uint32InValue, +void VerificationTestStub::testPredefinedTypeMethod(uint32_t uint32InValue, std::string stringInValue, uint32_t& uint32OutValue, std::string& stringOutValue) { diff --git a/org.genivi.commonapi.core.verification/src/VerificationTestStub.h b/org.genivi.commonapi.core.verification/src/VerificationTestStub.h index 4723d4b..609dc48 100644 --- a/org.genivi.commonapi.core.verification/src/VerificationTestStub.h +++ b/org.genivi.commonapi.core.verification/src/VerificationTestStub.h @@ -27,8 +27,7 @@ private: commonapi::tests::DerivedTypeCollection::TestEnumExtended2& testEnumExtended2OutValue, commonapi::tests::DerivedTypeCollection::TestMap& testMapOutValue); - virtual void testPredefinedTypeMethod(const CommonAPI::ClientId& clientId, - uint32_t uint32InValue, + virtual void testPredefinedTypeMethod(uint32_t uint32InValue, std::string stringInValue, uint32_t& uint32OutValue, std::string& stringOutValue); diff --git a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceGenerator.xtend b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceGenerator.xtend index bffc4aa..aa6a461 100644 --- a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceGenerator.xtend +++ b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceGenerator.xtend @@ -121,6 +121,12 @@ class FInterfaceGenerator { def void getRequiredHeaderFiles(FInterface fInterface, Collection<String> generatedHeaders, Collection<String> libraryHeaders) { libraryHeaders.add('CommonAPI/types.h') + if (!fInterface.methods.filter[errors != null].empty) { + libraryHeaders.addAll('CommonAPI/InputStream.h', 'CommonAPI/OutputStream.h') + } + if (!fInterface.managedInterfaces.empty) { + generatedHeaders.add('set'); + } fInterface.types.forEach[addRequiredHeaders(generatedHeaders, libraryHeaders)] var Iterable<FMethod> errorMethods = fInterface.methods.filter[errors!=null] if(errorMethods.size!=0){ @@ -139,4 +145,4 @@ class FInterfaceGenerator { val hasTypeWithImplementation = fInterface.types.exists[hasImplementation] return hasTypeWithImplementation } -}
\ No newline at end of file +} diff --git a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceProxyGenerator.xtend b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceProxyGenerator.xtend index 0fd4be0..814954a 100644 --- a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceProxyGenerator.xtend +++ b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceProxyGenerator.xtend @@ -15,7 +15,6 @@ import org.franca.core.franca.FMethod import org.genivi.commonapi.core.deployment.DeploymentInterfacePropertyAccessor import java.util.HashSet -import org.franca.core.franca.FBroadcast import org.eclipse.core.resources.IResource class FInterfaceProxyGenerator { @@ -46,11 +45,14 @@ class FInterfaceProxyGenerator { #if !defined (COMMONAPI_INTERNAL_COMPILATION) #define COMMONAPI_INTERNAL_COMPILATION #endif - + «FOR requiredHeaderFile : libraryHeaders.sort» #include <«requiredHeaderFile»> «ENDFOR» + «IF !fInterface.managedInterfaces.empty» + #include <CommonAPI/ProxyManager.h> + «ENDIF» «IF fInterface.hasAttributes» #include <CommonAPI/Attribute.h> «ENDIF» @@ -107,6 +109,9 @@ class FInterfaceProxyGenerator { virtual «method.generateAsyncDefinition» = 0; «ENDIF» «ENDFOR» + «FOR managed : fInterface.managedInterfaces» + virtual CommonAPI::ProxyManager& «managed.proxyManagerGetterName»() = 0; + «ENDFOR» }; «fInterface.model.generateNamespaceEndDeclaration» @@ -130,7 +135,7 @@ class FInterfaceProxyGenerator { #include <CommonAPI/AttributeExtension.h> #include <CommonAPI/Factory.h> «ENDIF» - + #undef COMMONAPI_INTERNAL_COMPILATION «fInterface.model.generateNamespaceBeginDeclaration» @@ -143,7 +148,9 @@ class FInterfaceProxyGenerator { «FOR attribute : fInterface.attributes» «FTypeGenerator::generateComments(attribute, false)» - /// Returns the wrapper class that provides access to the attribute «attribute.name». + /** + * Returns the wrapper class that provides access to the attribute «attribute.name». + */ virtual «attribute.generateGetMethodDefinition» { return delegate_->get«attribute.className»(); } @@ -151,7 +158,9 @@ class FInterfaceProxyGenerator { «FOR broadcast : fInterface.broadcasts» «FTypeGenerator::generateComments(broadcast, false)» - /// Returns the wrapper class that provides access to the broadcast «broadcast.name». + /** + * Returns the wrapper class that provides access to the broadcast «broadcast.name». + */ virtual «broadcast.generateGetMethodDefinition» { return delegate_->get«broadcast.className»(); } @@ -162,8 +171,8 @@ class FInterfaceProxyGenerator { «FTypeGenerator::generateComments(method, true)» * Calls «method.name» with «IF method.isFireAndForget»Fire&Forget«ELSE»synchronous«ENDIF» semantics. * -«IF !method.inArgs.empty» * All const parameters are input parameters to this method.«ENDIF» -«IF !method.outArgs.empty» * All non-const parameters will be filled with the returned values.«ENDIF» + «IF !method.inArgs.empty»* All const parameters are input parameters to this method.«ENDIF» + «IF !method.outArgs.empty»* All non-const parameters will be filled with the returned values.«ENDIF» * The CallStatus will be filled when the method returns and indicate either * "SUCCESS" or which type of error has occurred. In case of an error, ONLY the CallStatus * will be set. @@ -183,23 +192,42 @@ class FInterfaceProxyGenerator { virtual «method.generateAsyncDefinition»; «ENDIF» «ENDFOR» + + «FOR managed : fInterface.managedInterfaces» + virtual CommonAPI::ProxyManager& «managed.proxyManagerGetterName»(); + «ENDFOR» - /// Returns the CommonAPI address of the remote partner this proxy communicates with. + /** + * Returns the CommonAPI address of the remote partner this proxy communicates with. + */ virtual std::string getAddress() const; - /// Returns the domain of the remote partner this proxy communicates with. + /** + * Returns the domain of the remote partner this proxy communicates with. + */ virtual const std::string& getDomain() const; - /// Returns the service ID of the remote partner this proxy communicates with. + /** + * Returns the service ID of the remote partner this proxy communicates with. + */ virtual const std::string& getServiceId() const; - /// Returns the instance ID of the remote partner this proxy communicates with. + /** + * Returns the instance ID of the remote partner this proxy communicates with. + */ virtual const std::string& getInstanceId() const; - /// Returns true if the remote partner for this proxy is available. + /** + * Returns true if the remote partner for this proxy is currently known to be available. + */ virtual bool isAvailable() const; /** + * Returns true if the remote partner for this proxy is available. + */ + virtual bool isAvailableBlocking() const; + + /** * Returns the wrapper class that is used to (de-)register for notifications about * the availability of the remote partner of this proxy. */ @@ -276,6 +304,11 @@ class FInterfaceProxyGenerator { bool «fInterface.proxyClassName»<_AttributeExtensions...>::isAvailable() const { return delegate_->isAvailable(); } + + template <typename ... _AttributeExtensions> + bool «fInterface.proxyClassName»<_AttributeExtensions...>::isAvailableBlocking() const { + return delegate_->isAvailableBlocking(); + } template <typename ... _AttributeExtensions> CommonAPI::ProxyStatusEvent& «fInterface.proxyClassName»<_AttributeExtensions...>::getProxyStatusEvent() { @@ -286,6 +319,14 @@ class FInterfaceProxyGenerator { CommonAPI::InterfaceVersionAttribute& «fInterface.proxyClassName»<_AttributeExtensions...>::getInterfaceVersionAttribute() { return delegate_->getInterfaceVersionAttribute(); } + + + «FOR managed : fInterface.managedInterfaces» + template <typename ... _AttributeExtensions> + CommonAPI::ProxyManager& «fInterface.proxyClassName»<_AttributeExtensions...>::«managed.proxyManagerGetterName»() { + return delegate_->«managed.proxyManagerGetterName»(); + } + «ENDFOR» «fInterface.model.generateNamespaceEndDeclaration» @@ -300,7 +341,6 @@ class FInterfaceProxyGenerator { }; } «ENDIF» - #endif // «fInterface.defineName»_PROXY_H_ ''' diff --git a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceStubGenerator.xtend b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceStubGenerator.xtend index b27a259..6051687 100644 --- a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceStubGenerator.xtend +++ b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceStubGenerator.xtend @@ -80,7 +80,7 @@ class FInterfaceStubGenerator { virtual void «broadcast.stubAdapterClassSendSelectiveMethodName»(«generateSendSelectiveSignatur(broadcast, fInterface, true)») = 0; virtual void «broadcast.subscribeSelectiveMethodName»(const std::shared_ptr<CommonAPI::ClientId> clientId, bool& success) = 0; virtual void «broadcast.unsubscribeSelectiveMethodName»(const std::shared_ptr<CommonAPI::ClientId> clientId) = 0; - virtual CommonAPI::ClientIdList* const «broadcast.stubAdapterClassSubscribersMethodName»() = 0; + virtual std::shared_ptr<CommonAPI::ClientIdList> const «broadcast.stubAdapterClassSubscribersMethodName»() = 0; «ELSE» /** * Sends a broadcast event for «broadcast.name». Should not be called directly. @@ -89,6 +89,15 @@ class FInterfaceStubGenerator { virtual void «broadcast.stubAdapterClassFireEventMethodName»(«broadcast.outArgs.map['const ' + getTypeName(fInterface.model) + '& ' + name].join(', ')») = 0; «ENDIF» «ENDFOR» + + «FOR managed : fInterface.managedInterfaces» + virtual «managed.stubRegisterManagedMethod» = 0; + virtual bool «managed.stubDeregisterManagedName»(const std::string&) = 0; + virtual std::set<std::string>& «managed.stubManagedSetGetterName»() = 0; + «ENDFOR» + + virtual void deactivateManagedInstances() = 0; + protected: /** * Defines properties for storing the ClientIds of clients / proxies that have @@ -96,7 +105,7 @@ class FInterfaceStubGenerator { */ «FOR broadcast : fInterface.broadcasts» «IF broadcast.selective != null» - CommonAPI::ClientIdList «broadcast.stubAdapterClassSubscriberListPropertyName»; + std::shared_ptr<CommonAPI::ClientIdList> «broadcast.stubAdapterClassSubscriberListPropertyName»; «ENDIF» «ENDFOR» }; @@ -161,7 +170,7 @@ class FInterfaceStubGenerator { */ virtual void «broadcast.stubAdapterClassFireSelectiveMethodName»(«generateSendSelectiveSignatur(broadcast, fInterface, true)») = 0; /// retreives the list of all subscribed clients for «broadcast.name» - virtual CommonAPI::ClientIdList* const «broadcast.stubAdapterClassSubscribersMethodName»() = 0; + virtual std::shared_ptr<CommonAPI::ClientIdList> const «broadcast.stubAdapterClassSubscribersMethodName»() = 0; /// Hook method for reacting on new subscriptions or removed subscriptions respectively for selective broadcasts. virtual void «broadcast.subscriptionChangedMethodName»(const std::shared_ptr<CommonAPI::ClientId> clientId, const CommonAPI::SelectiveBroadcastSubscriptionEvent event) = 0; /// Hook method for reacting accepting or denying new subscriptions @@ -171,6 +180,12 @@ class FInterfaceStubGenerator { virtual void «broadcast.stubAdapterClassFireEventMethodName»(«broadcast.outArgs.map['const ' + getTypeName(fInterface.model) + '& ' + name].join(', ')») = 0; «ENDIF» «ENDFOR» + + «FOR managed : fInterface.managedInterfaces» + virtual «managed.stubRegisterManagedMethod» = 0; + virtual bool «managed.stubDeregisterManagedName»(const std::string&) = 0; + virtual std::set<std::string>& «managed.stubManagedSetGetterName»() = 0; + «ENDFOR» }; «fInterface.model.generateNamespaceEndDeclaration» @@ -185,6 +200,7 @@ class FInterfaceStubGenerator { #define «fInterface.defineName»_STUB_DEFAULT_H_ #include <«fInterface.stubHeaderPath»> + #include <sstream> «fInterface.model.generateNamespaceBeginDeclaration» @@ -224,7 +240,7 @@ class FInterfaceStubGenerator { «FTypeGenerator::generateComments(broadcast, false)» «IF !broadcast.selective.nullOrEmpty» virtual void «broadcast.stubAdapterClassFireSelectiveMethodName»(«generateSendSelectiveSignatur(broadcast, fInterface, true)»); - virtual CommonAPI::ClientIdList* const «broadcast.stubAdapterClassSubscribersMethodName»(); + virtual std::shared_ptr<CommonAPI::ClientIdList> const «broadcast.stubAdapterClassSubscribersMethodName»(); /// Hook method for reacting on new subscriptions or removed subscriptions respectively for selective broadcasts. virtual void «broadcast.subscriptionChangedMethodName»(const std::shared_ptr<CommonAPI::ClientId> clientId, const CommonAPI::SelectiveBroadcastSubscriptionEvent event); /// Hook method for reacting accepting or denying new subscriptions @@ -233,6 +249,13 @@ class FInterfaceStubGenerator { virtual void «broadcast.stubAdapterClassFireEventMethodName»(«broadcast.outArgs.map['const ' + getTypeName(fInterface.model) + '& ' + name].join(', ')»); «ENDIF» «ENDFOR» + + «FOR managed : fInterface.managedInterfaces» + bool «managed.stubRegisterManagedAutoName»(std::shared_ptr<«managed.stubClassName»>); + «managed.stubRegisterManagedMethod»; + bool «managed.stubDeregisterManagedName»(const std::string&); + std::set<std::string>& «managed.stubManagedSetGetterName»(); + «ENDFOR» protected: «FOR attribute : fInterface.attributes» @@ -264,6 +287,9 @@ class FInterfaceStubGenerator { }; RemoteEventHandler remoteEventHandler_; + «IF !fInterface.managedInterfaces.empty» + uint32_t autoInstanceCounter_; + «ENDIF» «FOR attribute : fInterface.attributes» «FTypeGenerator::generateComments(attribute, false)» @@ -283,6 +309,9 @@ class FInterfaceStubGenerator { «fInterface.model.generateNamespaceBeginDeclaration» «fInterface.stubDefaultClassName»::«fInterface.stubDefaultClassName»(): + «IF !fInterface.managedInterfaces.empty» + autoInstanceCounter_(0), + «ENDIF» remoteEventHandler_(this) { } @@ -371,7 +400,7 @@ class FInterfaceStubGenerator { // Accept in default return true; } - CommonAPI::ClientIdList* const «fInterface.stubDefaultClassName»::«broadcast.stubAdapterClassSubscribersMethodName»() { + std::shared_ptr<CommonAPI::ClientIdList> const «fInterface.stubDefaultClassName»::«broadcast.stubAdapterClassSubscribersMethodName»() { return(stubAdapter_->«broadcast.stubAdapterClassSubscribersMethodName»()); } @@ -381,6 +410,25 @@ class FInterfaceStubGenerator { } «ENDIF» «ENDFOR» + + «FOR managed : fInterface.managedInterfaces» + bool «fInterface.stubDefaultClassName»::«managed.stubRegisterManagedAutoName»(std::shared_ptr<«managed.stubClassName»> stub) { + autoInstanceCounter_++; + std::stringstream ss; + ss << stubAdapter_->getInstanceId() << "." << autoInstanceCounter_; + std::string instance = ss.str(); + return stubAdapter_->«managed.stubRegisterManagedName»(stub, instance); + } + bool «fInterface.stubDefaultClassName»::«managed.stubRegisterManagedMethodImpl» { + return stubAdapter_->«managed.stubRegisterManagedName»(stub, instance); + } + bool «fInterface.stubDefaultClassName»::«managed.stubDeregisterManagedName»(const std::string& instance) { + return stubAdapter_->«managed.stubDeregisterManagedName»(instance); + } + std::set<std::string>& «fInterface.stubDefaultClassName»::«managed.stubManagedSetGetterName»() { + return stubAdapter_->«managed.stubManagedSetGetterName»(); + } + «ENDFOR» «fInterface.stubDefaultClassName»::RemoteEventHandler::RemoteEventHandler(«fInterface.stubDefaultClassName»* defaultStub): defaultStub_(defaultStub) { diff --git a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FTypeGenerator.xtend b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FTypeGenerator.xtend index 12686ee..4315e31 100644 --- a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FTypeGenerator.xtend +++ b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FTypeGenerator.xtend @@ -46,7 +46,7 @@ class FTypeGenerator { return true; } return false - } + } def static sortAnnotations(FAnnotationBlock annots) { var ArrayList<ArrayList<FAnnotation>> ret = new ArrayList<ArrayList<FAnnotation>>(4) @@ -417,6 +417,9 @@ class FTypeGenerator { inArgs.forEach[type.derived?.addRequiredHeaders(generatedHeaders, libraryHeaders)] outArgs.forEach[type.derived?.addRequiredHeaders(generatedHeaders, libraryHeaders)] ] + fInterface.managedInterfaces.forEach[ + generatedHeaders.add(stubHeaderPath) + ] fInterface.broadcasts.forEach[outArgs.forEach[type.derived?.addRequiredHeaders(generatedHeaders, libraryHeaders)]] generatedHeaders.remove(fInterface.headerPath) diff --git a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGenerator.xtend b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGenerator.xtend index de2e6ca..6f7b8c6 100644 --- a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGenerator.xtend +++ b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGenerator.xtend @@ -190,7 +190,7 @@ class FrancaGenerator implements IGenerator { it.generateStub(fileSystemAccess, res) } ] - + return; } @@ -215,6 +215,7 @@ class FrancaGenerator implements IGenerator { def private getAllReferencedFInterfaces(FModel fModel) { val referencedFInterfaces = fModel.interfaces.toSet fModel.interfaces.forEach[base?.addFInterfaceTree(referencedFInterfaces)] + fModel.interfaces.forEach[managedInterfaces.forEach[addFInterfaceTree(referencedFInterfaces)]] return referencedFInterfaces } diff --git a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGeneratorExtensions.xtend b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGeneratorExtensions.xtend index 8e899fd..eedbeff 100644 --- a/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGeneratorExtensions.xtend +++ b/org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGeneratorExtensions.xtend @@ -44,7 +44,6 @@ import org.franca.core.franca.FTypedElement import java.util.Collection import org.genivi.commonapi.core.preferences.FPreferences import org.osgi.framework.FrameworkUtil -import org.eclipse.core.runtime.QualifiedName import org.eclipse.core.resources.IResource import org.osgi.framework.Version @@ -339,7 +338,7 @@ class FrancaGeneratorExtensions { if (!fBroadcast.outArgs.empty) signature = signature + ', ' - signature = signature + 'const CommonAPI::ClientIdList* receivers' + signature = signature + 'const std::shared_ptr<CommonAPI::ClientIdList> receivers' if (withDefault) signature = signature + ' = NULL' @@ -999,4 +998,40 @@ class FrancaGeneratorExtensions { } return builder.toString() } + + def stubManagedSetName(FInterface fInterface) { + 'registered' + fInterface.name + 'Instances' + } + + def stubManagedSetGetterName(FInterface fInterface) { + 'get' + fInterface.name + 'Instances' + } + + def stubRegisterManagedName(FInterface fInterface) { + 'registerManagedStub' + fInterface.name + } + + def stubRegisterManagedAutoName(FInterface fInterface) { + 'registerManagedStub' + fInterface.name + 'AutoInstance' + } + + def stubRegisterManagedMethod(FInterface fInterface) { + 'bool ' + fInterface.stubRegisterManagedName + '(std::shared_ptr<' + fInterface.stubClassName + '>, const std::string&)' + } + + def stubRegisterManagedMethodImpl(FInterface fInterface) { + fInterface.stubRegisterManagedName + '(std::shared_ptr<' + fInterface.stubClassName + '> stub, const std::string& instance)' + } + + def stubDeregisterManagedName(FInterface fInterface) { + 'deregisterManagedStub' + fInterface.name + } + + def proxyManagerGetterName(FInterface fInterface) { + 'getProxyManager' + fInterface.name + } + + def proxyManagerMemberName(FInterface fInterface) { + 'proxyManager' + fInterface.name + '_' + } } |