summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schanda <schanda@itestra.de>2013-09-17 14:08:26 +0200
committerPhilip Rauwolf <rauwolf@itestra.de>2013-09-18 18:16:43 +0200
commitf351f3415cc5fe1bd3e70eded698274abdeb0e52 (patch)
treef495aafaa77e38873e85a44571667e9fe53916f5
parent774d43c5791f69093a233f0c4d1fe217105401fd (diff)
downloadgenivi-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
-rw-r--r--CommonAPI-Examples/Makefile.am15
-rw-r--r--CommonAPI-Examples/configure.ac2
-rw-r--r--CommonAPI-Examples/src/helloworld-proxy.cpp36
-rw-r--r--CommonAPI-Examples/src/helloworld-stub.cpp48
-rw-r--r--CommonAPI-Examples/src/helloworld.fidl20
-rw-r--r--Tutorial142
-rw-r--r--org.genivi.commonapi.core.verification/src/VerificationTestStub.cpp3
-rw-r--r--org.genivi.commonapi.core.verification/src/VerificationTestStub.h3
-rw-r--r--org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceGenerator.xtend8
-rw-r--r--org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceProxyGenerator.xtend66
-rw-r--r--org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FInterfaceStubGenerator.xtend58
-rw-r--r--org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FTypeGenerator.xtend5
-rw-r--r--org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGenerator.xtend3
-rw-r--r--org.genivi.commonapi.core/src/org/genivi/commonapi/core/generator/FrancaGeneratorExtensions.xtend39
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
diff --git a/Tutorial b/Tutorial
index 1e22d98..c6dee22 100644
--- a/Tutorial
+++ b/Tutorial
@@ -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 + '_'
+ }
}