OpenNTF.org - LotusScript Signals & Slots li
My Links (Not logged in)
Code Bin Search
 
Hosted by Prominic.NET
Rate This Code
5 - brilliant stuff
4 - very nice
3 - average
2 - needs work
1 - bad
   OpenNTF Code Bin
About This Code
Brief Description:
LotusScript Signals & Slots library 
Rating:
Not Rated Yet 
Contributor:
Andrew Tetlaw 
Category:
Lotusscript 
Type:
Utilities 
Notes Version:
R6.x 
Last Modified:
18 Jan 2005 
OpenNTF Disclaimer

All of the program code and information presented in the OpenNTF.org Code Bin are provided "as-is", and should be used at your own risk. OpenNTF.org make no express or implied warranty about anything in the Code Bin, and OpenNTF.org will not be responsible or liable for any damage caused by the use or misuse of anything from this site. OpenNTF.org makes no guarantees about anything. Please thoroughly test all of the knowledge and code you find here before you attempt to use them in your production environment.

Code / Description
Quite possibly the most useless piece of LS code you could find. I was excited about the concept of signals and slots and a messaging framework in code and had an opportunity where I could plausibly use such a framework. Thus:


- Signals & Slots library -
A mechanism for passing messages to otherwise unconnected code elements

A slot is a listener or a transmitter or both, a signal is like a wire.
You connect 2 slots with a signal. A message is send down a signal wire.

In a signal connection, one slot is determined to be the parent or Transmitter
and one the target or listener

When a transmitter slot emits a message it will transmit the message down all
the signal wires that have been registered with it. If a slot is both a listener
and a tranmitter it will re-transmitt any message it receives down all registered signals.

The transmitting and listening slots are never aware of each other. Only the presence
of a signal allows the message to be send.

It is safe to keep telling a slot to send as it'll simply do nothing if no registered
signals are present. In this way you can set up slots in your code that operate in all
conditions making it more flexible to plug and unplug signals whenever you like.

Often the listener slots are sub-classed slots so that a custom handler can be written
for receiving the signal.

The signal class can also be subclassed for the purpose of modifying the message in
transmission before being received by the listener.

The signal can also be set to transmit only once or every time.

The MessageData class is a simple data holder so as to be flexible for a wide
variety of purposes.

Usage / Example
Where the hell would such a thing be necessary in a Notes application? Well if you have various LS libraries that are otherwise unrelated and you have cause to use these libraries in an agent or something and you want data to pass between them but keep them unrelated, then the sigslot classes can help you!

The one and only time I have used it is when I had a library that did a pile of document processing in various looping functions and another one that displayed a java progress meter. I wrote an agent that used both libraries and the sigslot classes to pass information between them so that the progressmeter would be updated as the docs were progressed.

This meant that the doc processing library could remain generic and reused in a variety of situations; i.e. it didn't need the hooks to update the progress meter hardcoded into the functions and be unusable in situations where a UI progressmeter was not possible or not needed.

What I did have to do, however is place open slots in each library. So when the libraries are used the slots become active. The slots must also be accessible to any process that uses the libraries. Thus the using process then has the option to create a signal object and connect the slots.

In my situation the document processing library had a slot that would emit a signal everytime a doc was updated. The progress meter has a slot that waits for a signal to tell it to update the progress meter. All that is needed is for the agent to create a signal and attach the doc updater's slot to the progress meter's slot and communication occurs between the two libraries without them having to know about each other!

I'd be really interested if anyone has a use for this!


OK here's my example:

First I have a DocumentProcessor class that has a loop for processing documents. The class creates a slot instance called 'CountUpdate' use to emit a signal with each loop cycle updating the number of documents that have been processed. It stores this information in a MessageData object under the key "COUNT".

Public Class DocumentProcessor

Public CountUpdate as new Slot()

public Sub ProcessAllDocuments()
...
' loop through all documents
call Me.EmitCountUpdateSignal(count)
...
End Sub

Public Function EmitCountUpdateSignal(count As Long)
Dim msg as new MessageData
msg.Data("COUNT") = count
Call Me.CountUpdate.EmitSignal(msg)
End Function

End Class


Next I have a class called NotesStatusBox which displays a progress meter in the Notes UI. I have sub-classed the Slot class to create a custom slot which listens for sigtnals that will tell the NotesStatusBox to update the progress meter. I have subclassed it so I can specify how to receive the information; in this instance it'll look for a data value with the key of "UPDATE" but also so that is can call a custom function in the NotesStatusBox class. When the NotesStatusBox is instatiated it'll create an instance of this custom slot as well.

Private Class StatusBoxUpdateValue As slot
Private parent As NotesStatusBox
Public Sub new(parent As NotesStatusBox), Slot()
Set Me.parent = parent
End Sub

Public Function ReceiveSignal(msg As MessageData) As Boolean
If(Iselement(msg.Data("UPDATE"))) Then

Call Me.parent.updatevalue(Clng(msg.Data("UPDATE")))
End If
End Function
End Class


Public Class NotesStatusBox

Public UpdateValueSlot as StatusBoxUpdateValue

Public Sub New ()
Set Me.updValSlot = New StatusBoxUpdateValue(Me)
End Sub

Public Sub updateValue(num as Long)
...
End Sub
End Class

Now the DocumentProcessor class and the NotesStatusBox class do not know about each other and both can work independantly without problem, their respective slots keep on functioning but ultimately do nothing at the moment.

Now I make an agent that uses the DocumentProsessor class and the NotesStatusBox class. I can connect them using a Signal Object. In this example I have sub-classed the Signal object so I can translate the data being sent between the two known slots above; it'll come in as "COUNT" but go out as "UPDATE".

Private Class UpdateMeterSignal As Signal
Public Sub new()
End Sub

Public Function GetTargetData(msg As MessageData) As MessageData
Dim msgNew as new MessageData
If(Iselement(msg.Data("COUNT))) Then
call msgNew.AddData("UPDATE", Clng(msg.Data("COUNT")))
End If
Set GetTargetData = msgNew
End Function
End Class


In the agent itself I create an instance of this new signal and use it to connect the CountUpdate slot in the DocumentProcessor object as a parent to the UpdateValueSlot slot (as the target) of the NotesStatusBox object. This now means if the parent slot emits a signal, our new custom signal will pass it onto the target slot.


Sub Initialize
...
Dim updsig As New UpdateMeterSignal()
Dim ProgressMeter as new NotesStatusBox()
Dim DocUpdater as new DocumentProcessor()


Call updsig.Connect(DocUpdater.CountUpdate, ProgressMeter.UpdateValueSlot)

End Sub


So now our DocumentProcessor class is sending signals to our NotesStatusBox class to update the progress meter.

Probably more significantly I've been able to create a slot for a 'cancel' event in the NotesStatusBox class so that if someone clicks cancel it'll emit a signal. This way I can interupt the process that is currently updating the progress meter. Which is something not normally easy to do in an agent. The cancel button interupts the document updating loop and exits cleanly.
Code Attachments
sigslot.lss (5 Kbytes)
 Comments
Posted by Stan Rogers on 01/11/2005 12:33:59 PMSametime for script libraries? Kewl!
Well, at least until my agents become self-aware. I mean, this kinda gives them the mechanism to organise and strike, doesn't it?
Posted by R v Laarhoven on 01/13/2005 07:39:44 AMPlease explain
Could someone please add and (code) example how and when I could use this class?
Posted by Andrew Tetlaw on 01/18/2005 06:18:19 PMExplanation
There you go an incomprehensible example for an incomprehensible library!
Posted by Benedict R Poole on 02/25/2005 07:07:17 AMGood point Stan
Those agent things are uppity at the best of times. Now, with Mr. Tetlaw's help I can see my (already fraught) code organising pickets, setting up "Scab!" transmitter slots, and all sorts.
The horror!
But seriously, an intriguing notion ;o)
Posted by David Peabody on 08/04/2006 01:23:33 PMCan this be applied to automatically refresh a view without losing ui control?
I'm creating(trying at least) an app that will be used as a dashboard. I have some indicators for status, etc.
I'd like to make the view that is being used as the dashboard to act as if it is displaying realtime. Before I really thought things through, I threw some code in the postopen event of the view to do the following:
while...
sleep(30)
workspace.ViewRefresh
wend
I lost control of the ui by doing this. I need some kind of event handler that I can shoot a message to so that the UIView will automatically refresh.
Thanks for any help in advance,
Dave
 Add your comment!