1 #ifndef __MASTERDISPATCH_H
2 #define __MASTERDISPATCH_H
5 #include "wvhashtable.h"
7 typedef AnyType (GenFunc
)(AnyType
&self
, AnyType parms
[]);
20 IfcInfo(WvStringParm _iname
, const UUID
&_iid
,
21 CallEntry
*_calls
, int _ncalls
);
32 static inline int WvHash(const UUID
&uuid
)
34 // it's random! any four bytes are as good as any others.
35 return WvHash(*(int *)&uuid
);
38 DeclareWvDict(IfcInfo
, UUID
, iid
);
49 { /* nothing special */ }
51 void add(IfcInfo
*info
)
52 { ifcs
.add(info
, false); }
53 void remove(IfcInfo
*info
)
54 { ifcs
.remove(info
); }
56 CallEntry
*find(AnyType
&self
, WvStringParm fname
, int argc
,
59 // FIXME: this is stupid. We have a hash table of interfaces that
60 // we iterate through, but we should have a hash table of function
61 // names with a list of CallEntry for each name. That would be
62 // much faster, but this is easier, so it'll do for now.
63 IfcInfoDict::Iter
ifc(ifcs
);
64 for (ifc
.rewind(); ifc
.next(); )
66 //printf("dispatch: checking interface '%s'\n", ifc->iname.cstr());
67 bool ret
= self
.switchto(ifc
->iid
);
68 //printf(" switch: %p -> %d\n", (IObject *)self.obj, ret);
69 if (!ret
) continue; // incompatible object
71 for (int i
= 0; i
< ifc
->ncalls
; i
++)
73 CallEntry
&ent
= ifc
->calls
[i
];
74 //printf(" dispatch: checking func '%s'\n", ent.name);
76 if (fname
!= ent
.name
) continue;
77 if (ent
.argc
!= argc
) continue;
78 assert(!argc
|| ent
.argtypes
);
81 for (int arg
= 0; arg
< argc
; arg
++)
83 if (!parms
[arg
].switchto(ent
.argtypes
[arg
]))
91 // if we get here, we found a match!
92 // printf("found entry '%s' (%p)\n", ent.name, &ent);
101 AnyType
call(AnyType
&self
, WvStringParm fname
, int argc
, AnyType parms
[])
103 CallEntry
*ent
= find(self
, fname
, argc
, parms
);
105 return ent
->func(self
, parms
);
110 extern MasterDispatch
*master
;
113 #endif // __MASTERDISPATCH_H