MVP : triggering events.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

MVP : triggering events.

Dominique Dartois-2
I try to display a running chronometer (displaying seconds) onto a
TimePresenter.
If the chronometer code is in the model class, the Presenter is updated
every second. That's what I want.

If the chronometer is in a class by itself with an instance contained
in the model, the presenter is not updated. I can't find the way to
update the presenter. I tried "addDependent" in the model class and
"trigger: #event" in the chrono class but the model class never receive
the event.
Any clue?
Thanks.
----
Dominique Dartois


Reply | Threaded
Open this post in threaded view
|

Re: MVP : triggering events.

Ian Bartholomew-21
Dominique,

> If the chronometer is in a class by itself with an instance contained
> in the model, the presenter is not updated. I can't find the way to
> update the presenter. I tried "addDependent" in the model class and
> "trigger: #event" in the chrono class but the model class never receive
> the event.
> Any clue?

You need to do three things.

1) In the object that contains the timer (a class called MyTimer for
example) you have to trigger an event when the time elapses.  Something like

MyTimer>>run
[Processor sleep: 1000.
self trigger: #myTimerTicked] fork


2) In the object that owns the instance of MyTimer (say a class called
MyClock) you have to register for the triggered event.  Something like

MyClock>>startClock
myTimer := MyTimer new.
myTimer when: #myTimerTicked send: #onMyTimerTicked to: self.
myTimer run


3) Add a method in the MyClock class that updates the display when the
event is triggered

MyClock>>onMyTimerTicked
myTimePresenter value: myTimer currentTime (or whatever)


An alternative would be to pass the current count with the triggered
event (note the extra colons)

MyTimer>>run
count := 0.
[Processor sleep: 1000.
count := count + 1.
self trigger: #myTimerTicked: with: count] fork

MyClock>>startClock
myTimer := myTimer new.
myTimer when: #onMyTimerTicked: send #onMyTimerTicked: to: self.
myTimer run

MyClock>>onMyTimerTicked: anInteger
myTimePresenter value: (Time fromSeconds: anInteger)

**completely untested of course :-)

There are other ways, for example - you could share a model between the
TimePresenter and your model, but the above is probably the easiest.

--
Ian

Use the Reply-To address to contact me (limited validity).
Mail sent to the From address is ignored.


Reply | Threaded
Open this post in threaded view
|

Re: MVP : triggering events.

Dominique Dartois-2
A Great Great thank you Ian.
I spend hours in Dolphin, missing your point number 2 :
..
myTimer when: #myTimerTicked send: #onMyTimerTicked to: self.
..

Now, it runs!
Thanks again.
----
Dominique Dartois


Reply | Threaded
Open this post in threaded view
|

Re: MVP : triggering events.

Schwab,Wilhelm K
In reply to this post by Ian Bartholomew-21
Ian,

> MyClock>>startClock
> myTimer := myTimer new.
> myTimer when: #onMyTimerTicked: send #onMyTimerTicked: to: self.
> myTimer run
>
> MyClock>>onMyTimerTicked: anInteger
> myTimePresenter value: (Time fromSeconds: anInteger)
>
> **completely untested of course :-)

One concern: have you synchronized this with the message loop?

Unless I am missing something, I would feel better with

MyTimer>>run
[Processor sleep: 1000.
  [ self trigger: #myTimerTicked ] post. ] fork

so there is no doubt about the calling thread with the UI is updated.
If accuracy is a huge concern, one could include the time in the event.

Have a good one,

Bill


--
Wilhelm K. Schwab, Ph.D.
[hidden email]


Reply | Threaded
Open this post in threaded view
|

Re: MVP : triggering events.

Dominique Dartois-2
In fact my code was the following:
boucle := [[Processor sleep: 1000.
            tempsEcoule := TimeStamp fromSeconds: self secondesEcoulees + 1.
            self trigger: #ticTac] repeat] fork

tempsEcoule is the "aspect" for the presenter.

Bill, what is "post" in you code:
MyTimer>>run
[Processor sleep: 1000.
 [ self trigger: #myTimerTicked ] post. ] fork

Regards.

----
Dominique Dartois


Reply | Threaded
Open this post in threaded view
|

Re: MVP : triggering events.

Schwab,Wilhelm K
Dominique Dartois wrote:

> In fact my code was the following:
> boucle := [[Processor sleep: 1000.
>             tempsEcoule := TimeStamp fromSeconds: self secondesEcoulees + 1.
>             self trigger: #ticTac] repeat] fork
>
> tempsEcoule is the "aspect" for the presenter.
>
> Bill, what is "post" in you code:
> MyTimer>>run
> [Processor sleep: 1000.
>  [ self trigger: #myTimerTicked ] post. ] fork

See #queueDeferredAction: and any senders of it, which are really just
ways to make it simpler to use - with one exception.  Steve Waring
created a second queue that is not broken by some of Windows' more modal
elements (popped menus).

The basic idea is the same: queue actions that should be done when the
GUI is ready for them.

Have a good one,

Bill

--
Wilhelm K. Schwab, Ph.D.
[hidden email]