 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Ritchie Guest
|
Posted: Thu Nov 27, 2003 2:18 am Post subject: Feedback from a Selection |
|
|
I am going to have multiple, simultaneous views of the same model. I
figured that it would be best to share some sort of IObjectSelection
interface amongst them, since objects can be selected from any view, and
each view has to respond to a change in selection.
I already have many ways of sending a notification.
I can either use my notification system for this:
ObjectSelection.ChangeSender.AddListener(View as ICOREListener,
'PooledThread' {or 'Synchronous' if I want to wait});
procedure TMyView.Listen(ANotification: ICORENotification);
var
SelectionChangeNotification : ISelectionChangeNotification;
begin
if Supports(ANotification,ISelectionChangeNotification,
SelectionChangeNotification) then
begin
// respond to the selection change
end;
end;
Or provide a direct, specialized callback:
ObjectSelection.AddChangeSubscriber
(View as ISelectionChangeSubscriber);
My question is on the sort of notification/callback that an
IObjectSelection should provide when the selection is changed (i.e. What
should ISelectionChangeNotification have in it?). There are a number of
possibilities, here spoken from the lips of the notification facet when
it arrives at the view to tell the view what happened:
(1) "Something's changed, you go figure it out"
(2) "Something's changed, here's the old selection, you go figure it
out"
(3) (courier #1 arrives) "This one thing has changed"...
(courier #2 arrives) "This one thing has changed"...
(courier #3 arrives) "This one thing has changed"...
(4) "These things have been removed, these things have been added"
(5) "These are all the changes, in the precise order that they happened"
Anyone got a good rule of thumb as to how to decide amongst such a set
of possibilities?
-- Ritchie Annand
Senior Software Architect
Malibu Software & Engineering Ltd.
http://www.malibugroup.com
http://nimble.nimblebrain.net
http://wiki.nimblebrain.net
|
|
| Back to top |
|
 |
Joanna Carter (TeamB) Guest
|
Posted: Thu Nov 27, 2003 10:01 am Post subject: Re: Feedback from a Selection |
|
|
Ritchie wrote:
| Quote: | I am going to have multiple, simultaneous views of the same model. I
figured that it would be best to share some sort of IObjectSelection
interface amongst them, since objects can be selected from any view,
and each view has to respond to a change in selection.
|
As you may have gathered, I use Interactors to respond to user gestures and
these are responsible for telling the Selection to change.
Because an Interactor can be a State Machine, you can detect whether the
Ctrl and/or Shift keys are pressed and Clear/Add/Replace the Selection
accordingly from an appropriate State class of the Interactor.
Once the Selection has changed, the Model should then notify any Observers.
Joanna
--
Joanna Carter (TeamB)
Consultant Software Engineer
TeamBUG support for UK-BUG
TeamMM support for ModelMaker
|
|
| Back to top |
|
 |
Ritchie Guest
|
Posted: Thu Nov 27, 2003 8:50 pm Post subject: Re: Feedback from a Selection |
|
|
In article <3fc5cc4a (AT) newsgroups (DOT) borland.com>, [email]joannac (AT) btinternetXX (DOT) com[/email]
says...
| Quote: | Ritchie wrote:
| I am going to have multiple, simultaneous views of the same model. I
| figured that it would be best to share some sort of IObjectSelection
| interface amongst them, since objects can be selected from any view,
| and each view has to respond to a change in selection.
As you may have gathered, I use Interactors to respond to user gestures and
these are responsible for telling the Selection to change.
|
If you want to flesh those Interactors out, you should check out the
SubArctic toolkit by Scott Hudson of Carnegie Mellon. I ran across this
toolkit looking for geometry management inspiration, but it has a whole
pile of interactors and animation objects. It's in preeminently readable
Java. Take a look-see.
http://www.cc.gatech.edu/gvu/ui/sub_arctic/
| Quote: | Because an Interactor can be a State Machine, you can detect whether the
Ctrl and/or Shift keys are pressed and Clear/Add/Replace the Selection
accordingly from an appropriate State class of the Interactor.
Once the Selection has changed, the Model should then notify any Observers.
|
*laugh* What the notification should contain was my actual question ;)
In clicking around on your web page, I noticed a French version; est-ce
vrai que tu en parles?
Toodles,
-- Ritchie Annand
Senior Software Architect
http://www.malibugroup.com
http://nimble.nimblebrain.net
http://wiki.nimblebrain.net
|
|
| Back to top |
|
 |
Ritchie Guest
|
Posted: Thu Nov 27, 2003 9:23 pm Post subject: Re: Interactors |
|
|
In article <3fc5cc4a (AT) newsgroups (DOT) borland.com>, [email]joannac (AT) btinternetXX (DOT) com[/email]
says...
| Quote: | As you may have gathered, I use Interactors to respond to user gestures and
these are responsible for telling the Selection to change.
|
By the way, Joanna - I pulled down the source for the MVP articles a
while back, and it looked like it was from the very first articles. Do
you have an update? :)
-- Ritchie Annand
Senior Software Architect
http://www.malibugroup.com
http://nimble.nimblebrain.net
http://wiki.nimblebrain.net
|
|
| Back to top |
|
 |
Bryan Crotaz Guest
|
Posted: Fri Nov 28, 2003 12:05 am Post subject: Re: Feedback from a Selection |
|
|
| Quote: | Once the Selection has changed, the Model should then notify any
Observers.
*laugh* What the notification should contain was my actual question
|
I pass a reference-counted interface to a data object. The receiver uses
generic methods on this interface to get basic data (like an integer event
type or a string name), then queries for more detailed and more specific
interfaces if it thinks it understands the notification.
By making it ref-counted, the receiver can shove it into a thread-safe queue
for later processing by another thread, which gets round the nasty
Synchronise stuff on TThread, and means that multiple internal worker
threads can communicate using the same Observer mechanism without blocking
each other.
Bryan
|
|
| Back to top |
|
 |
Ritchie Annand Guest
|
Posted: Fri Nov 28, 2003 4:34 am Post subject: Re: Feedback from a Selection |
|
|
Bryan Crotaz wrote:
Hi there, Brian :)
| Quote: | *laugh* What the notification should contain was my actual question ;)
I pass a reference-counted interface to a data object. The receiver uses
generic methods on this interface to get basic data (like an integer event
type or a string name), then queries for more detailed and more specific
interfaces if it thinks it understands the notification.
|
My entire framework is reference-counted so far I find it a wonderful way
to, amongst other things, get past ownership concerns of objects passed in
parameters.
My base notification interface is merely a "marker" interface (a string
might be a nice add-on), so if you are merely looking for something to have
happened, you can leave it alone. Otherwise, you can ask it for a specific
notification interface.
Certainly is a nice way to get around the lack of polymorphism in parameter
lists :)
What I was trying to figure out is what sort of detail to put into the
interface to the data object:
(1) Nothing; leave it as a marker interface and have the listening view
rescan the model
(2)
IModelChange = interface // GUIDs+properties left off for brevity
function GetOldModel: IModelObject;
end;
(3)
IModelChange = interface
function GetModelChanged: IModelItem;
function GetChange: TModelDeltaType; // added or removed
end;
(4a)
IModelChange = interface
function GetAddedItemCount: Integer;
function GetAddedItem(AIndex: Integer): IModelItem;
function GetRemovedItemCount: Integer;
function GetRemovedItem(AIndex: Integer): IModelItem;
end;
(4b)
IModelChange = interface
function GetAddedItems: IModelItemListIterator;
function GetRemovedItems: IModelItemListIterator;
end;
(5)
IModelDelta = interface
function GetItem: IModelItem;
function GetChange: TModelDeltaType;
end;
IModelDeltaIterator = iterable list of IModelDelta;
IModelChange = interface
function GetChanges: IModelDeltaIterator;
end;
Whew :)
| Quote: | By making it ref-counted, the receiver can shove it into a thread-safe
queue for later processing by another thread, which gets round the nasty
Synchronise stuff on TThread, and means that multiple internal worker
threads can communicate using the same Observer mechanism without blocking
each other.
|
Concurrency was another key focal point in the framework. I use a lot of
queuing, and enjoy ref-counting for exactly the same reason.
For example, I have two interfaces: ICOREExecutor and ICOREExecutable. The
former contains a single method: procedure Execute(X: ICOREExecutable), the
latter contains a single method: procedure Execute;.
I have a thread pool executor that implements ICOREExecutor. When you go
MyExecutor.Execute(MyTask), where MyExecutor is a TPooledThreadExecutor,
that MyTask goes into a queue. Queue it up twice, no problem. Plenty of
queues in the notification system as well.
(As for Synchronize, I made a version that you call directly, since
ICOREExecutables are -not- thread derivatives themselves :)
----8<----
Based on your interesting comments that parallel some things I've been
doing, I'm curious as to what kind of project you're doing, Bryan :)
-- Ritchie Annand
Senior Software Architect
Malibu Software & Engineering Ltd.
Bus. http://www.malibugroup.com
Home. http://nimble.nimblebrain.net
Wiki. http://wiki.nimblebrain.net
|
|
| Back to top |
|
 |
