Directred Event Multicasting

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Assume I have an n by n matrix of identical objects, each of which can both
invoke and consume event A. If, say, obect[1,2] invokes the event, the only
other objects that need to consume it are those in row 1 and those in column
2. Sending the notification to other objects would be a waste of CPU.

Is there an "approved" / efficient way to cause only those objects in row 1
and column 2 to receive the event notification? I've looked but just don't
see (or don't recognize) such a thing in the documentation...

Thanks in advance.
 
Pete said:
Assume I have an n by n matrix of identical objects, each of which can both
invoke and consume event A. If, say, obect[1,2] invokes the event, the only
other objects that need to consume it are those in row 1 and those in column
2. Sending the notification to other objects would be a waste of CPU.

Is there an "approved" / efficient way to cause only those objects in row 1
and column 2 to receive the event notification? I've looked but just don't
see (or don't recognize) such a thing in the documentation...

Does the object itself know its position and the objects in the other
positions?

I must say, it's not something I've encountered a need for before...
 
Hi,

If this event is only handled by certain object, you only need to add the
delegate to the event handler of the single object.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."
 
Sorry for the top posting.

If necessary, the objects can be made aware of their own position in the
matrix and can be told about other objects and their locations (all of which
are fixed). It would be better, though, if each object could remain
insensitive to context - to be able to fire the event and to have some
higher level entity route that event as required.

The problem I'm trying to solve is somewhat analogous to the Eight Queens
problem in chess. If I place a rook on a particular square (i.e. a
particular object becomes occupied), I'd like the other squares (objects) on
that rank and file to know that they're under attack. The newly occupied
square needn't care which other squares are under attack nor does the
attacked square care from where the attack comes.

In my case, I'm trying to build a Su Doku solver. In Su Doku, each square in
the matrix can potentially have one of nine values (1 through 9) and once
the value of a square is fixed, no other square on that rank or file can
have the same value. The idea is that if the value of square[m, n] becomes
fixed (e.g., it's known to be X), it would fire an event to be consumed by
the other squares on that rank or file, telling them to remove X from their
list of potential values. If that causes the value of the consuming cell to
become fixed, the consuming cell would fire off it's own similar event to
squares on it's rank and file.

I understand there are plenty of ways to do this depth-first search. I just
wondered if there was a way to use the event mechanism to get that for free.
(And, also, because it would be kind-of interesting to try.)


Jon Skeet said:
Pete said:
Assume I have an n by n matrix of identical objects, each of which can
both
invoke and consume event A. If, say, obect[1,2] invokes the event, the
only
other objects that need to consume it are those in row 1 and those in
column
2. Sending the notification to other objects would be a waste of CPU.

Is there an "approved" / efficient way to cause only those objects in row
1
and column 2 to receive the event notification? I've looked but just
don't
see (or don't recognize) such a thing in the documentation...

Does the object itself know its position and the objects in the other
positions?

I must say, it's not something I've encountered a need for before...
 
Jon Skeet said:
Pete said:
Assume I have an n by n matrix of identical objects, each of which can
both
invoke and consume event A. If, say, obect[1,2] invokes the event, the
only
other objects that need to consume it are those in row 1 and those in
column
2. Sending the notification to other objects would be a waste of CPU.

Is there an "approved" / efficient way to cause only those objects in row
1
and column 2 to receive the event notification? I've looked but just
don't
see (or don't recognize) such a thing in the documentation...

Does the object itself know its position and the objects in the other
positions?

I must say, it's not something I've encountered a need for before...

I suppose I could restate the problem for greater clarity.

Assume I have a form with two buttons, exactly one of which should be
enabled at any instant. The traditional way would be to have the form
consume the Clicked event for both buttons and to have the event handler for
each button set the Enabled property of the other button to False. I'm sure,
also, that one could set things up so that the two buttons could mutually
consume each others Clicked events, taking the form out of the mix
altogether.

But both of those approaches get a bit tedious when one introduces 81
buttons and each button has a different set of event trading partners. It
would be way cool if it were possible for, say, a single event handler to
trap the Clicked events for all buttons and, then, re-route those events (as
events, unchanged) by simply iterating over some data structure that
captures the inter-relationships between buttons.

It would be something like having a generic event (i.e., "some button,
somewhere has been clicked") but, then, only the buttons that need to know -
based on some higher-level(perhaps dynamically changing) criteria - would be
notified of that event.
 
Pete said:
Sorry for the top posting.

No problem - although I must say I'm intrigued as to why you apologised
rather than not top posting :)
If necessary, the objects can be made aware of their own position in the
matrix and can be told about other objects and their locations (all of which
are fixed). It would be better, though, if each object could remain
insensitive to context - to be able to fire the event and to have some
higher level entity route that event as required.

Well, here's an alternative way - make each of the squares expose an
event, and make each square subscribe to the events it's interested in.
So each square on the top row would subscribe to the "changed" event of
each of the other squares on the top row, etc.

The "routing" would be done once, at startup - and then you'd just fire
the event. That's the only way I can see of doing it without the square
being aware of its own position. (There may be ways I can't see, of
course :)
 
Pete said:
I suppose I could restate the problem for greater clarity.

Assume I have a form with two buttons, exactly one of which should be
enabled at any instant. The traditional way would be to have the form
consume the Clicked event for both buttons and to have the event handler for
each button set the Enabled property of the other button to False. I'm sure,
also, that one could set things up so that the two buttons could mutually
consume each others Clicked events, taking the form out of the mix
altogether.

But both of those approaches get a bit tedious when one introduces 81
buttons and each button has a different set of event trading partners.

Surely it only gets tedious when you need to wire up the events
manually. There's no need for that. For instance, you could have code
like this:
using System;

public class Square
{
const int GridSize = 9;

public event EventHandler Changed;

public static void Main()
{
// Create all the squares
Square[,] grid = new Square[GridSize,GridSize];

for (int i=0; i < GridSize; i++)
{
for (int j=0; j < GridSize; j++)
{
grid[i,j] = new Square();
}
}

// Wire up all the events
for (int i=0; i < GridSize; i++)
{
for (int j=0; j < GridSize; j++)
{
// Other squares in the same row and column
// should subscribe
for (int k=0; k < GridSize; k++)
{
if (k != i)
{
grid[i,j].Changed += new EventHandler
(grid[k,j].ChangeHandler);
}
if (k != j)
{
grid[i,j].Changed += new EventHandler
(grid[i,k].ChangeHandler);
}
}
}
}
}

public void ChangeHandler(object sender, EventArgs e)
{
// Do stuff here
}
}
It would be way cool if it were possible for, say, a single event handler to
trap the Clicked events for all buttons and, then, re-route those events (as
events, unchanged) by simply iterating over some data structure that
captures the inter-relationships between buttons.

It would have to know which location had changed though. Either the
square has to know, and tell the event handler that it was that square
(which it would normally do with the "sender" argument), or the event
handler would need to look it up to find the right square.
It would be something like having a generic event (i.e., "some button,
somewhere has been clicked") but, then, only the buttons that need to know -
based on some higher-level(perhaps dynamically changing) criteria - would be
notified of that event.

As I say though, you still need the knowledge of what's been clicked
*somewhere*.
 
Jon Skeet said:
Pete said:
I suppose I could restate the problem for greater clarity.

Assume I have a form with two buttons, exactly one of which should be
enabled at any instant. The traditional way would be to have the form
consume the Clicked event for both buttons and to have the event handler
for
each button set the Enabled property of the other button to False. I'm
sure,
also, that one could set things up so that the two buttons could mutually
consume each others Clicked events, taking the form out of the mix
altogether.

But both of those approaches get a bit tedious when one introduces 81
buttons and each button has a different set of event trading partners.

Surely it only gets tedious when you need to wire up the events
manually. There's no need for that. For instance, you could have code
like this:
using System;

public class Square
{
const int GridSize = 9;

public event EventHandler Changed;

public static void Main()
{
// Create all the squares
Square[,] grid = new Square[GridSize,GridSize];

for (int i=0; i < GridSize; i++)
{
for (int j=0; j < GridSize; j++)
{
grid[i,j] = new Square();
}
}

// Wire up all the events
for (int i=0; i < GridSize; i++)
{
for (int j=0; j < GridSize; j++)
{
// Other squares in the same row and column
// should subscribe
for (int k=0; k < GridSize; k++)
{
if (k != i)
{
grid[i,j].Changed += new EventHandler
(grid[k,j].ChangeHandler);
}
if (k != j)
{
grid[i,j].Changed += new EventHandler
(grid[i,k].ChangeHandler);
}
}
}
}
}

public void ChangeHandler(object sender, EventArgs e)
{
// Do stuff here
}
}
It would be way cool if it were possible for, say, a single event handler
to
trap the Clicked events for all buttons and, then, re-route those events
(as
events, unchanged) by simply iterating over some data structure that
captures the inter-relationships between buttons.

It would have to know which location had changed though. Either the
square has to know, and tell the event handler that it was that square
(which it would normally do with the "sender" argument), or the event
handler would need to look it up to find the right square.
It would be something like having a generic event (i.e., "some button,
somewhere has been clicked") but, then, only the buttons that need to
know -
based on some higher-level(perhaps dynamically changing) criteria - would
be
notified of that event.

As I say though, you still need the knowledge of what's been clicked
*somewhere*.

Yeah! You're right on all points. I suppose I was just thinking it might be
nice to have, in addition to the (sender, eventArgs) semantics, something
along the lines of (receiver, eventArgs) and/or (sender, receiver,
eventArgs) semantics also available. Might not be handy all the time and it
can be simutated by attaching and detaching event handlers but, well, you
know...

Thanks. Happy Holidays.
 
Pete said:
Yeah! You're right on all points. I suppose I was just thinking it might be
nice to have, in addition to the (sender, eventArgs) semantics, something
along the lines of (receiver, eventArgs) and/or (sender, receiver,
eventArgs) semantics also available. Might not be handy all the time and it
can be simutated by attaching and detaching event handlers but, well, you
know...

Hmm. One of the nice things about the current eventing model is that
the object raising the event doesn't need to know *anything* about
what's handling it - just that there's a delegate of the right type for
it to invoke. I think when you start specifying receivers, you lose a
lot of that elegance.

Of course, you can create any delegate you want and use it for your
event type - in your case you could create your own delegate which
included the position within the grid of the sender.
Thanks. Happy Holidays.

You too.
 
Back
Top