@@ -92,26 +92,28 @@ The following sequence shows the instantiation of a service class up to its serv
9292
9393<img alt =" SKELETON_CREATE_OFFER_SEQ " src =" https://www.plantuml.com/plantuml/proxy?src=https://raw.githubusercontent.com/eclipse-score/communication/refs/heads/main/score/mw/com/design/skeleton_proxy/skeleton_create_offer_seq.puml " >
9494
95- #### Binding independent level Registration of skeleton events/fields at their parent skeleton
95+ #### Binding independent level Registration of skeleton events/fields/methods at their parent skeleton
9696
9797Due to our architectural constraints, the ` impl::SkeletonBase ` (the base class of the generated skeleton/` DummySkeleton ` )
98- doesn't "know" its event/field children. Because events/fields are the members of the generated skeleton and not the
99- ` impl::SkeletonBase ` . But for various functionalities, we require the ` impl::SkeletonBase ` to have access to its
100- events/fields.
101- This is solved by a mechanism, where the event/field members of the generated skeleton class register themselves at
102- their parent skeleton, which they got by reference during their creation/` ctor ` call. So in their ` ctor ` they are
103- calling ` impl::SkeletonBase::RegisterEvent() ` resp. ` impl::SkeletonBase::RegisterField() ` , with their own reference and
104- name. So after creation of a generated skeleton, its base class (` impl::SkeletonBase ` ) has all the event/field members
105- stored in ` protected ` members ` events_ ` and ` fields_ ` , so that in the future these could be even made ` public `
106- accessible to the generated (user facing) skeleton. Since these user facing skeletons have discrete event/field
107- members anyhow, there is currently no need for such a generalized event/field access.
108-
109- So while we have this relation/accessibility of events/fields from the "parent" skeleton on the binding ** independent**
98+ doesn't "know" its event/field/method children. Because events/fields/methods are the members of the generated skeleton
99+ and not the ` impl::SkeletonBase ` . But for various functionalities, we require the ` impl::SkeletonBase ` to have access to
100+ its children.
101+ This is solved by a mechanism, where the event/field/method members of the generated skeleton class register themselves
102+ at their parent skeleton, which they got by reference during their creation/` ctor ` call. So in their ` ctor ` they are
103+ calling ` impl::SkeletonBase::RegisterEvent() ` , ` impl::SkeletonBase::RegisterField() ` or
104+ ` impl::SkeletonBase::RegisterMethod() ` , with their own ` special reference ` (see below) and name. So after creation of a
105+ generated skeleton, its base class (` impl::SkeletonBase ` ) has all the event/field/method members stored in ` protected `
106+ members ` events_ ` , ` fields_ ` and ` methods_ ` , so that in the future these could be even made ` public `
107+ accessible to the generated (user facing) skeleton. Since these user facing skeletons have discrete event/field/method
108+ members anyhow, there is currently no need for such a generalized access.
109+
110+ So while we have this relation/accessibility of children from the "parent" skeleton on the binding ** independent**
110111level, we ** don't** have a symmetric setup on the binding ** dependent** level. The binding specific implementation of
111112` SkeletonBinding ` , where ` impl::SkeletonBase ` is dispatching to via the ` pImpl ` idiom doesn't "know" its corresponding
112- binding specific events and fields, which would be represented ** both** as ` SkeletonEventBinding ` (as our field is a
113+ binding specific events, fields, which would be represented ** both** as ` SkeletonEventBinding ` (as our field is a
113114composite, which dispatches to ` impl::SkeletonEventBase ` , which then &ndash ; also via ` pImpl ` idiom &ndash ; dispatches
114- to the binding specific ` SkeletonEventBinding ` [ see here] ( #../todo ) ).
115+ to the binding specific ` SkeletonEventBinding ` [ see here] ( #../todo ) ). Nor does it know its binding specific methods,
116+ which would be represented as ` SkeletonMethodBinding ` .
115117
116118This symmetry isn't currently needed as we don't have any use case yet, where on the binding dependent level our
117119` lola::Skeleton ` (implementing ` SkeletonBinding ` ) would need to call functionality on its events/fields!
@@ -123,6 +125,39 @@ implementation of `SkeletonBinding`, since we do not have (yet) a field specific
123125whether we have to deal with a "pure" event or the "event part" of a field, we would resort to checking the related
124126` ElementFqId ` , which contains this differentiation.
125127
128+ #### How we handle moving of skeletons and their events/fields
129+
130+ In the previous section we have seen, that impl::SkeletonEvent, impl::SkeletonField and impl::SkeletonMethod register
131+ themselves at their parent ` impl::SkeletonBase ` during their construction with a reference to their parent.
132+ The special reference is obviously not a normal reference, but a ` ReferenceToMoveable<SkeletonEventBase>::Reference ` type
133+ (or ` ReferenceToMoveable<SkeletonFieldBase>::Reference ` resp. ` ReferenceToMoveable<SkeletonMethodBase>::Reference ` ).
134+ Why is that? If we stored a normal reference to the event/field/method in the parent skeleton, we would have the
135+ following problem: whenever the event/field/method instances get moved (which happens, when the user moves his outer
136+ skeleton instance), the references within the ` impl::SkeletonBase ` need to be updated. To accomplish this, the
137+ event/field/method instances would also need a reference to their parent () to do the update! This again complicates
138+ things further! In case the ` impl::SkeletonBase ` moves (also happens, when the user moves his outer skeleton instance),
139+ then also the parent reference has to be updated within all the event/field/method instances.
140+
141+ Our solution to this issue is the following:
142+ For each event/field/method instance, we store a ` ReferenceToMoveable<T>::Reference ` on the heap.
143+ ` T ` is in this case one of:
144+
145+ - ` SkeletonEventBase `
146+ - ` SkeletonFieldBase `
147+ - ` SkeletonMethodBase `
148+
149+ This "special reference" is created during the construction of the event/field/method instance and is passed to the
150+ ` impl::SkeletonBase ` during the registration call by reference. But since the ` ReferenceToMoveable<T>::Reference ` is
151+ stored on the heap and is ** neither** copyable nor moveable, it doesn't get moved when the event/field/method is moved!
152+ Instead, the ` ReferenceToMoveable<T>::Reference ` instance is updated with the new address of the moved event/field/method
153+ instance within the move constructor/move assign op of the event/field/method. So the ` impl::SkeletonBase ` always has a
154+ valid reference to the event/field/method instance, even if the user moves the outer skeleton instance as long as it
155+ uses the ` ReferenceToMoveable<T>::Reference::Get() ` API to access the event/field/method instance!
156+
157+ The mechanism to provide such a "special reference" for ` impl::SkeletonEventBase ` , ` impl::SkeletonFieldBase ` and
158+ ` impl::SkeletonMethodBase ` is realized by inheriting from ` EnableReferenceToMoveableFromThis<T> ` , where ` T ` is one of
159+ the above-mentioned types. making it a ` CRTP ` pattern!
160+
126161#### LoLa binding level Registration of skeleton events/fields at their parent skeleton
127162
128163Despite the last paragraph in the previous chapter, we are doing still "some registration" in our ` LoLa ` /shared-memory
0 commit comments