D - new D site
- Pavel Minayev (7/7) Mar 30 2002 My old tiny D page had grown into the site! You can still get all
- Walter (3/10) Mar 31 2002 Thanks! It's a cool web site. -Walter
- OddesE (13/20) Mar 31 2002 Wow Pavel, it looks great!
- Pavel Minayev (3/8) Mar 31 2002 Yes, it seems to be the best way for now!
- J. Daniel Smith (5/13) Apr 01 2002 This looks a lot like C#'s "delegates and events" mechanism. Coincidenc...
- Pavel Minayev (4/6) Apr 01 2002 I proposed it a hundred times already!
- Walter (6/12) Apr 01 2002 Coincidence?
- J. Daniel Smith (10/22) Apr 01 2002 Essentially, C#'s delegates are a way to easily maintain a collection of
- Pavel Minayev (44/46) Apr 01 2002 First of all, an example:
- Pavel Minayev (13/13) Apr 01 2002 Also, note that several handlers may be attached to a single
- Jan Jezabek (18/33) Apr 02 2002 I think that pointers to member functions (which as far as I know aren't...
- Pavel Minayev (5/20) Apr 02 2002 Don't forget that there is no fixed calling convention in D,
- Russ Lewis (8/13) Apr 02 2002 Function pointers need to specify the calling conventions, then...includ...
- Russ Lewis (14/14) Apr 02 2002 There are two key types of member function pointers; if D supports membe...
- Jan Jezabek (3/6) Apr 02 2002 Isn't it the same as pointers to static member functions (I might be
- Russ Lewis (16/22) Apr 02 2002 I'm thinking more along the lines of things that might be registered for...
- Jan Jezabek (45/55) Apr 02 2002 Something like a static pointer to a non-static member function? :) I
- Pavel Minayev (12/17) Apr 02 2002 calls.
- Richard Krehbiel (18/23) Apr 02 2002 calls.
- Pavel Minayev (9/15) Apr 02 2002 was
- Russ Lewis (12/17) Apr 02 2002 Guess I wasn't clear. :) I meant this only for member function pointer...
- Walter (5/10) Apr 02 2002 absent
- Pavel Minayev (10/12) Apr 02 2002 It is the same type of pointers you could see in C++:
- Sean L. Palmer (8/20) Apr 04 2002 long,
- Russell Borogove (5/16) Apr 02 2002 I'm not sure I understand -- normally, wouldn't the target-object
- Russ Lewis (24/27) Apr 02 2002 Let's use Pavel's example. We have created a button object, which has s...
- Pavel Minayev (11/14) Apr 02 2002 No. Delegate variable stores both pointer to object and to method,
- J. Daniel Smith (51/51) Apr 02 2002 charset="Windows-1252"
- Pavel Minayev (9/9) Apr 02 2002 charset="Windows-1252"
- Walter (7/53) Apr 02 2002 So, "event" consists of both an object pointer and a virtual function? I...
- J. Daniel Smith (10/76) Apr 02 2002 In C# (actually, the .NET framework), an object pointer and a pointer to...
- Walter (12/91) Apr 02 2002 Hmm. I wonder if the "pointer to function" part is a vtbl[] index or a h...
- Pavel Minayev (8/10) Apr 02 2002 hard
- Walter (4/14) Apr 02 2002 Is it expected to work with non-member functions too, with member functi...
- Russ Lewis (9/23) Apr 02 2002 It would be nice to have a type that could mix
- Pavel Minayev (65/67) Apr 02 2002 functions
- J. Daniel Smith (6/73) Apr 02 2002 I think the C# compiler uses some reflection stuff so that it can do
- Walter (11/78) Apr 03 2002 The C# syntax I find very confusing. The delegate declaration looks like...
- Pavel Minayev (17/26) Apr 03 2002 possible
- Walter (20/38) Apr 03 2002 a
- Patrick Down (9/9) Mar 31 2002 I't a really nice site Pavel. I do have
- Pavel Minayev (9/17) Mar 31 2002 Oh yes, you've caught me! I've just done the change to the event system,
- Sean L. Palmer (5/12) Mar 31 2002 Oh, God, Walter, it's too bad you can't make the D language specificatio...
- Pavel Minayev (3/5) Apr 01 2002 Well, he could just make pointers to methods... =)
- Svyatoslav Bezgin (3/6) Apr 01 2002 I completely agree with Pavel that we Must make pointers to methods
- Russ Lewis (7/8) Apr 01 2002 Maybe, since we're moving from C to D, we should be known as a dommunity...
- OddesE (10/18) Apr 02 2002 dommunity... :)
- Robert W. Cunningham (3/21) Apr 02 2002 Yeah, but it's not like we want to be called the "Kaas Kopmunity"...
- OddesE (12/34) Apr 03 2002 LOL!
My old tiny D page had grown into the site! You can still get all the stuff I've made, there, but there's also my D FAQ, and some information on my D projects, including not-yet-released WinD. Unfortunately, Russ is unable to provide hosting further, for several reasons, so the site has moved to my ex-homepage, http://int19h.tamb.ru. You can still access it via the old URL, though - it'll redirect you there.
Mar 30 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a86b4p$1elj$1 digitaldaemon.com...My old tiny D page had grown into the site! You can still get all the stuff I've made, there, but there's also my D FAQ, and some information on my D projects, including not-yet-released WinD. Unfortunately, Russ is unable to provide hosting further, for several reasons, so the site has moved to my ex-homepage, http://int19h.tamb.ru. You can still access it via the old URL, though - it'll redirect you there.Thanks! It's a cool web site. -Walter
Mar 31 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a86b4p$1elj$1 digitaldaemon.com...My old tiny D page had grown into the site! You can still get all the stuff I've made, there, but there's also my D FAQ, and some information on my D projects, including not-yet-released WinD. Unfortunately, Russ is unable to provide hosting further, for several reasons, so the site has moved to my ex-homepage, http://int19h.tamb.ru. You can still access it via the old URL, though - it'll redirect you there.Wow Pavel, it looks great! I liked the code example from WinD! So it seems you have decided on the event handling? You seem to be using a function pointer in combination with an object pointer? -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
Mar 31 2002
"OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a8868m$2d6u$1 digitaldaemon.com...Wow Pavel, it looks great! I liked the code example from WinD! So it seems you have decided on the event handling? You seem to be using a function pointer in combination with an object pointer?Yes, it seems to be the best way for now!
Mar 31 2002
Dan "Pavel Minayev" <evilone omen.ru> wrote in message news:a88uv7$2q1e$1 digitaldaemon.com..."OddesE" <OddesE_XYZ hotmail.com> wrote in message news:a8868m$2d6u$1 digitaldaemon.com...Wow Pavel, it looks great! I liked the code example from WinD! So it seems you have decided on the event handling? You seem to be using a function pointer in combination with an object pointer?Yes, it seems to be the best way for now!
Apr 01 2002
"J. Daniel Smith" <j_daniel_smith HoTMaiL.com> wrote in message news:a89tgs$bmi$1 digitaldaemon.com...I proposed it a hundred times already! Probably, I wasn't that convincing... =)
Apr 01 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8a89q$hd7$1 digitaldaemon.com..."J. Daniel Smith" <j_daniel_smith HoTMaiL.com> wrote in message news:a89tgs$bmi$1 digitaldaemon.com...Coincidence?Is it worth making this technique a standard part of the language likeI proposed it a hundred times already! Probably, I wasn't that convincing... =)The problem is I don't understand the problem. I've been buried with work lately, and haven't given that issue the attention it needs. -Walter
Apr 01 2002
(member-) function pointers; firing an event invokes each of the function pointers. With a bit of work, you can achieve similar functionality in C++, although you need templates (and ideally partial template specialization) for type-safety. Building the feature directly into the language makes the "roll your own"). Dan "Walter" <walter digitalmars.com> wrote in message news:a8ad5n$r5c$1 digitaldaemon.com..."Pavel Minayev" <evilone omen.ru> wrote in message news:a8a89q$hd7$1 digitaldaemon.com..."J. Daniel Smith" <j_daniel_smith HoTMaiL.com> wrote in message news:a89tgs$bmi$1 digitaldaemon.com...Coincidence?Is it worth making this technique a standard part of the language likeI proposed it a hundred times already! Probably, I wasn't that convincing... =)The problem is I don't understand the problem. I've been buried with work lately, and haven't given that issue the attention it needs. -Walter
Apr 01 2002
"Walter" <walter digitalmars.com> wrote in message news:a8ad5n$r5c$1 digitaldaemon.com...The problem is I don't understand the problem. I've been buried with work lately, and haven't given that issue the attention it needs. -WalterFirst of all, an example: class Button { event void onMouseMove(int, int); // event (pointer to function) ... void mouseMoved(int x, int y) { // raise event (will first call OK_MouseMove1, then OK_MouseMove2) onMouseMove(x, y); } } void OK_MouseMove1(int x, int y) // global event handler { ... } class MyForm: Form { Button OK; void OK_MouseMove2(int x, int y) // local event handler { ... } this() { OK.onMouseMove = OK_MouseMove1; // set event handler OK.onMouseMove ~= OK_MouseMove2; // add another handler } } Advantage of this approach is that you can make global, static, and nonstatic member functions event handlers - unlike usual function pointers, which only allow global and static functions. In most cases, event handler is actually part of the class, and now, to make it work, it needs to be declared static, and to get "this" pointer as one of explicit arguments: static void OK_MouseMove(Object self, int x, int y) { ... } Not only this requires typing "self.blablabla" all the time (or wrap the function into with-block), but you also have to cast self to whatever class it actually is...
Apr 01 2002
Also, note that several handlers may be attached to a single event slot. Practically, it's an array of pointers, not a single pointer, and functions are called in straight order: event void onInit(); void foo(); void bar(); void baz(); onInit = &foo; // set onInit = &onInit ~ &bar; // add another onInit ~= &baz; // one more onInit = onInit[0 .. 1] ~ // remove bar() onInit[2 .. 3]; onInit(); // call foo(), then baz()
Apr 01 2002
I think that pointers to member functions (which as far as I know aren't there in D) should be explicitly castable to a normal function pointer, for example: class one { public: int x(int y); }; typedef int (*FPTR)(void *, int); void main() { FPTR z = (FPTR) &one::x; // this will give an error one instance; z(&instance, 10); // same as instance->x } If such cast was legal, it would solve your problem (of course I might be wrong:). Of course it's quite inconvenient, and I would prefer using delegates just as I preferred virtual functions over function pointers.Advantage of this approach is that you can make global, static, and nonstatic member functions event handlers - unlike usual function pointers, which only allow global and static functions. In most cases, event handler is actually part of the class, and now, to make it work, it needs to be declared static, and to get "this" pointer as one of explicit arguments: static void OK_MouseMove(Object self, int x, int y) { ... } Not only this requires typing "self.blablabla" all the time (or wrap the function into with-block), but you also have to cast self to whatever class it actually is...
Apr 02 2002
"Jan Jezabek" <jezabek poczta.onet.pl> wrote in message news:3CA9DC00.4070601 poczta.onet.pl...I think that pointers to member functions (which as far as I know aren't there in D) should be explicitly castable to a normal function pointer, for example: class one { public: int x(int y); }; typedef int (*FPTR)(void *, int); void main() { FPTR z = (FPTR) &one::x; // this will give an error one instance; z(&instance, 10); // same as instance->x }Don't forget that there is no fixed calling convention in D, functions might get called in a way different from methods, so this is not guaranteed to work...
Apr 02 2002
Pavel Minayev wrote:"Jan Jezabek" <jezabek poczta.onet.pl> wrote in message news:3CA9DC00.4070601 poczta.onet.pl... Don't forget that there is no fixed calling convention in D, functions might get called in a way different from methods, so this is not guaranteed to work...Function pointers need to specify the calling conventions, then...including, perhaps a "D-member-function" calling convention. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Apr 02 2002
There are two key types of member function pointers; if D supports member function pointers, it should support both: * Pointers that include a pointer to the object they are to be called on. These are useful for event handlers and such, where you know which object should handle the event. * Pointers that do NOT include an object pointer. These are useful where you might have a class (perhaps a child class) register the handler to use on ANY of its objects when a certain event occurs. I don't know what a good syntax for the two types might be. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Apr 02 2002
Isn't it the same as pointers to static member functions (I might be getting something wrong)? Russ Lewis wrote:* Pointers that do NOT include an object pointer. These are useful where you might have a class (perhaps a child class) register the handler to use on ANY of its objects when a certain event occurs.
Apr 02 2002
Jan Jezabek wrote:Isn't it the same as pointers to static member functions (I might be getting something wrong)? Russ Lewis wrote:I'm thinking more along the lines of things that might be registered for a class of objects, but when called should be called as member objects, not static. This would work when you have a group of related objects, and you want to save a single function pointer that is the handler for a particular event for ALL of those objects. Also, I think that member function pointers should properly handle virtual calls. That is, you can save a pointer to a virtual function (remember, all member functions in D are virtual automatically), and the code will, at runtime, call the right virtual version of it. This probably would require the compiler to create wrapper functions in some circumstances :( -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]* Pointers that do NOT include an object pointer. These are useful where you might have a class (perhaps a child class) register the handler to use on ANY of its objects when a certain event occurs.
Apr 02 2002
Russ Lewis wrote:I'm thinking more along the lines of things that might be registered for a class of objects, but when called should be called as member objects, not static. This would work when you have a group of related objects, and you want to save a single function pointer that is the handler for a particular event for ALL of those objects.Something like a static pointer to a non-static member function? :) I know if there are static delegates.Also, I think that member function pointers should properly handle virtual calls. That is, you can save a pointer to a virtual function (remember, all member functions in D are virtual automatically), and the code will, at runtime, call the right virtual version of it. This probably would require the compiler to create wrapper functions in some circumstances :(I think it is easier than having mixed virtual and non-virtual functions. Consider the following example: #include <stdio.h> class base { public: int a() { printf("base\n"); } virtual int b() { printf("base\n"); } }; class derived: public base { public: int a() { printf("derived\n"); } virtual int b() { printf("derived\n"); } }; int main() { int (base::*ptr)(); base X; derived Y; ptr = &base::a; // non-virtual (X.*ptr)(); // prints "base" (Y.*ptr)(); // prints "base" ptr = &base::b; // virtual (X.*ptr)(); // prints "base" (Y.*ptr)(); // prints "derived" return 0; } How does the code know whether to call a virtual or a non-virtual function?
Apr 02 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3CA9E742.B2C0766E deming-os.org...Also, I think that member function pointers should properly handle virtualcalls.That is, you can save a pointer to a virtual function (remember, allmemberfunctions in D are virtual automatically), and the code will, at runtime,call theright virtual version of it. This probably would require the compiler tocreatewrapper functions in some circumstances :(You probably mean for the second type of pointers (to class members rather than to object members)? Once again, I don't think these are of real importance, for now at least. Delegates are, on one hand, more useful, and on other, seem to be simpler to implement (so we can hope to convince Walter to do it relatively easy =)).
Apr 02 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3CA9E742.B2C0766E deming-os.org...Also, I think that member function pointers should properly handle virtualcalls.That is, you can save a pointer to a virtual function (remember, allmemberfunctions in D are virtual automatically), and the code will, at runtime,call theright virtual version of it. This probably would require the compiler tocreatewrapper functions in some circumstances :(So, an object should be able to change type during it's lifetime? That's not an operation that's supported in any OO-language that I know of - absent ugly unsupported pointer-poking hacks. It wasn't too many message ago I was reading how Walter was messing with the vtbl in his platform/compiler-specific code - for shame, Walter! :-) Even so, it supportable by having a method pointer be {object pointer, vtbl offset}, rather than {function pointer, object pointer}. Not really a big deal when all methods are virtual; problematic when many are not (as in C++). -- Richard Krehbiel, Arlington, VA, USA rich kastle.com (work) or krehbiel3 comcast.net (personal)
Apr 02 2002
"Richard Krehbiel" <rich kastle.com> wrote in message news:a8d3jm$2ejp$1 digitaldaemon.com...ugly unsupported pointer-poking hacks. It wasn't too many message ago Iwasreading how Walter was messing with the vtbl in his platform/compiler-specific code - for shame, Walter! :-)Well, actually, it was me messing with the vtbl =)Even so, it supportable by having a method pointer be {object pointer,vtbloffset}, rather than {function pointer, object pointer}. Not really a big deal when all methods are virtual; problematic when many are not (as inDon't see any reason in it; why store the offset, if the value there is constant and doesn't change as program runs? Isn't it simplier AND faster to store the pointer itself, especially since not all methods are virtual (compiler decides).
Apr 02 2002
Richard Krehbiel wrote:So, an object should be able to change type during it's lifetime? That's not an operation that's supported in any OO-language that I know of - absent ugly unsupported pointer-poking hacks. It wasn't too many message ago I was reading how Walter was messing with the vtbl in his platform/compiler-specific code - for shame, Walter! :-)Guess I wasn't clear. :) I meant this only for member function pointers that did NOT include the object pointer. That is, you attach the pointer at one time and at a later date use it against some object(s). The pointer, in this case, would use the appropriate virtual function for the object it was run against. However, if we only support pointers to static members and pointers to members WITH the object pointer, then you're right, this point is moot. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Apr 02 2002
"Richard Krehbiel" <rich kastle.com> wrote in message news:a8d3jm$2ejp$1 digitaldaemon.com...So, an object should be able to change type during it's lifetime? That's not an operation that's supported in any OO-language that I know of -absentugly unsupported pointer-poking hacks. It wasn't too many message ago Iwasreading how Walter was messing with the vtbl in his platform/compiler-specific code - for shame, Walter! :-)All's fair when trying to win benchmarks!
Apr 02 2002
"Jan Jezabek" <jezabek poczta.onet.pl> wrote in message news:3CA9E3ED.3060600 poczta.onet.pl...Isn't it the same as pointers to static member functions (I might be getting something wrong)?It is the same type of pointers you could see in C++: class Foo; void (Foo::*ptr)(); // pointer to member of Foo Foo foo; foo->*ptr(); // call it I don't really see much need in it, however. In my experience (not so long, but still...), I've never ever used C++ pointers to members. Can anyone give a sample where these might be useful?
Apr 02 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8ct54$2aja$1 digitaldaemon.com..."Jan Jezabek" <jezabek poczta.onet.pl> wrote in message news:3CA9E3ED.3060600 poczta.onet.pl...long,Isn't it the same as pointers to static member functions (I might be getting something wrong)?It is the same type of pointers you could see in C++: class Foo; void (Foo::*ptr)(); // pointer to member of Foo Foo foo; foo->*ptr(); // call it I don't really see much need in it, however. In my experience (not sobut still...), I've never ever used C++ pointers to members. Can anyone give a sample where these might be useful?They're good for implementing some kinds of state machines... usually the object pointer is something simple, such as "this" or "objectwithmethodtocall". Other people may have found some more exotic uses for it. Sean
Apr 04 2002
Russ Lewis wrote:There are two key types of member function pointers; if D supports member function pointers, it should support both: * Pointers that include a pointer to the object they are to be called on. These are useful for event handlers and such, where you know which object should handle the event. * Pointers that do NOT include an object pointer. These are useful where you might have a class (perhaps a child class) register the handler to use on ANY of its objects when a certain event occurs. I don't know what a good syntax for the two types might be.I'm not sure I understand -- normally, wouldn't the target-object pointer be part of the call, rather than part of the function pointer? -Russell B
Apr 02 2002
Russell Borogove wrote:I'm not sure I understand -- normally, wouldn't the target-object pointer be part of the call, rather than part of the function pointer?Let's use Pavel's example. We have created a button object, which has some standard behavior. Then we create a form that includes that button. When the button is pressed, we want a specific function in the form to be called. Thus, we have a function pointer in the Button object, which we set to point at the form object. When the button is pressed, this function is called. Now, it makes no sense in this example to have a "generic" function pointer that can be called on any object...we only want the call to go to one specific Form object. Thus, if you don't include the pointer to the Form in the function pointer, then you have to have a 2nd variable in the Button that stores the pointer to the Form. Worse, you have to remember that this Button is a standard object which could be included in many things...Forms, dialogs, message boxes, etc. So we can't actually store a pointer to type Form there...instead, we have to store a pointer to Object, since it could point to any type of object. But will the function pointer syntax allow you to call a member function pointer to Form when all you have is a pointer to an Object? Anyhow, what I'm saying is that in some circumstances, it doesn't make any sense to separate the function pointer from the object it is intended to be called with. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Apr 02 2002
"Russell Borogove" <kaleja estarcion.com> wrote in message news:3CA9E738.30607 estarcion.com...I'm not sure I understand -- normally, wouldn't the target-object pointer be part of the call, rather than part of the function pointer?No. Delegate variable stores both pointer to object and to method, and it doesn't care about object's class at all. When you call the pointer, it passes the object to the function as if it was "this". As the result, pointers to member functions behave in the same way as pointers to static functions - you won't see would be able to hold pointers to static functions as well (when pointer to object == null), and be able to call both types properly.
Apr 02 2002
charset="Windows-1252" Content-Transfer-Encoding: quoted-printable Here's some C++ code snippets to demonstrate how delegates/events work = functions, everything is in some class. =20 Dan =20 class DelegatesAndEvents { typedef DelegateT<Object::void1_T<string>::mf_t, string> = PrintString_; public: template <typename OBJECT> static PrintString_ PrintString(OBJECT& o, void = (OBJECT::*mf)(string)) { return PrintString_(o, = static_cast<Object::void1_T<string>::mf_t>(mf)); } PrintString_::Event MyPrintString; =20 =20 void FirePrintString(string s) { MyPrintString(s); } }; =20 class MyDelegates : public ObjectT<MyDelegates> { private: string m_name; public: void SimpleDelegateFunction(string s) { printf("SimpleDelegateFunction called from %s, = string=3D%s\n", m_name, s); } }; =20 void main() { DelegatesAndEvents dae; MyDelegates d; =20 dae.MyPrintString +=3D DelegatesAndEvents::PrintString(d, = &MyDelegates::SimpleDelegateFunction); =20 dae.FirePrintString("Event fired!"); } =20
Apr 02 2002
charset="Windows-1252" Content-Transfer-Encoding: quoted-printable "J. Daniel Smith" <j_daniel_smith HoTMaiL.com> wrote in message = news:a8d5d1$2fic$1 digitaldaemon.com... Here's some C++ code snippets to demonstrate how delegates/events work = functions, everything is in some class. globals) to be used as delegates.
Apr 02 2002
So, "event" consists of both an object pointer and a virtual function? Is the event an array of these, called sequentially, or only the "top of stack" last entry is called? "Pavel Minayev" <evilone omen.ru> wrote in message news:a8afmg$sb6$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8ad5n$r5c$1 digitaldaemon.com...workThe problem is I don't understand the problem. I've been buried withfunction)lately, and haven't given that issue the attention it needs. -WalterFirst of all, an example: class Button { event void onMouseMove(int, int); // event (pointer to... void mouseMoved(int x, int y) { // raise event (will first call OK_MouseMove1, then OK_MouseMove2) onMouseMove(x, y); } } void OK_MouseMove1(int x, int y) // global event handler { ... } class MyForm: Form { Button OK; void OK_MouseMove2(int x, int y) // local event handler { ... } this() { OK.onMouseMove = OK_MouseMove1; // set event handler OK.onMouseMove ~= OK_MouseMove2; // add another handler } } Advantage of this approach is that you can make global, static, and nonstatic member functions event handlers - unlike usual function pointers, which only allow global and static functions. In most cases, event handler is actually part of the class, and now, to make it work, it needs to be declared static, and to get "this" pointer as one of explicit arguments: static void OK_MouseMove(Object self, int x, int y) { ... } Not only this requires typing "self.blablabla" all the time (or wrap the function into with-block), but you also have to cast self to whatever class it actually is...
Apr 02 2002
of its member functions are wrapped up into a single object called a object. An Event object is a collection of delegates; the collection itself is a "set" because 1) a calling order is not defined and 2) adding the same delegate twice does not result in two calls. Dan "Walter" <walter digitalmars.com> wrote in message news:a8corb$28g2$1 digitaldaemon.com...So, "event" consists of both an object pointer and a virtual function? Is the event an array of these, called sequentially, or only the "top ofstack"last entry is called? "Pavel Minayev" <evilone omen.ru> wrote in message news:a8afmg$sb6$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8ad5n$r5c$1 digitaldaemon.com...workThe problem is I don't understand the problem. I've been buried withfunction)lately, and haven't given that issue the attention it needs. -WalterFirst of all, an example: class Button { event void onMouseMove(int, int); // event (pointer to... void mouseMoved(int x, int y) { // raise event (will first call OK_MouseMove1, then OK_MouseMove2) onMouseMove(x, y); } } void OK_MouseMove1(int x, int y) // global event handler { ... } class MyForm: Form { Button OK; void OK_MouseMove2(int x, int y) // local event handler { ... } this() { OK.onMouseMove = OK_MouseMove1; // set event handler OK.onMouseMove ~= OK_MouseMove2; // add another handler } } Advantage of this approach is that you can make global, static, and nonstatic member functions event handlers - unlike usual function pointers, which only allow global and static functions. In most cases, event handler is actually part of the class, and now, to make it work, it needs to be declared static, and to get "this" pointer as one of explicit arguments: static void OK_MouseMove(Object self, int x, int y) { ... } Not only this requires typing "self.blablabla" all the time (or wrap the function into with-block), but you also have to cast self to whatever class it actually is...
Apr 02 2002
Hmm. I wonder if the "pointer to function" part is a vtbl[] index or a hard pointer. "J. Daniel Smith" <j_daniel_smith HoTMaiL.com> wrote in message news:a8cr62$29g9$1 digitaldaemon.com...oneof its member functions are wrapped up into a single object called a object. An Event object is a collection of delegates; the collectionitselfis a "set" because 1) a calling order is not defined and 2) adding thesamedelegate twice does not result in two calls. Dan "Walter" <walter digitalmars.com> wrote in message news:a8corb$28g2$1 digitaldaemon.com...IsSo, "event" consists of both an object pointer and a virtual function?whichthe event an array of these, called sequentially, or only the "top ofstack"last entry is called? "Pavel Minayev" <evilone omen.ru> wrote in message news:a8afmg$sb6$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8ad5n$r5c$1 digitaldaemon.com...workThe problem is I don't understand the problem. I've been buried withfunction)lately, and haven't given that issue the attention it needs. -WalterFirst of all, an example: class Button { event void onMouseMove(int, int); // event (pointer to... void mouseMoved(int x, int y) { // raise event (will first call OK_MouseMove1, then OK_MouseMove2) onMouseMove(x, y); } } void OK_MouseMove1(int x, int y) // global event handler { ... } class MyForm: Form { Button OK; void OK_MouseMove2(int x, int y) // local event handler { ... } this() { OK.onMouseMove = OK_MouseMove1; // set event handler OK.onMouseMove ~= OK_MouseMove2; // add another handler } } Advantage of this approach is that you can make global, static, and nonstatic member functions event handlers - unlike usual function pointers,isonly allow global and static functions. In most cases, event handlerarguments:actually part of the class, and now, to make it work, it needs to be declared static, and to get "this" pointer as one of explicitthestatic void OK_MouseMove(Object self, int x, int y) { ... } Not only this requires typing "self.blablabla" all the time (or wrapfunction into with-block), but you also have to cast self to whatever class it actually is...
Apr 02 2002
"Walter" <walter digitalmars.com> wrote in message news:a8ct2q$2ain$1 digitaldaemon.com...Hmm. I wonder if the "pointer to function" part is a vtbl[] index or ahardpointer.There's no reason in storing index to vtbl, since you have a pointer to _object_, not _class_ - and object's class (and thus all vtbl entries) is known at run-time. So, when you write &foo, the compiler looks for this function in the vtbl, gets the pointer, and stores it into the delegate struct.
Apr 02 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8ctft$2ao5$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8ct2q$2ain$1 digitaldaemon.com...Is it expected to work with non-member functions too, with member functions arbitrarilly mixed in?Hmm. I wonder if the "pointer to function" part is a vtbl[] index or ahardpointer.There's no reason in storing index to vtbl, since you have a pointer to _object_, not _class_ - and object's class (and thus all vtbl entries) is known at run-time. So, when you write &foo, the compiler looks for this function in the vtbl, gets the pointer, and stores it into the delegate struct.
Apr 02 2002
Walter wrote:"Pavel Minayev" <evilone omen.ru> wrote in message news:a8ctft$2ao5$1 digitaldaemon.com...It would be nice to have a type that could mix pointer-to-member-function-with-object and pointer-to-global-function, but this might be too much to ask for from the compiler. -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]"Walter" <walter digitalmars.com> wrote in message news:a8ct2q$2ain$1 digitaldaemon.com...Is it expected to work with non-member functions too, with member functions arbitrarilly mixed in?Hmm. I wonder if the "pointer to function" part is a vtbl[] index or ahardpointer.There's no reason in storing index to vtbl, since you have a pointer to _object_, not _class_ - and object's class (and thus all vtbl entries) is known at run-time. So, when you write &foo, the compiler looks for this function in the vtbl, gets the pointer, and stores it into the delegate struct.
Apr 02 2002
"Walter" <walter digitalmars.com> wrote in message news:a8d3t1$2em9$1 digitaldaemon.com...Is it expected to work with non-member functions too, with memberfunctionsarbitrarilly mixed in?Practically, internals could look like this: // format of delegate pointer struct Delegate { Object obj; void* func; } class Form { void bar(int n); } Form foo; void baz(int n); delegate void ptr(int); // declare delegate pointer ptr = &foo.bar; // store pointer to method bar() of object foo /* Implemented as: ptr.obj = foo; ptr.func = &foo.classinfo.vtbl[bar]; */ ptr(666); // call it /* Implemented as: if (obj != null) // member function (our case) (cast(void (*ptr)(Object, int)) ptr.func)(obj, 666); else // static function (cast(void (*ptr)(int)) ptr.func)(666); */ ptr = &baz; // store pointer to function baz() /* Implemented as: ptr.obj = null; ptr.func = &baz; */ ptr(666); // call it /* Implemented as: if (obj != null) // member function (cast(void (*ptr)(Object, int)) ptr.func)(obj, 666); else // static function (our case) (cast(void (*ptr)(int)) ptr.func)(666); */ As you can see, the check is done at run-time. This makes things a bit slower, but more flexible. For example, you could write: // sorts array of strings, using user-defined comparison function void sort(char[][] s, delegate int cmp(char[], char[])); int my_sort(char[] s1, char[] s2); sort(foo, &my_sort); class Bar { bit case_sensitive; int bar_sort(char[] s1, char[] s2) { if (this.case_sensitive) ... else ... } void baz() { sort(foo, &bar_sort); } }
Apr 02 2002
typechecking at compile time. With some effort in C++, you can do it all Dan "Pavel Minayev" <evilone omen.ru> wrote in message news:a8d552$2fc7$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8d3t1$2em9$1 digitaldaemon.com...Is it expected to work with non-member functions too, with memberfunctionsarbitrarilly mixed in?Practically, internals could look like this: // format of delegate pointer struct Delegate { Object obj; void* func; } class Form { void bar(int n); } Form foo; void baz(int n); delegate void ptr(int); // declare delegate pointer ptr = &foo.bar; // store pointer to method bar() of object foo /* Implemented as: ptr.obj = foo; ptr.func = &foo.classinfo.vtbl[bar]; */ ptr(666); // call it /* Implemented as: if (obj != null) // member function (our case) (cast(void (*ptr)(Object, int)) ptr.func)(obj, 666); else // static function (cast(void (*ptr)(int)) ptr.func)(666); */ ptr = &baz; // store pointer to function baz() /* Implemented as: ptr.obj = null; ptr.func = &baz; */ ptr(666); // call it /* Implemented as: if (obj != null) // member function (cast(void (*ptr)(Object, int)) ptr.func)(obj, 666); else // static function (our case) (cast(void (*ptr)(int)) ptr.func)(666); */ As you can see, the check is done at run-time. This makes things a bit slower, but more flexible. For example, you could write: // sorts array of strings, using user-defined comparison function void sort(char[][] s, delegate int cmp(char[], char[])); int my_sort(char[] s1, char[] s2); sort(foo, &my_sort); class Bar { bit case_sensitive; int bar_sort(char[] s1, char[] s2) { if (this.case_sensitive) ... else ... } void baz() { sort(foo, &bar_sort); } }
Apr 02 2002
storage class, but it isn't, it's a type component. It doesn't seem possible or a pointer to a delegate or a function returning a delegate. The static/virtual delegate call shouldn't cause a slowdown in D, for the happy coincidence that the 'this' pointer is passed in EAX. Hence, just stuff the object reference in EAX after pushing the parameters. If the function doesn't take a this pointer, it ignores EAX with no adverse consequences. "Pavel Minayev" <evilone omen.ru> wrote in message news:a8d552$2fc7$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8d3t1$2em9$1 digitaldaemon.com...Is it expected to work with non-member functions too, with memberfunctionsarbitrarilly mixed in?Practically, internals could look like this: // format of delegate pointer struct Delegate { Object obj; void* func; } class Form { void bar(int n); } Form foo; void baz(int n); delegate void ptr(int); // declare delegate pointer ptr = &foo.bar; // store pointer to method bar() of object foo /* Implemented as: ptr.obj = foo; ptr.func = &foo.classinfo.vtbl[bar]; */ ptr(666); // call it /* Implemented as: if (obj != null) // member function (our case) (cast(void (*ptr)(Object, int)) ptr.func)(obj, 666); else // static function (cast(void (*ptr)(int)) ptr.func)(666); */ ptr = &baz; // store pointer to function baz() /* Implemented as: ptr.obj = null; ptr.func = &baz; */ ptr(666); // call it /* Implemented as: if (obj != null) // member function (cast(void (*ptr)(Object, int)) ptr.func)(obj, 666); else // static function (our case) (cast(void (*ptr)(int)) ptr.func)(666); */ As you can see, the check is done at run-time. This makes things a bit slower, but more flexible. For example, you could write: // sorts array of strings, using user-defined comparison function void sort(char[][] s, delegate int cmp(char[], char[])); int my_sort(char[] s1, char[] s2); sort(foo, &my_sort); class Bar { bit case_sensitive; int bar_sort(char[] s1, char[] s2) { if (this.case_sensitive) ... else ... } void baz() { sort(foo, &bar_sort); } }
Apr 03 2002
"Walter" <walter digitalmars.com> wrote in message news:a8eie6$40d$1 digitaldaemon.com...storage class, but it isn't, it's a type component. It doesn't seempossibledelegatesor a pointer to a delegate or a function returning a delegate.which declares type, and not variable: delegate void Foo(int); // Foo is a new type Foo ptr; // declare a pointer of that type So, you can actually have arrays: Foo[] ptr; Still, I like your syntax more. It is more distinct from normal function declaration.The static/virtual delegate call shouldn't cause a slowdown in D, for the happy coincidence that the 'this' pointer is passed in EAX. Hence, just stuff the object reference in EAX after pushing the parameters. If the function doesn't take a this pointer, it ignores EAX with no adverse consequences.It's implementation detail, I guess. As long as it works, great, and no matter how it is done. I wouldn't mind if it were slower than normal ptr call, but if you can make it the same, well, it's great! By the way, I guess functions with non-D calling conventions cannot be delegated?
Apr 03 2002
"Pavel Minayev" <evilone omen.ru> wrote in message news:a8evkh$5tf$1 digitaldaemon.com..."Walter" <walter digitalmars.com> wrote in message news:a8eie6$40d$1 digitaldaemon.com...aThat completely threw me. If the descriptions would just *say* that it was a wierd form of typedef, it would have made a lot more sense to me. I couldn't figure out if it was declaring a delegate type, a variable of type delegate, or a function to be delegated, hence I couldn't figure out what a delegate was. I looked at several descriptions of it via Google, and they were all a mess. Needless to say, I am not going to do it that way in D!storage class, but it isn't, it's a type component. It doesn't seempossibledelegatesor a pointer to a delegate or a function returning a delegate.which declares type, and not variable: delegate void Foo(int); // Foo is a new type Foo ptr; // declare a pointer of that type So, you can actually have arrays: Foo[] ptr;Still, I like your syntax more. It is more distinct from normal function declaration.Thanks for pointing out the conceptual simplicity of it just being a function pointer bundled with an object reference. I guess I tend to think about programming concepts differently than others, I see complexity where they see simplicity and vice versa <g>. It really is just an enhanced "pointer to function", so it should declare in a manner similar to pointer to function. I thought of using another special character to replace the * in pointer to function, but that got too wierd looking <g>. I considered *., but that looked too confusing with C++ pointers to members.By the way, I guess functions with non-D calling conventions cannot be delegated?Sure they can be, they just can't be mixed into one delegate type. This works analogously to the type checking on function pointers.
Apr 03 2002
I't a really nice site Pavel. I do have one question about your WinD example. You have: static void OK_Click(Object me, Event e) { me.close(); } Shouldn't me be cast to Frame or something?
Mar 31 2002
"Patrick Down" <pat codemoon.com> wrote in message news:Xns91E2EF11F18F2patcodemooncom 63.105.9.61...I't a really nice site Pavel. I do have one question about your WinD example. You have: static void OK_Click(Object me, Event e) { me.close(); } Shouldn't me be cast to Frame or something?Oh yes, you've caught me! I've just done the change to the event system, and corrected the sample properly, but didn't test it =) Now, I prefer to write it this way: static void OK_Click(Object me, Event e) { with (cast(Frame) me) { close(); }}
Mar 31 2002
Oh, God, Walter, it's too bad you can't make the D language specification require reasonable indentation! ;) Sean "Pavel Minayev" <evilone omen.ru> wrote in message news:a88v29$2q3b$1 digitaldaemon.com...Oh yes, you've caught me! I've just done the change to the event system, and corrected the sample properly, but didn't test it =) Now, I prefer to write it this way: static void OK_Click(Object me, Event e) { with (cast(Frame) me) { close(); }}
Mar 31 2002
"Sean L. Palmer" <spalmer iname.com> wrote in message news:a88val$2q6s$1 digitaldaemon.com...Oh, God, Walter, it's too bad you can't make the D language specification require reasonable indentation! ;)Well, he could just make pointers to methods... =)
Apr 01 2002
I completely agree with Pavel that we Must make pointers to methods I think it'll be more convinient to develop software using it.... I ask You about it. Not only for me, but for whole Dcommunity....Oh, God, Walter, it's too bad you can't make the D language specification require reasonable indentation! ;)Well, he could just make pointers to methods... =)
Apr 01 2002
Svyatoslav Bezgin wrote:I ask You about it. Not only for me, but for whole Dcommunity....Maybe, since we're moving from C to D, we should be known as a dommunity... :) -- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]
Apr 01 2002
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3CA8C79E.703CAD34 deming-os.org...Svyatoslav Bezgin wrote:dommunity... :)I ask You about it. Not only for me, but for whole Dcommunity....Maybe, since we're moving from C to D, we should be known as a-- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]But in Dutch 'dom' means stupid... :( -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail
Apr 02 2002
OddesE wrote:"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3CA8C79E.703CAD34 deming-os.org...Yeah, but it's not like we want to be called the "Kaas Kopmunity"... -BobCSvyatoslav Bezgin wrote:dommunity... :)I ask You about it. Not only for me, but for whole Dcommunity....Maybe, since we're moving from C to D, we should be known as a-- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]But in Dutch 'dom' means stupid... :(
Apr 02 2002
"Robert W. Cunningham" <rwc_2001 yahoo.com> wrote in message news:3CAA7EAF.A410548E yahoo.com...OddesE wrote:LOL! How did you know? Do you have friends in Holland? :) -- Stijn OddesE_XYZ hotmail.com http://OddesE.cjb.net _________________________________________________ Remove _XYZ from my address when replying by mail"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:3CA8C79E.703CAD34 deming-os.org...Yeah, but it's not like we want to be called the "Kaas Kopmunity"... -BobCSvyatoslav Bezgin wrote:dommunity... :)I ask You about it. Not only for me, but for whole Dcommunity....Maybe, since we're moving from C to D, we should be known as a-- The Villagers are Online! villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ]But in Dutch 'dom' means stupid... :(
Apr 03 2002