mrbar Guest
|
Posted: Fri Nov 28, 2003 12:13 pm Post subject: Re: Feedback from a Selection |
|
|
Hi Ritchie Annand
I send a message for your homepage's email address. Could you answer-me please
Thanks.
Marcos Barreto
|
|
| Back to top |
|
 |
Bryan Crotaz Guest
|
Posted: Fri Nov 28, 2003 2:21 pm Post subject: Re: Feedback from a Selection |
|
|
www.inspiredsignage.com
It's a real-time multimedia player for dynamic signage on projectors or
plasmas in public environments. Renders 100 layers or text or graphics,
each with 3d moves, fades etc, running at 75 frames per second at 1280x1024.
Working now on a version that will render up to 20,000x10,000 pixels at
75fps. The current version can also play 3 MPEG2 files or up to 18 divx
files simultaneously at full frame rate within those 100 layers.
Content changes at run-time, and elements of the schedule are connected to
each other to move spatially or temporally as other elements are changed. A
template architecture uses interfaces to navigate the element tree to insert
data live.
There's about 300 classes, several of which exceed 100 lines of declaration
with all the interfaces they implement!
The "Composer" controller is done with Bold + BoldExpress + Firebird as a
web interface. I've worked closely with Neosight to help specify and test
Bold Express 2, and the resulting components are brilliant. I couldn't do
this without them!
Bryan
"Ritchie Annand" <ritchiea (AT) spamcop (DOT) net> wrote
| Quote: | Bryan Crotaz wrote:
Hi there, Brian :)
*laugh* What the notification should contain was my actual question ;)
I pass a reference-counted interface to a data object. The receiver
uses
generic methods on this interface to get basic data (like an integer
event
type or a string name), then queries for more detailed and more specific
interfaces if it thinks it understands the notification.
My entire framework is reference-counted so far I find it a wonderful
way
to, amongst other things, get past ownership concerns of objects passed in
parameters.
My base notification interface is merely a "marker" interface (a string
might be a nice add-on), so if you are merely looking for something to
have
happened, you can leave it alone. Otherwise, you can ask it for a specific
notification interface.
Certainly is a nice way to get around the lack of polymorphism in
parameter
lists :)
What I was trying to figure out is what sort of detail to put into the
interface to the data object:
(1) Nothing; leave it as a marker interface and have the listening view
rescan the model
(2)
IModelChange = interface // GUIDs+properties left off for brevity
function GetOldModel: IModelObject;
end;
(3)
IModelChange = interface
function GetModelChanged: IModelItem;
function GetChange: TModelDeltaType; // added or removed
end;
(4a)
IModelChange = interface
function GetAddedItemCount: Integer;
function GetAddedItem(AIndex: Integer): IModelItem;
function GetRemovedItemCount: Integer;
function GetRemovedItem(AIndex: Integer): IModelItem;
end;
(4b)
IModelChange = interface
function GetAddedItems: IModelItemListIterator;
function GetRemovedItems: IModelItemListIterator;
end;
(5)
IModelDelta = interface
function GetItem: IModelItem;
function GetChange: TModelDeltaType;
end;
IModelDeltaIterator = iterable list of IModelDelta;
IModelChange = interface
function GetChanges: IModelDeltaIterator;
end;
Whew :)
By making it ref-counted, the receiver can shove it into a thread-safe
queue for later processing by another thread, which gets round the nasty
Synchronise stuff on TThread, and means that multiple internal worker
threads can communicate using the same Observer mechanism without
blocking
each other.
Concurrency was another key focal point in the framework. I use a lot of
queuing, and enjoy ref-counting for exactly the same reason.
For example, I have two interfaces: ICOREExecutor and ICOREExecutable. The
former contains a single method: procedure Execute(X: ICOREExecutable),
the
latter contains a single method: procedure Execute;.
I have a thread pool executor that implements ICOREExecutor. When you go
MyExecutor.Execute(MyTask), where MyExecutor is a TPooledThreadExecutor,
that MyTask goes into a queue. Queue it up twice, no problem. Plenty of
queues in the notification system as well.
(As for Synchronize, I made a version that you call directly, since
ICOREExecutables are -not- thread derivatives themselves :)
----8<----
Based on your interesting comments that parallel some things I've been
doing, I'm curious as to what kind of project you're doing, Bryan :)
Bryan
-- Ritchie Annand
Senior Software Architect
Malibu Software & Engineering Ltd.
Bus. http://www.malibugroup.com
Home. http://nimble.nimblebrain.net
Wiki. http://wiki.nimblebrain.net
|
|
|
| Back to top |
|
 |
