Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
2012/11/29 luiz americo pereira camara : > > There's a more concrete example about the duplicate typecast. > > I'm developing a model manager that would be responsible to easily > create LCL forms/frames, html forms, LazReport reports etc with the > same set of data/models > > Each project has a TModels collection with a TModel item > Each TMode item has a TFields collection with a TField item > Each TField has a unique Id managed per project > Currently to set the id of new Fields i have a circular reference > TField <> Project > My idea is to isolate TModel/TField to be independent of TProject > I can add a intermediate class to connect each other > But i could also takes advantage of Observer so i could observe the > Fields collection of each TModel to update the id when is added > The idea is add a FieldsObserver property to TModels and attach it to > each TModel > > It can be done as today?. Sure. My concerns are > > - I cannot define FieldsObserver as IFPObserver (the reasons why do i > prefer as it are above) > - Using FieldsObserver as TObject each time i attach/dettach from a > TFields there will be a type cast that i know before hand is not > necessary and could avoid. Attached is the classes as is today. I'll try to get rid of circular dependency from TProject using the observer pattern. I 'll post the result later Luiz datamodelclasses.pas Description: Binary data ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
2012/11/29 : > > > On Thu, 29 Nov 2012, luiz americo pereira camara wrote: > > > Yes. I still do not see how your example shows this ? > > Your wizard knows it can observe. It attaches itself to the frame. > The code frame does not need to know the observing object ? Yes, you are right in this wizard case the page owner would know it's an observer. [] >> It can crash since not necessarily owner (e.g. a simple TForm) will >> implements IFPObserver? > > > Who takes the decision to observe or not ? The TForm, I assume. > Somewhere the decision is made. In this location you will necessarily know > who will do the observing, and you will know it has IFPObserver. OK >> >> You would not be forced or induced to use an interface it would be >> optional. > > > Eh ? I would need to do a AttachObserver(MyObservingObject as IFPObserver) > everywhere where I want to observe, instead of > AttachObserver(MyObservingObject). > > That is hardly optional ? > It's the small cost i pointed elsewhere. In the other hand makes the code contract (what AttachObserver expects) clear in the declaration. Also improves compiler type check This is a trade off. I see your reason to hides the interface. >> >> BTW: did you read my comment about observer method not being public? >> By the currently implementation to attach a Observer to a TPersistent >> the programmer is _forced_ to use an interface contradicting what you >> said above. > > > I already fixed that. I also fixed the sender problem. In my cases I always > had (Sender=Self). > Thanks Did you read the TGUID (not necessary) part? >> I know what to expect when i see an IFPObserver property but not when >> i see an TObject (although i can guess by the name). > > > I am sorry, but I really still do not understand your problem with the > interface. > > Contrary to what it may look like, it is not so that I am dead set against > such a change. However, to me, your change presents a serious disadvantage. > Therefore I expect you at least to show to me that there is a substantial > need or benefit in this for all of us. > > Because till now I simply do not see the need or benefit... In the program that i mentioned in other message there's a use case for observer. I'll try to implement it and post the result here. Luiz ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
Hello luiz, Thursday, November 29, 2012, 9:39:36 PM, you wrote: > In the message of the example observer: It seems Gmail searching has failed me. Thanks for fulfilling my curiosity. As for my comment. It was purely a suggestion (for convenience). My personal preference is still to use interface methods only via a interface reference. As I also mentioned in my quoted comment - there is good arguments for doing so. -- Best regards, Graeme fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
2012/11/29 Graeme Geldenhuys : > Hello luiz, > > Thursday, November 29, 2012, 12:31:41 PM, you wrote: > >> BTW: Graeme already pointed, that the Observer methods should be >> public. Does not makes sense to protect methods that are exposed by an >> interface. > > When did I say that? [Though my memory has been failing me once or > twice. :)] In the message of the example observer: " 1) I would probably surface the IFPObserver methods to Public. Though there is good arguments to not do it either - thus you are forced to use correct interface usage... via Supports(), getting a interface pointer back, and using that interface pointer to make method calls. " Luiz ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
Hello luiz, Thursday, November 29, 2012, 12:31:41 PM, you wrote: > BTW: Graeme already pointed, that the Observer methods should be > public. Does not makes sense to protect methods that are exposed by an > interface. When did I say that? [Though my memory has been failing me once or twice. :)] As far as I'm concerned it should be the other way round. Interface implementations should all be done private - because you should always access those interface methods using an Interface reference. That's the way I do it in my own code. -- Best regards, Graeme ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
On Thu, 29 Nov 2012, luiz americo pereira camara wrote: - I cannot define FieldsObserver as IFPObserver (the reasons why do i prefer as it are above) - Using FieldsObserver as TObject each time i attach/dettach from a TFields there will be a type cast that i know before hand is not necessary and could avoid. That depends on the implementation. Not everybody will have the IFPObserver available as a separate field. I suspect that in many cases, it will be the observer object itself. In that case you would have to do (YourObserverObject as IFPObserver) anyway, and you gain nothing. the 'as' does the same thing as what is now in the implementation of attachobserver... In my proposition, is up to programmer decide if will use TObject or IFPObserver in FieldsObserver, different from today that i'm tied with TObject. Since every object is TObject, I do not see this as a problem. Since in your code you will only attach a FieldsObserver, you lose nothing in the process. Different from what Michael stated in previous email, in my proposition there would be no increase of interface usage in the functionality itself. Just would be explicit to the programmer that this feature requires a interface rather than now, that is hidden in the implementation. That it is hidden, is exactly what I wanted. To me, that is a plus. Anyway, with this I have a clearer example of what you want to achieve. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
On Thu, 29 Nov 2012, luiz americo pereira camara wrote: I fail to see how the current interface forbids this ? It does not forbids. It's just an example of the need to check if a object implements an IFPObserver before attaching it. You have said that there's no real life situation you need to do this check since the programmer should know that implements always before hand Yes. I still do not see how your example shows this ? Your wizard knows it can observe. It attaches itself to the frame. The code frame does not need to know the observing object ? In the two cases one does not know about the other. What links is if the owner implements an interface or not and the implicit contract of this interface usage that is defined by the programmer. So i cannot simply call AttachObserver(Owner). So you say, but you do not explain why not. It can crash since not necessarily owner (e.g. a simple TForm) will implements IFPObserver? Who takes the decision to observe or not ? The TForm, I assume. Somewhere the decision is made. In this location you will necessarily know who will do the observing, and you will know it has IFPObserver. Anyway, to me is clear that you wont change your mind regardless of the arguments i use since you are not willing to change your code that relies on it. No, actually that is the least of my worries. It is an argument, not *the* argument. The argument is: I am not a fan of interfaces, and will avoid them like the plague when possible. The current implementation makes absolute minimal use of them and it works. Your proposal goes against all that I try to avoid, meaning that if I do as you ask, I am in fact changing it to something that I will later try to avoid as much as possible ? You would not be forced or induced to use an interface it would be optional. Eh ? I would need to do a AttachObserver(MyObservingObject as IFPObserver) everywhere where I want to observe, instead of AttachObserver(MyObservingObject). That is hardly optional ? Other programmer can have a different view/need of you. It's up to him decide what to use. BTW: did you read my comment about observer method not being public? By the currently implementation to attach a Observer to a TPersistent the programmer is _forced_ to use an interface contradicting what you said above. I already fixed that. I also fixed the sender problem. In my cases I always had (Sender=Self). I am willing to do this for the sake of FPC in general, but then you'll have to convince me of the huge benefits this change will bring. OK You now present a use case where you do not want to change your own implementation in order to be able to use Observer ? As i said Observer would simplify the usage, so i'm willing to change my code. OK. When in fact you could most likely perfectly use it as it is (see the "as TObject" elsewhere), or in the worst case slightly change your interface so the observer support can be used. All you need to do is 'expose' the observer TObject (implicitly or explicitly). I hardly see how this compromises your interface/implementation separation, by definition it is a TObject anyway ? I know what to expect when i see an IFPObserver property but not when i see an TObject (although i can guess by the name). I am sorry, but I really still do not understand your problem with the interface. Contrary to what it may look like, it is not so that I am dead set against such a change. However, to me, your change presents a serious disadvantage. Therefore I expect you at least to show to me that there is a substantial need or benefit in this for all of us. Because till now I simply do not see the need or benefit... Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
2012/11/29 Graeme Geldenhuys : > Hi Luiz, > > First off, thanks for take the trouble it creating test projects. > Thanks for looking at them ;-) > > On 2012-11-29 02:59, luiz americo pereira camara wrote: >> >> Test1 >> As is today, if you have a reference to a IFPObserver is not possible >> to use it to attach to, e.g., child objects. This occurs because AFAIK >> you can't get a TObject from a interface reference. > > > OK, there are quite a few things I consider wrong with your Test1 > application. > > 1) Nothing stops Michael from extending the IPFObserver interface to > include a GetObject function that returns a TObject reference of > the observer. > I have seen many such cases in the wild. Not sure if I agree > with it, but that is another story. Yep but would be yet another type cast although Sven have concerns about if is really possible > 2) What exactly are you observing in Test1? What are you trying to > accomplish? It's just to say that sometimes you have only an interface reference (in the case IFPObserver) In some of my code i have properties of an interface type like IPageController. So i know what it does (or what is supposed todo) and i'm not tied for any specific implementation or class. In this case a IPageController can be a non visual component placed in a form that controls the page behavior or it can be TTreeView or TListBox descendant > > 4) If you change FChildren to TObjectList, then it can be observer. > Then simply attach observers directly to the Children property. That > way if you add or remove children, the observers are notified. The example was simply a quick demo. Think Children as private and not necessarily a TObjectList or TList, just an structure that holds more than one object that can be observed by the same observer. BTW: the objective of Test2 is to show that it can be unnecessary typecasts. In the example if Observer was IFPObserver no type casts would be done when attaching child objects > 5) I guess this depends on what you want to accomplish. But if you > first add children, then only call Initialize, then the observer > will never be notified that children was added to the list. > It was actually hard to figure out what you are trying to accomplish > with your test project. I think I'm still unclear of this. I'm seriously > under the weather at the moment (bad case of flu), so that probably > affects my judgement. So if I misinterpreted your Test project, please > do let me know. In the mean time, I modified your test1 (see attached). > The Observer now observes the Children List, and each Child - again, not > 100% sure what you wanted to accomplish. See above There's a more concrete example about the duplicate typecast. I'm developing a model manager that would be responsible to easily create LCL forms/frames, html forms, LazReport reports etc with the same set of data/models Each project has a TModels collection with a TModel item Each TMode item has a TFields collection with a TField item Each TField has a unique Id managed per project Currently to set the id of new Fields i have a circular reference TField <> Project My idea is to isolate TModel/TField to be independent of TProject I can add a intermediate class to connect each other But i could also takes advantage of Observer so i could observe the Fields collection of each TModel to update the id when is added The idea is add a FieldsObserver property to TModels and attach it to each TModel It can be done as today?. Sure. My concerns are - I cannot define FieldsObserver as IFPObserver (the reasons why do i prefer as it are above) - Using FieldsObserver as TObject each time i attach/dettach from a TFields there will be a type cast that i know before hand is not necessary and could avoid. In my proposition, is up to programmer decide if will use TObject or IFPObserver in FieldsObserver, different from today that i'm tied with TObject. Different from what Michael stated in previous email, in my proposition there would be no increase of interface usage in the functionality itself. Just would be explicit to the programmer that this feature requires a interface rather than now, that is hidden in the implementation. BTW: TField name is abbreviated so no clash with db.TField Luiz ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
2012/11/29 : > > > On Thu, 29 Nov 2012, luiz americo pereira camara wrote: > >> >> >> Well i have at least two situations, with code that is already >> running, that the observer pattern would fit as i described. >> >> - I implemented a Wizard Page component where i can attach a page to >> any TFrame. Each page can be assigned as an instance or it can be >> created at demand when is entered. Optionally the TFrame (Observed) >> can implement a CORBA interface to communicate with the wizard >> controller (Observer). This same TFrame can be used elsewhere, e.g, in >> a configuration page, in this case, the wizard functionality will be >> ignored since there's no observer. >> >> I could use the native Observer support to simplify the interface, >> making easier implement. > > > I still do not see how this is forbidden by the observers as they work now. >> >> - I have a code that takes a TFrame and show as dialog with some >> configurable buttons. To communicate to inform of state changes i use >> LCL messages that is really cumbersome. >> >> I could use the native observer support also. So if something changed >> in the TFrame i could enable the save button or popup a dialog to save >> the changes. If this same frame is used every where the Notidications >> would be discarded since there's no observer > > > I fail to see how the current interface forbids this ? It does not forbids. It's just an example of the need to check if a object implements an IFPObserver before attaching it. You have said that there's no real life situation you need to do this check since the programmer should know that implements always before hand > > >> In the two cases one does not know about the other. What links is if >> the owner implements an interface or not and the implicit contract of >> this interface usage that is defined by the programmer. So i cannot >> simply call AttachObserver(Owner). > > > So you say, but you do not explain why not. > It can crash since not necessarily owner (e.g. a simple TForm) will implements IFPObserver? >> Anyway, to me is clear that you wont change your mind regardless of >> the arguments i use since you are not willing to change your code that >> relies on it. > > > No, actually that is the least of my worries. It is an argument, not *the* > argument. > > The argument is: > > I am not a fan of interfaces, and will avoid them like the plague when > possible. The current implementation makes absolute minimal use of them and > it works. > > Your proposal goes against all that I try to avoid, meaning that if I do as > you ask, I am in fact changing it to something that I will later try to > avoid as much as possible ? You would not be forced or induced to use an interface it would be optional. Other programmer can have a different view/need of you. It's up to him decide what to use. BTW: did you read my comment about observer method not being public? By the currently implementation to attach a Observer to a TPersistent the programmer is _forced_ to use an interface contradicting what you said above. > > I am willing to do this for the sake of FPC in general, but then you'll have > to convince me of the huge benefits this change will bring. OK > You now present a use case where you do not want to change your own > implementation in order to be able to use Observer ? As i said Observer would simplify the usage, so i'm willing to change my code. > When in fact you could most likely perfectly use it as it is (see the "as > TObject" elsewhere), or in the worst case slightly change your interface so > the observer support can be used. > > All you need to do is 'expose' the observer TObject (implicitly or > explicitly). I hardly see how this compromises your interface/implementation > separation, by definition it is a TObject anyway ? I know what to expect when i see an IFPObserver property but not when i see an TObject (although i can guess by the name). > So in my eyes, you fail to present a clear use case to show that > use of interfaces would actually be beneficial for the majority of intended > use cases of observers. Ok. Thanks for taking your time reading my comments Luiz ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
Am 29.11.2012 10:44, schrieb michael.vancann...@wisa.be: On Thu, 29 Nov 2012, Sven Barth wrote: Am 29.11.2012 03:59, schrieb luiz americo pereira camara: As is today, if you have a reference to a IFPObserver is not possible to use it to attach to, e.g., child objects. This occurs because AFAIK you can't get a TObject from a interface reference. At least for COM interfaces "as" and "is" with a class type on the right side is supported. The corresponding code for Corba interfaces is not implemented (yet). This feature exists at least since 2.6.0. Well. I did not know of this feature. I should document it :-) It's also supported by newer Delphi versions (I don't know from when on though...) interfaces: What routine needs to be implemented to do this for Corba interfaces ? After thinking this through a bit I don't think that this will be possible... the "intf as class" and "intf is class" code relies no the existence of the QueryInterface function which is not supported by CORBA interfaces. It's also not possible to cast a CORBA interfaces to a another CORBA interface (or even a COM interface) exactly because of this. Nevertheless the corresponding RTL code is located in rtl/inc/objpas.inc from ~ line 110 to ~ line 270 (these are the compilerprocs which are used by the compiler). Of course compiler code would be needed as well... Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
On Thu, 29 Nov 2012, luiz americo pereira camara wrote: Well i have at least two situations, with code that is already running, that the observer pattern would fit as i described. - I implemented a Wizard Page component where i can attach a page to any TFrame. Each page can be assigned as an instance or it can be created at demand when is entered. Optionally the TFrame (Observed) can implement a CORBA interface to communicate with the wizard controller (Observer). This same TFrame can be used elsewhere, e.g, in a configuration page, in this case, the wizard functionality will be ignored since there's no observer. I could use the native Observer support to simplify the interface, making easier implement. I still do not see how this is forbidden by the observers as they work now. - I have a code that takes a TFrame and show as dialog with some configurable buttons. To communicate to inform of state changes i use LCL messages that is really cumbersome. I could use the native observer support also. So if something changed in the TFrame i could enable the save button or popup a dialog to save the changes. If this same frame is used every where the Notidications would be discarded since there's no observer I fail to see how the current interface forbids this ? In the two cases one does not know about the other. What links is if the owner implements an interface or not and the implicit contract of this interface usage that is defined by the programmer. So i cannot simply call AttachObserver(Owner). So you say, but you do not explain why not. Anyway, to me is clear that you wont change your mind regardless of the arguments i use since you are not willing to change your code that relies on it. No, actually that is the least of my worries. It is an argument, not *the* argument. The argument is: I am not a fan of interfaces, and will avoid them like the plague when possible. The current implementation makes absolute minimal use of them and it works. Your proposal goes against all that I try to avoid, meaning that if I do as you ask, I am in fact changing it to something that I will later try to avoid as much as possible ? I am willing to do this for the sake of FPC in general, but then you'll have to convince me of the huge benefits this change will bring. You now present a use case where you do not want to change your own implementation in order to be able to use Observer ? When in fact you could most likely perfectly use it as it is (see the "as TObject" elsewhere), or in the worst case slightly change your interface so the observer support can be used. All you need to do is 'expose' the observer TObject (implicitly or explicitly). I hardly see how this compromises your interface/implementation separation, by definition it is a TObject anyway ? So in my eyes, you fail to present a clear use case to show that use of interfaces would actually be beneficial for the majority of intended use cases of observers. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
On 2012-11-29 12:10, michael.vancann...@wisa.be wrote: > > The primary reason of existence for TFPList and TFPObjectList is speed and > minimal overhead. OK, I understand now. Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
2012/11/29 : > > > On Wed, 28 Nov 2012, luiz americo pereira camara wrote: > >> Given the considerations i did about the observer feature, here are >> some simple projects that supports my concerns and therefore the >> request i made to change the interface of two functions. >> >> Test1 >> As is today, if you have a reference to a IFPObserver is not possible >> to use it to attach to, e.g., child objects. This occurs because AFAIK >> you can't get a TObject from a interface reference. >> >> This limits the programmer choice to use a TObject in such situations, >> in this case the Observer property. > > > All objects in memory descend from TObject, so this is not a problem. > COM provided objects are not supported. That would require COM interfaces. > > I have looked at your tests. They are IMHO rather theoretical and will not > happen in real life. I can think of plenty of things that will not work even > with TComponent or TObject. That doesn't mean they will happen. > > Your 'problem' is that you store only interfaces for objects that will > observe. Indeed, this is a programming model I do not care to support *for > observers*, because I do not think it is likely to happen in real life > situations. > I explain this below. > > >> Test3 >> Pretty simple: if you don't know if a TObject descendant instance >> implements a IFPObserver (most cases) you have to do a check before >> attaching to a IFPObserved otherwise an exception is raised. > > > Let me get this straight: > > What you say is that you get from somewhere an unknown object (or an > interface) and just decide to let it observe another object ? For what ? For > fun ? > That is a very strange argument. You don't "accidentally" observe. > It is also not true that all objects A that have the IFPObserver interface > are suitable to observe a particular object B. > > You observe for a purpose. I'll say even more: in most cases your observer > will be written to specifically observe the observed class. > > You will not let object A observe object B for no good reason. > Observing introduces an overhead. For this reason alone, you should not > 'just observe'. > > A will observe B in order to react on changes that B reports, > and A will act on these changes. In almost all cases, A will have specific > knowledge about B: even if it is just that B has a published property named > XYZ. > > So you will know in advance that when attaching A to B, that A will have the > IFPObserver interface. Well i have at least two situations, with code that is already running, that the observer pattern would fit as i described. - I implemented a Wizard Page component where i can attach a page to any TFrame. Each page can be assigned as an instance or it can be created at demand when is entered. Optionally the TFrame (Observed) can implement a CORBA interface to communicate with the wizard controller (Observer). This same TFrame can be used elsewhere, e.g, in a configuration page, in this case, the wizard functionality will be ignored since there's no observer. I could use the native Observer support to simplify the interface, making easier implement. - I have a code that takes a TFrame and show as dialog with some configurable buttons. To communicate to inform of state changes i use LCL messages that is really cumbersome. I could use the native observer support also. So if something changed in the TFrame i could enable the save button or popup a dialog to save the changes. If this same frame is used every where the Notidications would be discarded since there's no observer In the two cases one does not know about the other. What links is if the owner implements an interface or not and the implicit contract of this interface usage that is defined by the programmer. So i cannot simply call AttachObserver(Owner). Anyway, to me is clear that you wont change your mind regardless of the arguments i use since you are not willing to change your code that relies on it. The alternative i proposed does not forbid the current usage pattern, just add an option with possible performance benefits with no, or very small, costs. Generally now, it's up to the programmer takes what way best fit his need and if a pattern is not used by a programmer, how good or experienced he is, does not mean there are not valid usage scenarios. This is even more true with new stuff that still not exposed for a wider audience. I won't discuss this more, the arguments are there to anyone judge. BTW: Graeme already pointed, that the Observer methods should be public. Does not makes sense to protect methods that are exposed by an interface. You can just do (APersistent as IFPObserved).FPOAttachObserver. And yes, i have real life examples that should be useful. Also in TPersistent.FPONotifyObservers you should not be using ASender in Obs.FPOObservedChanged? Luiz ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
On Thu, 29 Nov 2012, Graeme Geldenhuys wrote: Hi Luiz, First off, thanks for take the trouble it creating test projects. On 2012-11-29 02:59, luiz americo pereira camara wrote: Test1 As is today, if you have a reference to a IFPObserver is not possible to use it to attach to, e.g., child objects. This occurs because AFAIK you can't get a TObject from a interface reference. OK, there are quite a few things I consider wrong with your Test1 application. 1) Nothing stops Michael from extending the IPFObserver interface to include a GetObject function that returns a TObject reference of the observer. I have seen many such cases in the wild. Not sure if I agree with it, but that is another story. 2) What exactly are you observing in Test1? What are you trying to accomplish? TMyParentView is a TObject. Adding children to the Children property doesn't notify the observer about anything. ... now if the Observer property is holding reference to something that should observer each of the Children, well, then that is very easy to accomplish too. Simply changes the Observer property to a TObject instance. 3) Something Michael should fix. TFPObjectList doesn't support IPFObserver. TObjectList does though. I guess many of the list classes in the Contnrs unit should be double checked. No. This is left out on purpose. If you want observer support, you need TObjectList and TList. The primary reason of existence for TFPList and TFPObjectList is speed and minimal overhead. TList and it's observer/notification capabilities introduce a serious speed penalty. For instance when doing a Clear, all items are removed one by one as opposed to just de-allocating the array used to hold them. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
Hi Luiz, First off, thanks for take the trouble it creating test projects. On 2012-11-29 02:59, luiz americo pereira camara wrote: > > Test1 > As is today, if you have a reference to a IFPObserver is not possible > to use it to attach to, e.g., child objects. This occurs because AFAIK > you can't get a TObject from a interface reference. OK, there are quite a few things I consider wrong with your Test1 application. 1) Nothing stops Michael from extending the IPFObserver interface to include a GetObject function that returns a TObject reference of the observer. I have seen many such cases in the wild. Not sure if I agree with it, but that is another story. 2) What exactly are you observing in Test1? What are you trying to accomplish? TMyParentView is a TObject. Adding children to the Children property doesn't notify the observer about anything. ... now if the Observer property is holding reference to something that should observer each of the Children, well, then that is very easy to accomplish too. Simply changes the Observer property to a TObject instance. 3) Something Michael should fix. TFPObjectList doesn't support IPFObserver. TObjectList does though. I guess many of the list classes in the Contnrs unit should be double checked. 4) If you change FChildren to TObjectList, then it can be observer. Then simply attach observers directly to the Children property. That way if you add or remove children, the observers are notified. 5) I guess this depends on what you want to accomplish. But if you first add children, then only call Initialize, then the observer will never be notified that children was added to the list. It was actually hard to figure out what you are trying to accomplish with your test project. I think I'm still unclear of this. I'm seriously under the weather at the moment (bad case of flu), so that probably affects my judgement. So if I misinterpreted your Test project, please do let me know. In the mean time, I modified your test1 (see attached). The Observer now observes the Children List, and each Child - again, not 100% sure what you wanted to accomplish. So solving your supposedly "impossible" problem was rather easy. So I'm still on Michael's side that the FPC Observer API needs no change. Regards, - Graeme - -- fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ program ObserverTest1; {$mode objfpc}{$H+} uses Classes, contnrs; type { TMyParentView } TMyParentView = class private FChildren: TObjectList; FObserver: TObject; public constructor Create; destructor Destroy; override; procedure Initialize; property Children: TObjectList read FChildren; property Observer: TObject read FObserver write FObserver; end; { TMyObserver } TMyObserver = class(TObject, IFPObserver) public procedure FPOObservedChanged(ASender : TObject; Operation : TFPObservedOperation; Data : Pointer); end; { TMyObserver } procedure TMyObserver.FPOObservedChanged(ASender: TObject; Operation: TFPObservedOperation; Data: Pointer); begin writeln('Observer changed'); end; constructor TMyParentView.Create; begin writeln('Creating MyParentView...'); FChildren := TObjectList.Create(True); end; destructor TMyParentView.Destroy; var i: Integer; Observed: IFPObserved; Child: TObject; begin writeln('Destroying MyParentView...'); for i := 0 to FChildren.Count-1 do begin Child := FChildren[i]; if Child.GetInterface(SGUIDObserved, Observed) then begin //AFAIK it's not possible to get a TObject instance from an interface reference //so if you have an IFPObserver variable or field it cannot be used to attach dettach to IFPObserved Observed.FPODetachObserver(FObserver); end; end; FChildren.Destroy; inherited Destroy; end; procedure TMyParentView.Initialize; var i: Integer; Observed: IFPObserved; Child: TObject; begin for i := 0 to FChildren.Count-1 do begin Child := FChildren[i]; if Child.GetInterface(SGUIDObserved, Observed) then begin //AFAIK it's not possible to get a TObject instance from an interface reference //so if you have an IFPObserver variable or field it cannot be used to attach dettach to IFPObserved Observed.FPOAttachObserver(FObserver); end; end; end; var View: TMyParentView; ObserverObj: TMyObserver; begin ObserverObj := TMyObserver.Create; View := TMyParentView.Create; View.Observer := ObserverObj; // as IFPObserver; View.Children.FPOAttachObserver(ObserverObj); View.Children.Add(TPersistent.Create); View.Children.Add(TPersistent.Create); View.Children.Add(TPersistent.Create); View.Initialize; //Execute View View.Destroy; ObserverObj.Destroy; end. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/li
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
On Thu, 29 Nov 2012, luiz americo pereira camara wrote: 2012/11/29 : On Thu, 29 Nov 2012, Sven Barth wrote: Am 29.11.2012 03:59, schrieb luiz americo pereira camara: As is today, if you have a reference to a IFPObserver is not possible to use it to attach to, e.g., child objects. This occurs because AFAIK you can't get a TObject from a interface reference. At least for COM interfaces "as" and "is" with a class type on the right side is supported. The corresponding code for Corba interfaces is not implemented (yet). This feature exists at least since 2.6.0. Well. I did not know of this feature. I should document it :-) If so, that solves Luiz' problem, since it would allow him to retrieve the object to use as an observer. I'm assuming that Luiz uses COM interfaces. Again: in this case, i don't use COM interfaces nor do i propose to use That's not what I meant with this statement: I meant that if you do happen to use COM interfaces for everything else, the above means you can get the object that's associated with it and pass it on as an observer, so the current implementation will work for you as it is now. If you use CORBA interfaces, it means you must wait till the corresponding code is implemented (which I am willing to do) for it to work. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
2012/11/29 : > > > On Thu, 29 Nov 2012, Sven Barth wrote: > >> Am 29.11.2012 03:59, schrieb luiz americo pereira camara: >>> >>> As is today, if you have a reference to a IFPObserver is not possible >>> to use it to attach to, e.g., child objects. This occurs because AFAIK >>> you can't get a TObject from a interface reference. >> >> >> At least for COM interfaces "as" and "is" with a class type on the right >> side is supported. The corresponding code for Corba interfaces is not >> implemented (yet). This feature exists at least since 2.6.0. > > > Well. I did not know of this feature. I should document it :-) > > If so, that solves Luiz' problem, since it would allow him to retrieve the > object > to use as an observer. > > I'm assuming that Luiz uses COM interfaces. Again: in this case, i don't use COM interfaces nor do i propose to use Luiz ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
On Thu, 29 Nov 2012, Sven Barth wrote: Am 29.11.2012 03:59, schrieb luiz americo pereira camara: As is today, if you have a reference to a IFPObserver is not possible to use it to attach to, e.g., child objects. This occurs because AFAIK you can't get a TObject from a interface reference. At least for COM interfaces "as" and "is" with a class type on the right side is supported. The corresponding code for Corba interfaces is not implemented (yet). This feature exists at least since 2.6.0. Well. I did not know of this feature. I should document it :-) If so, that solves Luiz' problem, since it would allow him to retrieve the object to use as an observer. I'm assuming that Luiz uses COM interfaces. But in the case he uses CORBA interfaces: What routine needs to be implemented to do this for Corba interfaces ? Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
On Wed, 28 Nov 2012, luiz americo pereira camara wrote: Given the considerations i did about the observer feature, here are some simple projects that supports my concerns and therefore the request i made to change the interface of two functions. Test1 As is today, if you have a reference to a IFPObserver is not possible to use it to attach to, e.g., child objects. This occurs because AFAIK you can't get a TObject from a interface reference. This limits the programmer choice to use a TObject in such situations, in this case the Observer property. All objects in memory descend from TObject, so this is not a problem. COM provided objects are not supported. That would require COM interfaces. I have looked at your tests. They are IMHO rather theoretical and will not happen in real life. I can think of plenty of things that will not work even with TComponent or TObject. That doesn't mean they will happen. Your 'problem' is that you store only interfaces for objects that will observe. Indeed, this is a programming model I do not care to support *for observers*, because I do not think it is likely to happen in real life situations. I explain this below. Test3 Pretty simple: if you don't know if a TObject descendant instance implements a IFPObserver (most cases) you have to do a check before attaching to a IFPObserved otherwise an exception is raised. Let me get this straight: What you say is that you get from somewhere an unknown object (or an interface) and just decide to let it observe another object ? For what ? For fun ? That is a very strange argument. You don't "accidentally" observe. It is also not true that all objects A that have the IFPObserver interface are suitable to observe a particular object B. You observe for a purpose. I'll say even more: in most cases your observer will be written to specifically observe the observed class. You will not let object A observe object B for no good reason. Observing introduces an overhead. For this reason alone, you should not 'just observe'. A will observe B in order to react on changes that B reports, and A will act on these changes. In almost all cases, A will have specific knowledge about B: even if it is just that B has a published property named XYZ. So you will know in advance that when attaching A to B, that A will have the IFPObserver interface. Therefore your test to see if A has the observer interface is simply redundant. Anyway, all this is why I think that using an interface-based API has no value in this case. There will be an object somewhere that you will have written to do some observations and act on changes. All I require is that you use the actual object in the API. It's guaranteed to be there anyway. Michael. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
Am 29.11.2012 10:12, schrieb Marco van de Voort: In our previous episode, Sven Barth said: As is today, if you have a reference to a IFPObserver is not possible to use it to attach to, e.g., child objects. This occurs because AFAIK you can't get a TObject from a interface reference. At least for COM interfaces "as" and "is" with a class type on the right side is supported. The corresponding code for Corba interfaces is not implemented (yet). This feature exists at least since 2.6.0. Also: You can get a tcomponent though, if you implement IInterfaceComponentreference TComponent implements this. I haven't tested that, but does "SomeCorbaInterface as SomeCOMInterface" work? Because maybe the IInterfaceComponentReference trick would only work if the interface I'm working on is also a COM interface (because it could rely on the existence of QueryInterface)... Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
In our previous episode, Sven Barth said: > > As is today, if you have a reference to a IFPObserver is not possible > > to use it to attach to, e.g., child objects. This occurs because AFAIK > > you can't get a TObject from a interface reference. > > At least for COM interfaces "as" and "is" with a class type on the right > side is supported. The corresponding code for Corba interfaces is not > implemented (yet). This feature exists at least since 2.6.0. Also: You can get a tcomponent though, if you implement IInterfaceComponentreference TComponent implements this. ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
Re: [fpc-devel] Tests of observer feature [was: Considerations about observer]
Am 29.11.2012 03:59, schrieb luiz americo pereira camara: As is today, if you have a reference to a IFPObserver is not possible to use it to attach to, e.g., child objects. This occurs because AFAIK you can't get a TObject from a interface reference. At least for COM interfaces "as" and "is" with a class type on the right side is supported. The corresponding code for Corba interfaces is not implemented (yet). This feature exists at least since 2.6.0. Regards, Sven ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel
[fpc-devel] Tests of observer feature [was: Considerations about observer]
Given the considerations i did about the observer feature, here are some simple projects that supports my concerns and therefore the request i made to change the interface of two functions. Test1 As is today, if you have a reference to a IFPObserver is not possible to use it to attach to, e.g., child objects. This occurs because AFAIK you can't get a TObject from a interface reference. This limits the programmer choice to use a TObject in such situations, in this case the Observer property. The option of using a interface reference instead of TObject is valid and has some advantages like implementation decoupling and making clear what the programming contract is by the declaration itself, i.e., if i have a Observer: IFPObserver property i know what to expect from it different from Observer: TObject It's possible to use a specialized class but it will create a dependency to a specific implementation In my proposition, the programmer could use a TObject or a Interface reference such cases, without any overhead. Test2 This test shows the duplication of typecasts when adapting Test1 to match the current observer implementation. ObserverObj is tested/casted to IFPObserver 1 + 2 * Children.Count In the example 7 times. Yes the same test is done 7 times. In my proposition, it could be implemented (test1) with only 1 typecast Test3 Pretty simple: if you don't know if a TObject descendant instance implements a IFPObserver (most cases) you have to do a check before attaching to a IFPObserved otherwise an exception is raised. In the current implementation the same test is done twice, one in caller and another in the callee In my proposition there would be only one test (caller) So, i hope i made my points clear and exemplified. Although the examples are abstract they derives from a concrete example like having using a TForm/TFrame with a Observer property that would be responsible to attach the Observer for some child controls. The change is simple with a leaner implementation, although breaks interface. This fact is minimized since it's the first public fpc release with this feature PS: The main objection by Michael seems to be code that relies on the current interface. The proposed change needs only to change as the argument is called without any logic change. Luiz ObserverTest1.lpr Description: Binary data ObserverTest2.lpr Description: Binary data ObserverTest3.lpr Description: Binary data ___ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel