HEAD: an extra unit test for wvbase64 that I forgot to check in a while ago.
[wvapps.git] / xplcidl / masterdispatch.h
blob8c9091ee06b9d5996c833e8ef241d2fdff4edb41
1 #ifndef __MASTERDISPATCH_H
2 #define __MASTERDISPATCH_H
4 #include "anytype.h"
5 #include "wvhashtable.h"
7 typedef AnyType (GenFunc)(AnyType &self, AnyType parms[]);
9 struct CallEntry {
10 const char *name;
11 GenFunc *func;
12 int argc;
13 const UUID *argtypes;
17 class IfcInfo
19 public:
20 IfcInfo(WvStringParm _iname, const UUID &_iid,
21 CallEntry *_calls, int _ncalls);
22 ~IfcInfo();
24 WvString iname;
25 const UUID &iid;
27 CallEntry *calls;
28 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);
40 class MasterDispatch
42 public:
43 IfcInfoDict ifcs;
45 MasterDispatch()
46 : ifcs(10)
47 { }
48 ~MasterDispatch()
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,
57 AnyType parms[])
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);
80 bool ok = true;
81 for (int arg = 0; arg < argc; arg++)
83 if (!parms[arg].switchto(ent.argtypes[arg]))
85 ok = false;
86 break;
89 if (!ok) continue;
91 // if we get here, we found a match!
92 // printf("found entry '%s' (%p)\n", ent.name, &ent);
93 return &ent;
97 // whoops, no match!
98 return NULL;
101 AnyType call(AnyType &self, WvStringParm fname, int argc, AnyType parms[])
103 CallEntry *ent = find(self, fname, argc, parms);
104 assert(ent);
105 return ent->func(self, parms);
110 extern MasterDispatch *master;
113 #endif // __MASTERDISPATCH_H