Malte Persike Guest
|
Posted: Fri Nov 28, 2003 4:39 pm Post subject: Re: Feedback from a Selection |
|
|
| Quote: | (2) "Something's changed, here's the old selection, you go figure it
out"
|
I prefer the second alternative together with an observer mechanism
that allows observers to attach to specific changes in the model. The
latter is some of the things I always liked about the SmallTalk MVC
paradigm.
Now, why the (2). The idea of a plain "you figure it out" approach
appears to me as a waste of resources considering that the information
about what has changed is already there. When a selection changes, it
spawns a memento and hands it to the observers which associated to
this specific change. There still remains some property-comparing
drugwork for the observers but at least this reduces to only those
observers which have to adjust to the specific change.
More specialized schemes will inevitably result in an explosion of the
number of classes (or messages, at least) where in the end it could
become necessary to implement a message class for every property of
the selection.
---
The above e-mail address is not valid. To
contact me, please use my real e-mail address:
malte AT t DASH online DOT de
|
|
| Back to top |
|
 |
Ritchie Annand Guest
|
Posted: Fri Nov 28, 2003 8:19 pm Post subject: Re: Signage |
|
|
Bryan Crotaz wrote:
| Quote: | www.inspiredsignage.com
It's a real-time multimedia player for dynamic signage on projectors or
plasmas in public environments. Renders 100 layers or text or graphics,
each with 3d moves, fades etc, running at 75 frames per second at
1280x1024. Working now on a version that will render up to 20,000x10,000
pixels at 75fps. The current version can also play 3 MPEG2 files or up to
18 divx files simultaneously at full frame rate within those 100 layers.
|
That sounds like a lot more fun than what I'm doing May I commence being
envious now? :)
| Quote: | Content changes at run-time, and elements of the schedule are connected to
each other to move spatially or temporally as other elements are changed.
A template architecture uses interfaces to navigate the element tree to
insert data live.
|
I'm pretty impressed at the claim of live software updates, too :)
| Quote: | There's about 300 classes, several of which exceed 100 lines of
declaration with all the interfaces they implement!
|
That's a pretty hefty length for an interface... let me guess - those would
be the multimedia equivalents of TCanvas? How many interfaces do you
host on a class? How many of them are 'main' interfaces and how many are
'support' (e.g. ILoggable, ISerializable, ...)?
| Quote: | The "Composer" controller is done with Bold + BoldExpress + Firebird as a
web interface. I've worked closely with Neosight to help specify and test
Bold Express 2, and the resulting components are brilliant. I couldn't do
this without them!
|
With BoldRetina on the web side?
-- Ritchie Annand
|
|
| Back to top |
|
 |
