pharo-users@lists.pharo.org

Any question about pharo is welcome

View all threads

Announcements - and whether its bad to check if a subscription would be handled?

TM
Tim Mackinnon
Thu, Apr 22, 2021 10:34 PM

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

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
TM
Tim Mackinnon
Tue, Apr 27, 2021 2:03 PM

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

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 > >
EM
Esteban Maringolo
Tue, Apr 27, 2021 2:50 PM

Exceptions are real, so your use case might justify it.
In my experience I never had to test whether an announcer has some
subscription, and before using announcements whether an object has some
"listener" to some event.

I always saw announcements as a fire and forget kind of architecture.

Not sure if I'm answering your question (probably not), but let's start
this conversation :-)

Esteban A. Maringolo

On Tue, Apr 27, 2021 at 11:04 AM 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

Exceptions are real, so your use case might justify it. In my experience I never had to test whether an announcer has some subscription, and before using announcements whether an object has some "listener" to some event. I always saw announcements as a fire and forget kind of architecture. Not sure if I'm answering your question (probably not), but let's start this conversation :-) Esteban A. Maringolo On Tue, Apr 27, 2021 at 11:04 AM 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 > > > > >
SV
Sven Van Caekenberghe
Tue, Apr 27, 2021 2:51 PM

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

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 >> >>
TM
Tim Mackinnon
Tue, Apr 27, 2021 3:49 PM

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

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 > >> > >> >
EM
Esteban Maringolo
Tue, Apr 27, 2021 4:03 PM

The bubbling up is very common in UI, I don't know how it is implemented
though.
I don't know if event handling is programmed using events or imperative
calls to continue "bubbling" up, or... the event is handler by the
container presenter and passed down to the target (e.g. a button).

So the end user of the event registers the handling of an event directly at
the component (presenter in MVP), regardless of who fires it. And it is the
event object or the listener of the event that decides to stop its
propagation.

Regards,

Esteban A. Maringolo

On Tue, Apr 27, 2021 at 12:50 PM 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

The bubbling up is very common in UI, I don't know how it is implemented though. I don't know if event handling is programmed using events or imperative calls to continue "bubbling" up, or... the event is handler by the container presenter and passed down to the target (e.g. a button). So the end user of the event registers the handling of an event directly at the component (presenter in MVP), regardless of who fires it. And it is the event object or the listener of the event that decides to stop its propagation. Regards, Esteban A. Maringolo On Tue, Apr 27, 2021 at 12:50 PM 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 > > >> > > >> > > >
JA
John Aspinall
Tue, Apr 27, 2021 4:19 PM

The MVP scenario you describe with “bubbling up” of event handling is how Dolphin implements command routing in MVP. I’d suggest that what you need is an implementation of this, which is a separate mechanism to Announcements.

Possibly your suggested solution is a clever way to implement a command mechanism by piggybacking Announcements..?

On 27 Apr 2021, at 16:49, 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

The MVP scenario you describe with “bubbling up” of event handling is how Dolphin implements command routing in MVP. I’d suggest that what you need is an implementation of this, which is a separate mechanism to Announcements. Possibly your suggested solution is a clever way to implement a command mechanism by piggybacking Announcements..? > On 27 Apr 2021, at 16:49, 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 >>>> >>>> >>
RS
Richard Sargent
Tue, Apr 27, 2021 4:31 PM

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

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 >> >> >> >> >>
TM
Tim Mackinnon
Tue, Apr 27, 2021 5:13 PM

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

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 >>>>>
RS
Richard Sargent
Tue, Apr 27, 2021 6:33 PM

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

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 > > >