Upcasting is a behavioural feature. You would not play with the announcements. The class would receive it and its handler would delegate to a parent if necessary.
On Tue, Apr 27, 2021 at 10:14 AM Tim Mackinnon <tim@testit.works> wrote: > I appreciate the further thoughts of others - I should go back and look > at Dolphin code (I think there are ways to run it on Mac now?). > > The upcasting Richard refers to is what I'm trying to do - which is how I > got interested in understanding if you could tell if someone was subscribed > to an event, as if not - then you could pass it up to the parent to - > re-announce it via the announcer of that parent (in CP - the announcers are > by presenter, so hence the handoff). > > In theory it's quite neat - but I did see some deprecations in Announcer > trying to stop too much knowledge leaking out. However, knowing if an event > has any listeners doesn't on the surface seem too controversial - but I can > see that everyone approaches this idea with understandable caution. > Possibly this is masking some other approach to this - or - I can happily > have an extension method on Announcer - or - I can propose this method in a > PR for symetry with some of the other #hasXXXX methods. > > Tim > > On Tue, 27 Apr 2021, at 5:31 PM, Richard Sargent wrote: > > I have seen something called upcasting and downcasting (as contrasted with > broadcasting). Mostly, I have seen it in UI layers. > > e.g. a leaf node receives a change notification, decides it isn't > interested in handling the notification, and so passes it up to its parent, > etc. > > Downcasting is similar but in the opposite direction. e.g. a window > receives an event and asks its children to handle it, and they do the same. > In this case especially, the one that handles the event needs to mark it as > handled so that no one else is asked to handle it. > > On April 27, 2021 5:49:56 AM HST, Tim Mackinnon <tim@testit.works> wrote: > > Hi guys - yes that fire and forget was always how I had viewed announcements, > and potentially my scenario is misusing "announcements" which is why I was > interested in views here. > > However - as announcements are typically a mechanism for farming out > processing to others - how does one handle the scenario that you might only > want one object to handle the announcement (and not others)? > > in my specific example, with MVP - a view, totally decoupled in a web > browser, wants to pass on a button click to a presenter - however it not > clear what the best mechanism to bubble up that handling should be? If the > immediate presenter of the view can handle it - great - but if not, how would > you continue to broadcast wider to see if someone higher up the parent > component chain can handle it? > > If you go fire and forget (which is how I had viewed announcements prior to > this specific case) - then you have the problem a different way - when > someone processes an announcement it might already have been handled earlier > and so the consumer either has to check first, or their work is simply > ignored as the announcement payload could just filter a response out. > > In my head, I'm sort of thinking this is akin to CPU interrupt chaining - > where an interrupt can cascade up a stack if not handled OR like object > inheritance where an object can choose to override a message and stop it from > cascading up the inheritance chain. > > Maybe announcements aren't intended for this at all - although it seems an > elegant way to handle it - with just 1 method addition to Announcer (but it > does slightly expose things - albeit in a structured way - and similar to the > similar #hasSubscriber:). > > I'm sure it "depends" - but interested in other observations from the field, > as I'm sure I'm not the first person to hit something like this. > > Tim > > On Tue, 27 Apr 2021, at 3:51 PM, Sven Van Caekenberghe wrote: > > The whole idea is to decouple producers and consumers, like in > messaging systems. > > You should not care if there are other listening, just like the > listeners should not care if there is someone posting data. > > Asking for subscribers is introducing a coupling. > > The announcement mechanism will/should deal with this in an efficient way. > > On 27 Apr 2021, at 16:03, Tim Mackinnon <tim@testit.works> wrote: > > From my rather long ramble below - I am still curious if its distasteful to > have a method on Announcer > > hasSubscriptionsHandling: anAnnouncement > "Answer true if I have any subscribers to anAnnouncement" > > ^(registry subscriptionsHandling: anAnnouncement ) notEmpty > > Tim > > On Thu, 22 Apr 2021, at 11:34 PM, Tim Mackinnon wrote: > > Hi everyone - I’ve always thought the article on announcements many > years ago was very cool - and we don’t seem to use them as much as we > could (but equally they aren’t a panacea to be overused everywhere > either - and they do get used in Pharo to some extent). > > Anyway, I’ve been playing around with CodeParadise (CP is a very cool > project, and Erik is very supportive and thinking about how to write > web apps a different way… I’m fascinated), > > And - CP uses announcements as mechanism to send events from the View > Client (in a web browser) to a Presenter on the server (which makes > total sense). > > In taking things for a spin, I hit an interesting problem on how in a > web component world, you should display a spelling test of words - > > e.g. SpellingTest — has many —> SpellingWord(s). > > > Initially I bunged it all in a single presenter with its associated > view, and it was a bit messy, and Erik guided me down a route (that CP > nicely supports) - that my SpellingTest view should have the name/date > of the test as well as an add word input field, but the list of current > Words (which I had bunged into a table) - were actually more elegant as > sub-components - hence a WordView - which renders a single word in a > DIV, and for the edit screen I was creating, a Delete button next to > the word (so you could delete it). So a 1 to many relationship > essentials. > > This is where the announcements kick in (and lead to my ultimate question). > > When you click the Delete button, if I use a sub component - my view > will generate a DeleteWordAnnouncement - which gets fed to my > SpellingWordPresenter - however words in this sense don’t naturally > know their parent (the SpellingTest) - and its the parent test that has > a #deleteWord: method. > > I’ve been taking with Erik, on different ways to elegantly handle this. > > a) you could change the model so words know their parent (in my case, > I’m using a 3rd party model for Flashcards, and they just don’t know > this - and adapting them would be a nuisance > b) my TestPresenter could listen to announcements on the WordPresenter > - and I could get some communications between presenters (although > normally the Presenters just get events from Views, and pure domain > models - so it feels a bit abnormal to consider another Presenter as a > sort of model - but I could live with this > c) given the composable nature of views/presenters (and CP is base on a > WebComponent model) - you could bubble up Announcements, so that if an > event isn’t handled by a view’s immediate presenter, you could re-route > it to the parent of the View (the component owner) and see if it’s > presenter could do something. > > > I think (c) has a certain expectation to it - in fact when I converted > my initial one-presenter attempt into components, I still had listener > code in my TestPresenter that was expecting to get a deleteWord > announcement and I was initially surprised that I wasn’t getting it (as > it was now just going to the Word component I had refactored out). > > So I wonder if others here would expect things to work this way too > (and are there other examples in the wild that lead you here - or scare > you away from this?). > > Back to my Announcement question - if C is a good idea - why doesn’t > the Announcer class let you check if if will handle a particular > announcement? The API has #hasSubscriber: and #hasSubscriberClass: , > but its missing: > > hasSubscriptionsHandling: anAnnouncement > "Answer true if I have any subcribers to anAnnouncement" > > ^(registry subscriptionsHandling: anAnnouncement ) notEmpty > > > And I am wondering if this is because it's a bad thing to expect to be > able to check? In my case above, I would want to do this to know if CP > should instead try announcing a message to a parent presenter because > the current presenter won’t handle it. In my example above, my > WordComponentView will broadcast that the delete button was clicked, > but its actually a parent view which would reasonably want to listen to > this kind of event and process the delete. And in a many words > scenario (the Test has many words), its unrealistic for the parent to > register to listen to each word component individually (in fact CP sort > of hides this from you), however if you could listen to an event in > your TestView, it seems to come out quite nicely - and looks a bit > like this: > > viewCreated > super viewCreated. > > self view > when: CpNavigationAnnouncement > do: [ :action | self model goto: action location ]; > > when: CpAddWordAnnouncement do: [ :action | self addWord: > action data > ]; > when: CpDeleteWordAnnouncement do: [ :action | self deleteWord: > action data ]. <— this is the one I’m talking about > > > So I’m curious on the overall thought process here, but in particular > whether I should even submit a PR on Announcer for > #hasSubscriptionsHandling: ? > > Tim > > >