Bryan Crotaz Guest
|
Posted: Fri Nov 28, 2003 9:20 pm Post subject: Re: Signage |
|
|
| Quote: | That sounds like a lot more fun than what I'm doing May I commence
being
envious now?
|
Want a job? Just move to London...
| Quote: | Content changes at run-time, and elements of the schedule are connected
to
each other to move spatially or temporally as other elements are
changed.
A template architecture uses interfaces to navigate the element tree to
insert data live.
I'm pretty impressed at the claim of live software updates, too
|
Plugins are wonderful things... Can't reveal my magic technique in public
though!
| Quote: | There's about 300 classes, several of which exceed 100 lines of
declaration with all the interfaces they implement!
That's a pretty hefty length for an interface...
|
LOL - the interfaces are MUCH shorter!
| Quote: | let me guess - those would
be the multimedia equivalents of TCanvas? How many interfaces do you
host on a class? How many of them are 'main' interfaces and how many are
'support' (e.g. ILoggable, ISerializable, ...)?
|
There's only 3 or 4 whoppers - base classes only. Most are support
interfaces.
| Quote: |
The "Composer" controller is done with Bold + BoldExpress + Firebird as
a
web interface. I've worked closely with Neosight to help specify and
test
Bold Express 2, and the resulting components are brilliant. I couldn't
do
this without them!
With BoldRetina on the web side?
|
"Bold Express Server" now it's version 2. Same stuff though much more fully
featured.
Bryan
|
|
| Back to top |
|
 |
