> I'm not sure what the use case for comparing two delegates is
> anyway. Can you give me some?

In a multi delegate (called event in C#), you have the possibility to add or remove delegates. For example, consider a button in a GUI. Anyone can add a delegate to its OnClick event:

...
Button myBytton = new Button ();
myButton.addOnClickHandler(
MethodClosure.newInstance(
Button.OnClickHandler, this, "myButtonPressed"));
myButton.addOnClickHandler(
MethodClosure.newInstance(
Button.OnClickHandler, this, "generalClickHandler"));
...

Which will cause the myButtonPressed and the generalClickHandler methods to be called when the button is clicked.

The question is now: If you add the same method twice, will it be called twice?

...
Button myBytton = new Button ();
myButton.addOnClickHandler(
MethodClosure.newInstance(
Button.OnClickHandler, this, "myButtonPressed"));
myButton.addOnClickHandler(
MethodClosure.newInstance(
Button.OnClickHandler, this, "myButtonPressed"));
...

Excalibur's implementation (and C#) says no. The MultiDelegate has a set-like behavior, so that adding a delegate once is the same as adding it twice. The code above is therefore equal to:

...
Button myBytton = new Button ();
myButton.addOnClickHandler(
MethodClosure.newInstance(
Button.OnClickHandler, this, "myButtonPressed"));
...

as the second add has no effect.

In order for the MultiDelegate to figure out if it already has a delegate in its collection of delegates, it must have some method of comparing them. And that's where equals() and hashCode() comes in.

> Sure. Although if it does happen that CGLIB gets used by Avalon, there
> would need to be a good rationale and understanding of the general
> usefulness of each class that gets moved over. For my benefit, it would be
> helpful to have a summary of which classes are under consideration, how
> they fit into the Avalon framework at a macro level, and how they could be
> useful outside of Avalon.

Of course. Avalon is roughly divided into two parts: Framework and the rest. Framework is the "bare minimum" - it is usually just interfaces and the contracts surrounding them. We're not about to put in a CGLIB dependency here. We can use delegates without introducing a CGLIB dependency - all that will be in Framework would be the delegate interfaces. How the actual delegates are created is left as out-of-scope for Framework.

Then you have "the rest": Here you'll find Phoenix, Fortress and all the other "big things" as measured in lines of code and features. A BCEL dependency here is OK.

The classes we would donate are usually those that have very well-defined contracts. For example, you can't change a delegate into something that would break Avalon and still keep it a delegate.

> I understand now. I'll go ahead and make the factory protected, and
> change the name to something less likely to conflict (for example
> "cglib_newInstance", which is already used in another class for this same
> reason).

May I suggest the name "$cglib_NewInstance"? I think I read somewhere that identifiers starting with a "$" are a no-no for programmers, meaning that we can use it for this purpose. (Should Sun start including a method by that name there's just one place where it is used, and if someone else creates a delegate with that signature, well, then that person is clearly in the wrong.)

> The problem is that invoking the constructor of the generated class would
> require reflection, which will give back a lot of the performance gains.
> The only other alternative is to generate yet another class whose sole
> purpose is to call the constructor of the delegate, but I do not think it
> is worth it.

I value startup time less than runtime. A delegate will only be created once, but may be called thousands of times. However, with a name that is forbidden for general use (cglib_newInstance or $cglib_newInstance), the collision scenario should not happen, so I think this is a non-issue.

/LS


--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to