aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/api/service/svcs/svc_collection.h
blob: 9769d5a329d74e40bc931fec88537d16e32952fb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#ifndef _SVC_COLLECTION_H
#define _SVC_COLLECTION_H

#include <bfc/dispatch.h>
#include <bfc/ptrlist.h>
#include <bfc/pair.h>
#include <api/xml/xmlreader.h>
#include <api/service/services.h>

class CollectionElement;
class svc_collectionI;

class NOVTABLE svc_collection : public Dispatchable 
{
public:
  static FOURCC getServiceType() { return WaSvc::COLLECTION; }
  int testTag(const wchar_t *xmltag);
  void addElement(const wchar_t *id, const wchar_t *includepath, int removalid, skin_xmlreaderparams *params); 
  void removeElement(int recored_value);
  void removeAllElements();
  int getNumElements();
  int getNumElementsUnique();
  CollectionElement *enumElement(int n, int *ancestor);
  CollectionElement *enumElementUnique(int n, int *ancestor);
  CollectionElement *getElement(const wchar_t *id, int *ancestor);
  CollectionElement *getAncestor(CollectionElement *e);

  enum 
	{
    COLLECTION_TESTTAG=10,
    COLLECTION_ADDELEMENT=20,
    COLLECTION_REMOVEELEMENT=30,
    COLLECTION_REMOVEALLELEMENTS=35,
    COLLECTION_GETNUMELEMENTS=40,
    COLLECTION_GETNUMELEMENTSUNIQUE=50,
    COLLECTION_ENUMELEMENT=60,
    COLLECTION_ENUMELEMENTUNIQUE=70,
    COLLECTION_GETELEMENT=80,
  };
};

inline int svc_collection::testTag(const wchar_t *xmltag) {
  return _call(COLLECTION_TESTTAG, 0, xmltag);
}

inline void svc_collection::addElement(const wchar_t *id, const wchar_t *includepath, int incrementalremovalid, skin_xmlreaderparams *params) {
  _voidcall(COLLECTION_ADDELEMENT, id, includepath, incrementalremovalid, params);
}

inline void svc_collection::removeElement(int removalid) {
  _voidcall(COLLECTION_REMOVEELEMENT, removalid);
}

inline void svc_collection::removeAllElements() {
  _voidcall(COLLECTION_REMOVEALLELEMENTS);
}

inline int svc_collection::getNumElements() {
  return _call(COLLECTION_GETNUMELEMENTS, 0);
}

inline int svc_collection::getNumElementsUnique() {
  return _call(COLLECTION_GETNUMELEMENTSUNIQUE, 0);
}

inline CollectionElement *svc_collection::enumElement(int n, int *ancestor) {
  return _call(COLLECTION_ENUMELEMENT, (CollectionElement *)NULL, n, ancestor);
}

inline CollectionElement *svc_collection::enumElementUnique(int n, int *ancestor) {
  return _call(COLLECTION_ENUMELEMENTUNIQUE, (CollectionElement *)NULL, n, ancestor);
}

inline CollectionElement *svc_collection::getElement(const wchar_t *id, int *ancestor) {
  return _call(COLLECTION_GETELEMENT, (CollectionElement *)NULL, id, ancestor);
}

class SortPairString {
public:
  static int compareItem(Pair<StringW, StringW> *p1, Pair<StringW, StringW> *p2) {
    return WCSICMP(p1->a, p2->a);
  }
  static int compareAttrib(const wchar_t *attrib, Pair<StringW, StringW> *item) {
    return WCSICMP(attrib, item->a);
  }
};

class CollectionElement : public Dispatchable {
  public:
    const wchar_t *getId();
    const wchar_t *getParamValue(const wchar_t *param, CollectionElement **item=NULL);
    int getParamValueInt(const wchar_t *param);
    const wchar_t *getIncludePath(const wchar_t *param=NULL); 
    CollectionElement *getAncestor();

    enum {
      COLLECTIONELEMENT_GETID=10,
      COLLECTIONELEMENT_GETPARAMVALUE=20,
      COLLECTIONELEMENT_GETPARAMVALUEINT=30,
      COLLECTIONELEMENT_GETANCESTOR=40,
      COLLECTIONELEMENT_GETINCLUDEPATH=50,
    };
};

inline const wchar_t *CollectionElement::getId() {
  return _call(COLLECTIONELEMENT_GETID, (const wchar_t *)NULL);
}

