Why this is not working ?

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

Why this is not working ?

Joseph Frippiat
Starting from Ian Bartholomew SerialChat example I continue to build my
own application and I encounter a little problem.

I have a model which update a "readBuffer" string. Each time it updates
the "readBuffer", it triggers #readBufferChanged:

------- 8> ------- 8> -------
RemoteMonitoringModel>>connectTo: aString
        | comPort |
        comPort := self comPorts indexOf: aString.
       
        [reader := KPSSerialPortDriver
                                onPort: comPort
                                baud: CBR_9600
                                data: 8
                                parity: NOPARITY
                                stop: ONESTOPBIT]
                        on: NotFoundError
                        do:
                                [:ex |
                                MessageBox errorMsg: 'Unable to open device'.
                                ^false].
        status := (String writeStream)
                                nextPutAll: '  Connected to COM';
                                nextPutAll: comPort printString;
                                nextPutAll: ' at ';
                                print: Time now;
                                nextPutAll: '  (';
                                nextPutAll: reader serialPort connectionParameters;
                                nextPut: $);
                                contents.
        self trigger: #newStatus.
        process :=
                        [
                        [| text b |
                        Processor sleep: 250.
                        b := reader carrierDetected.
                        b = carrierPresent
                                ifFalse:
                                        [carrierPresent := b.
                                        self trigger: #dcdChanged].
                        (text := self read) notNil
                                ifTrue:
                                        [readBuffer := readBuffer , text asString.
                                        self trigger: #readBufferChanged]]
                                        repeat]
                                        fork.
        ^true
------- 8> ------- 8> -------

I have a presenter (and an associated view) which watches "readBuffer":

------- 8> ------- 8> -------
ModemTester>>createComponents
        super createComponents.
        comPort := self add: ListPresenter new name: 'comPort'.
        entry := self add: TextPresenter new name: 'entry'.
        display := self add: TextPresenter new name: 'display'.
        status := self add: TextPresenter new name: 'status'.
        dcdLed := self add: LedPresenter new name: 'dcdLed'

ModemTester>>model: aModel
        super model: aModel.
        display model: ((aModel aspectValue: #readBuffer) aspectTriggers:
#readBufferChanged).
        status model: ((aModel aspectValue: #status) aspectTriggers: #newStatus).
        dcdLed model: ((aModel aspectValue: #carrierPresent) aspectTriggers:
#dcdChanged)

ModemTester>>createSchematicWiring
        super createSchematicWiring.
        display when: #valueChanged send: #refreshDisplay to: self

ModemTester>>refreshDisplay
        Sound beep.
        display view scrollToEnd
------- 8> ------- 8> -------

Each time readBuffer is updated, I hear the beep but "display" doesn't
scroll to end.

What am I doing wrong ?

Thanks,

Joseph


Reply | Threaded
Open this post in threaded view
|

Re: Why this is not working ?

Chris Uppal-3
Joseph,

> Each time readBuffer is updated, I hear the beep but "display" doesn't
> scroll to end.

This is just a guess, but maybe your change handler (#refreshDisplay) is being
called before the view's own handler.  As far as I know there is no defined
order in which event handlers are called, so that seems possible.  If you
invoke #scrollToEnd before the View has seen that the text is different, then
naturally it won't scroll far ;-)

If that is the case, then one possible workaround would be to use a deferred
action.

    [display view scrollToEnd] postToInputQueue.

I think that there might be some problems with that if you are using a
RichTextEdit, but there's no need to worry about that possibility unless you
are.

It would be better if there was some event triggered by the view /after/ it has
updated itself.  Perhaps I'm missing something, but there doesn't seem to be
one.  There is a #valueChanged event which is triggered off the presenter, but
that seems to happen in response to the change to the model, rather than being
triggered explicitly by the view.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: Why this is not working ?

Joseph Frippiat
Chris Uppal wrote:

> If that is the case, then one possible workaround would be to use a deferred
> action.
>
>     [display view scrollToEnd] postToInputQueue.
>

This solves the problem :-) .

> It would be better if there was some event triggered by the view /after/ it has
> updated itself.  Perhaps I'm missing something, but there doesn't seem to be
> one.

There isn't any, the view is used only to display the data exchanges
with the remote equipment for diagnostic.

Thanks,

Joseph