Ritchie Guest
|
Posted: Sat Nov 29, 2003 12:46 am Post subject: Re: Feedback from a Selection |
|
|
In article <0jsesvg4loaa7ff60teve8m64s7mn5t7jq (AT) 4ax (DOT) com>, [email]me (AT) privacy (DOT) net[/email]
says...
| Quote: | (2) "Something's changed, here's the old selection, you go figure it
out"
I prefer the second alternative together with an observer mechanism
that allows observers to attach to specific changes in the model. The
latter is some of the things I always liked about the SmallTalk MVC
paradigm.
|
When you say specific changes, do you mean specific -kinds- of changes
(additions, removals, modifications), or do you mean changes to specific
-objects-?
Most of the observers I will have here will be views, so they'll be
concerned with reflecting the whole model and changes to it. Even an
object inspector, if it's multi-selection capable (as Delphi's one is),
may have to keep up to date on more than one object, where objects go
away, and whether the selection changes.
I guess we have something akin to (my apologies for those who don't read
in monospace :
Model<---Selection
^ ^
| Quote: | |
+---+ +--+
|
Views |
If the Model changes, the Selection and Views should be updated; if the
Selection changes, the Views should be updated.
I always find it nice to keep the visual state of each View as intact as
possible, so, for example, if you have a treeview:
- Country (scrolled off the top of the screen)
- Leaders
- Dictators
. Eric Idle
+ Liberals
- Weird
. Krusty
. Mr. Clean
- States
....and decide to delete the Weird branch and add a new dictator, it's
nice to keep:
- Country (still scrolled off the top of the screen)
- Leaders
- Dictators
. Eric Idle
. Jake the Cat From Outer Space
+ Liberals
- States
The notification from the model could simply be:
'Model changed'
You'd then get your view to scan the entire model looking for what's no
longer there and what's been added. This is less well-equipped to detect
moves, and scans on a big model could take some time (though likely only
enough to make the interface 'jerk' a bit).
Or, the notification could say:
'Model changed: Deleted ObjectID=6 (Weird), Added ObjectID=10, Added
ObjectID=10's Name "Jake the Cat From Outer Space"'
....
Mind you, if you used the above notification to actually *modify* the
Model, you could simply pass it along to the Views and the Selection.
That would make for a little more interpretation effort on the part of
the Views and Selection, but they always have the option of rescanning
instead of looking at the model.
But then there's the case of doing an Undo. Bah, if it's an Undo, a
rescan's not so bad :/
I've quite liked Smalltalk's MVC paradigm myself :)
| Quote: | Now, why the (2). The idea of a plain "you figure it out" approach
appears to me as a waste of resources considering that the information
about what has changed is already there. When a selection changes, it
spawns a memento and hands it to the observers which associated to
this specific change. There still remains some property-comparing
drugwork for the observers but at least this reduces to only those
observers which have to adjust to the specific change.
More specialized schemes will inevitably result in an explosion of the
number of classes (or messages, at least) where in the end it could
become necessary to implement a message class for every property of
the selection.
|
I have only Entities and Attributes in the scheme I'm thinking of, and
neither of them have specializations :)
I'll have to figure out a compromise between message-per-individual-
change and message-per-change-block.
One other thing I'm trying to consider (to keep the visual interface
relatively snappy) is how to make the updates asynchronous... and
therefore, how to make the Views resistant to mismatches between the
Model and View (e.g. no access violations when you try editing something
that no longer exists but hasn't been updated visually yet)
Thanks for the discussion, folks; getting things out on the table
*really* helps :)
Thanks for the thoughts, Malte :)
-- Ritchie Annand
Senior Software Architect
http://www.malibugroup.com
http://nimble.nimblebrain.net
http://wiki.nimblebrain.net
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|