inline const wchar_t *CollectionElement::getParamValue(const wchar_t *param, CollectionElement **item) {
  return _call(COLLECTIONELEMENT_GETPARAMVALUE, (const wchar_t *)NULL, param, item);
}

inline int CollectionElement::getParamValueInt(const wchar_t *param) {
  return _call(COLLECTIONELEMENT_GETPARAMVALUEINT, 0, param);
}

inline CollectionElement *CollectionElement::getAncestor() {
  return _call(COLLECTIONELEMENT_GETANCESTOR, (CollectionElement *)NULL);
}

inline const wchar_t *CollectionElement::getIncludePath(const wchar_t *param) {
  return _call(COLLECTIONELEMENT_GETINCLUDEPATH, (const wchar_t *)NULL, param);
}

class CollectionElementI : public CollectionElement {
  public:
    CollectionElementI(svc_collectionI *collectionI, const wchar_t *id, skin_xmlreaderparams *params, int seccount, const wchar_t *includepath);
    virtual ~CollectionElementI();

    virtual const wchar_t *getId();
    virtual const wchar_t *getParamValue(const wchar_t *param, CollectionElement **item=NULL);
    virtual int getParamValueInt(const wchar_t *param);
    virtual CollectionElement *getAncestor();
    const wchar_t *getIncludePath(const wchar_t *param=NULL);  // null returns last override's include path

    int getSecCount();

  protected:
    RECVS_DISPATCH;

    PtrListQuickSorted < Pair < StringW, StringW >, SortPairString > params;
    StringW id;
    int seccount;
    svc_collectionI *collection;
    StringW path;
};

class SortCollectionElementsI {
public:
  static int compareItem(CollectionElementI *p1, CollectionElementI *p2) {
    int r = WCSICMP(p1->getId(), p2->getId());
    if (r == 0) {
      if (p1->getSecCount() < p2->getSecCount()) return -1;
      if (p1->getSecCount() > p2->getSecCount()) return 1;
      return 0;
    }
    return r;
  }
  static int compareAttrib(const wchar_t *attrib, CollectionElementI *item) {
    return WCSICMP(attrib, item->getId());
  }
};

// derive from this one
class svc_collectionI : public svc_collection {
public:
  svc_collectionI();
  virtual ~svc_collectionI();
  virtual int testTag(const wchar_t *xmltag)=0;
  virtual void addElement(const wchar_t *id, const wchar_t *includepath, int incrementalremovalid, skin_xmlreaderparams *params);
  virtual void removeElement(int removalid);
  virtual void removeAllElements();
  virtual int getNumElements();
  virtual int getNumElementsUnique();
  virtual CollectionElement *enumElement(int n, int *ancestor);
  virtual CollectionElement *enumElementUnique(int n, int *ancestor);
  virtual CollectionElement *getElement(const wchar_t *id, int *ancestor);
  virtual CollectionElement *getAncestor(CollectionElement *e);

protected:
  RECVS_DISPATCH;

  PtrListQuickMultiSorted < CollectionElementI, SortCollectionElementsI > elements;
  int count;
};

#include <api/service/servicei.h>
template <class T>
class CollectionCreator : public waServiceFactoryTSingle<svc_collection, T> {};

template <wchar_t TAG[]>
class CollectionSvc : public svc_collectionI {
  public:
    int testTag(const wchar_t *xmltag) {
      if (!WCSICMP(xmltag, TAG)) return 1;
      return 0;
    }
  static const char *getServiceName() { return StringPrintf("Collection Service for \"%S\"", TAG); }
};

template <class T>
class CollectionSvc2 : public svc_collectionI {
  public:
    int testTag(const wchar_t *xmltag) {
      if (STRCASEEQL(xmltag, T::collection_getXmlTag())) return 1;
      return 0;
    }
  static const char *getServiceName() { return StringPrintf("Collection Service for \"%S\"", T::collection_getXmlTag()); }
};


#include <api/service/svc_enum.h>
#include <bfc/string/StringW.h>
class CollectionSvcEnum : public SvcEnumT<svc_collection> 
{
public:
  CollectionSvcEnum(const wchar_t *xmltag) : tag(xmltag) {}
protected:
  virtual int testService(svc_collection *svc) {
    return (svc->testTag(tag));
  }
private:
  StringW tag;
};

#endif