OpenClonk
C4FindObject.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 #ifndef C4FINDOBJECT_H
17 #define C4FINDOBJECT_H
18 
19 #include "lib/C4Rect.h"
20 #include "script/C4Value.h"
21 
22 // Condition map
24 {
25  C4FO_Not = 1,
26  C4FO_And = 2,
27  C4FO_Or = 3,
34  C4FO_ID = 10,
35  C4FO_OCF = 11,
42  C4FO_Owner = 18,
44  C4FO_Func = 20,
45  C4FO_Layer = 21,
49  C4FO_Cone = 25,
50  // last C4FO must be smaller than C4SO_First.
51 };
52 
53 // Sort map - using same values as C4FindObjectCondID!
55 {
56  C4SO_First = 30, // no sort condition smaller than this
57  C4SO_Reverse = 31, // reverse sort order
58  C4SO_Multiple = 32, // multiple sorts; high priority first; lower priorities if higher prio returned equal
59  C4SO_Distance = 33, // nearest first
60  C4SO_Random = 34, // random first
61  C4SO_Speed = 35, // slowest first
62  C4SO_Mass = 36, // lightest first
63  C4SO_Value = 37, // cheapest first
64  C4SO_Func = 38, // least return values first
65  C4SO_Last = 50 // no sort condition larger than this
66 };
67 
68 // Base class
70 {
71  friend class C4FindObjectNot;
72  friend class C4FindObjectAnd;
73  friend class C4FindObjectOr;
74 
75  class C4SortObject *pSort{nullptr};
76 public:
77  C4FindObject() = default;
78  virtual ~C4FindObject();
79 
80  static C4FindObject *CreateByValue(const C4Value &Data, C4SortObject **ppSortObj=nullptr, const C4Object *context=nullptr, bool *has_layer_check=nullptr); // createFindObject or SortObject - if ppSortObj==nullptr, SortObject is not allowed
81 
82  int32_t Count(const C4ObjectList &Objs); // Counts objects for which the condition is true
83  C4Object *Find(const C4ObjectList &Objs); // Returns first object for which the condition is true
84  C4ValueArray *FindMany(const C4ObjectList &Objs); // Returns all objects for which the condition is true
85 
86  int32_t Count(const C4ObjectList &Objs, const C4LSectors &Sct); // Counts objects for which the condition is true
87  C4Object *Find(const C4ObjectList &Objs, const C4LSectors &Sct); // Returns first object for which the condition is true
88  C4ValueArray *FindMany(const C4ObjectList &Objs, const C4LSectors &Sct); // Returns all objects for which the condition is true
89 
90  void SetSort(C4SortObject *pToSort);
91 
92 protected:
93  // Overridables
94  virtual bool Check(C4Object *pObj) = 0;
95  virtual C4Rect *GetBounds() { return nullptr; }
96  virtual bool UseShapes() { return false; }
97  virtual bool IsImpossible() { return false; }
98  virtual bool IsEnsured() { return false; }
99 
100 private:
101  void CheckObjectStatus(C4ValueArray *pArray);
102 };
103 
104 // Combinators
106 {
107 public:
109  : pCond(pCond) { }
110  ~C4FindObjectNot() override;
111 private:
112  C4FindObject *pCond;
113 protected:
114  bool Check(C4Object *pObj) override;
115  bool IsImpossible() override { return pCond->IsEnsured(); }
116  bool IsEnsured() override { return pCond->IsImpossible(); }
117 };
118 
120 {
121 public:
122  C4FindObjectAnd(int32_t iCnt, C4FindObject **ppConds, bool fFreeArray = true);
123  ~C4FindObjectAnd() override;
124 private:
125  int32_t iCnt;
126  C4FindObject **ppConds; bool fFreeArray; bool fUseShapes;
127  C4Rect Bounds; bool fHasBounds;
128 protected:
129  bool Check(C4Object *pObj) override;
130  C4Rect *GetBounds() override { return fHasBounds ? &Bounds : nullptr; }
131  bool UseShapes() override { return fUseShapes; }
132  bool IsEnsured() override { return !iCnt; }
133  bool IsImpossible() override;
134  void ForgetConditions() { ppConds=nullptr; iCnt=0; }
135 };
136 
137 // Special variant of C4FindObjectAnd that does not free its conditions
139 {
140 public:
142  : C4FindObjectAnd(iCnt, ppConds, true) {}
143  ~C4FindObjectAndStatic() override {ForgetConditions(); }
144 };
145 
147 {
148 public:
149  C4FindObjectOr(int32_t iCnt, C4FindObject **ppConds);
150  ~C4FindObjectOr() override;
151 private:
152  int32_t iCnt;
153  C4FindObject **ppConds; bool fUseShapes;
154  C4Rect Bounds; bool fHasBounds;
155 protected:
156  bool Check(C4Object *pObj) override;
157  C4Rect *GetBounds() override { return fHasBounds ? &Bounds : nullptr; }
158  bool UseShapes() override { return fUseShapes; }
159  bool IsEnsured() override;
160  bool IsImpossible() override { return !iCnt; }
161 };
162 
163 // Primitive conditions
165 {
166 public:
168  : pExclude(pExclude) { }
169 private:
170  C4Object *pExclude;
171 protected:
172  bool Check(C4Object *pObj) override;
173 };
174 
176 {
177 public:
179  : def(def) { }
180 private:
181  C4PropList * def;
182 protected:
183  bool Check(C4Object *pObj) override;
184  bool IsImpossible() override;
185 };
186 
188 {
189 public:
191  : rect(rect) { }
192 private:
193  C4Rect rect;
194 protected:
195  bool Check(C4Object *pObj) override;
196  C4Rect *GetBounds() override { return ▭ }
197  bool IsImpossible() override;
198 };
199 
201 {
202 public:
203  C4FindObjectAtPoint(int32_t x, int32_t y)
204  : bounds(x, y, 1, 1) { }
205 private:
206  C4Rect bounds;
207 protected:
208  bool Check(C4Object *pObj) override;
209  C4Rect *GetBounds() override { return &bounds; }
210  bool UseShapes() override { return true; }
211 };
212 
214 {
215 public:
216  C4FindObjectAtRect(int32_t x, int32_t y, int32_t wdt, int32_t hgt)
217  : bounds(x, y, wdt, hgt) { }
218 private:
219  C4Rect bounds;
220 protected:
221  bool Check(C4Object *pObj) override;
222  C4Rect *GetBounds() override { return &bounds; }
223  bool UseShapes() override { return true; }
224 };
225 
227 {
228 public:
229  C4FindObjectOnLine(int32_t x, int32_t y, int32_t x2, int32_t y2)
230  : x(x), y(y), x2(x2), y2(y2), bounds(x, y, 1, 1) { bounds.Add(C4Rect(x2, y2, 1,1)); }
231 private:
232  int32_t x, y, x2, y2;
233  C4Rect bounds;
234 protected:
235  bool Check(C4Object *pObj) override;
236  C4Rect *GetBounds() override { return &bounds; }
237  bool UseShapes() override { return true; }
238 };
239 
241 {
242 public:
243  C4FindObjectDistance(int32_t x, int32_t y, int32_t r)
244  : x(x), y(y), r2(r*r), bounds(x-r, y-r, 2*r+1, 2*r+1) { }
245 private:
246  int32_t x, y, r2;
247  C4Rect bounds;
248 protected:
249  bool Check(C4Object *pObj) override;
250  C4Rect *GetBounds() override { return &bounds; }
251 };
252 
254 {
255 public:
256  C4FindObjectCone(int32_t x, int32_t y, int32_t r, int32_t angle, int32_t width, int32_t prec = 1)
257  : x(x), y(y), r2(r * r), cone_angle(angle % (360 * prec)), cone_width(width), prec_angle(prec), bounds(x - r, y - r, 2 * r + 1, 2 * r + 1) { }
258 private:
259  int32_t x, y, r2, cone_angle, cone_width, prec_angle;
260  C4Rect bounds;
261 protected:
262  bool Check(C4Object *pObj) override;
263  C4Rect *GetBounds() override { return &bounds; }
264 };
265 
267 {
268 public:
269  C4FindObjectOCF(int32_t ocf)
270  : ocf(ocf) { }
271 private:
272  int32_t ocf;
273 protected:
274  bool Check(C4Object *pObj) override;
275  bool IsImpossible() override;
276 };
277 
279 {
280 public:
281  C4FindObjectCategory(int32_t iCategory)
282  : iCategory(iCategory) { }
283 private:
284  int32_t iCategory;
285 protected:
286  bool Check(C4Object *pObj) override;
287  bool IsEnsured() override;
288 };
289 
291 {
292 public:
293  C4FindObjectAction(const char *szAction)
294  : szAction(szAction) { }
295 private:
296  const char *szAction;
297 protected:
298  bool Check(C4Object *pObj) override;
299 };
300 
302 {
303 public:
304  C4FindObjectActionTarget(C4Object *pActionTarget, int index)
305  : pActionTarget(pActionTarget), index(index) { }
306 private:
307  C4Object *pActionTarget;
308  int index;
309 protected:
310  bool Check(C4Object *pObj) override;
311 };
312 
314 {
315 public:
317  : procedure(procedure) { /* no need to incref, the pointer is never dereferenced */ }
318 private:
319  C4String * procedure;
320 protected:
321  bool Check(C4Object *pObj) override;
322  bool IsImpossible() override;
323 };
324 
326 {
327 public:
329  : pContainer(pContainer) { }
330 private:
331  C4Object *pContainer;
332 protected:
333  bool Check(C4Object *pObj) override;
334 };
335 
337 {
338 public:
339  C4FindObjectAnyContainer() = default;
340 protected:
341  bool Check(C4Object *pObj) override;
342 };
343 
345 {
346 public:
347  C4FindObjectOwner(int32_t iOwner)
348  : iOwner(iOwner) { }
349 private:
350  int32_t iOwner;
351 protected:
352  bool Check(C4Object *pObj) override;
353  bool IsImpossible() override;
354 };
355 
357 {
358 public:
359  C4FindObjectController(int32_t controller)
360  : controller(controller) { }
361 private:
362  int32_t controller;
363 protected:
364  bool Check(C4Object *pObj) override;
365  bool IsImpossible() override;
366 };
367 
369 {
370 public:
371  C4FindObjectFunc(C4String * Name): Name(Name) { }
372  void SetPar(int i, const C4Value &val);
373 private:
374  C4String * Name;
375  C4AulParSet Pars;
376 protected:
377  bool Check(C4Object *pObj) override;
378  bool IsImpossible() override;
379 };
380 
382 {
383 public:
384  C4FindObjectProperty(C4String * Name) : Name(Name) { }
385  C4FindObjectProperty(C4String * Name, const C4Value &Value)
386  : Name(Name), have_value(true), Value(Value) { }
387 private:
388  C4String * Name;
389  bool have_value = false;
390  C4Value Value;
391 protected:
392  bool Check(C4Object *pObj) override;
393  bool IsImpossible() override;
394 };
395 
397 {
398 public:
399  C4FindObjectLayer(C4Object *pLayer) : pLayer(pLayer) {}
400 private:
401  C4Object *pLayer;
402 protected:
403  bool Check(C4Object *pObj) override;
404  bool IsImpossible() override;
405 };
406 
408 {
409 public:
410  C4FindObjectInArray(C4ValueArray *pArray) : pArray(pArray) {}
411 private:
412  C4ValueArray *pArray;
413 protected:
414  bool Check(C4Object *pObj) override;
415  bool IsImpossible() override;
416 };
417 
418 // result sorting
420 {
421 public:
422  C4SortObject() = default;
423  virtual ~C4SortObject() = default;
424 
425 public:
426  // Overridables
427  virtual int32_t Compare(C4Object *pObj1, C4Object *pObj2) = 0; // return value <0 if obj1 is to be sorted before obj2
428 
429  virtual bool PrepareCache(const C4ValueArray *pObjs) { return false; }
430  virtual int32_t CompareCache(int32_t iObj1, int32_t iObj2, C4Object *pObj1, C4Object *pObj2) { return Compare(pObj1, pObj2); }
431 
432 public:
433  static C4SortObject *CreateByValue(const C4Value &Data, const C4Object *context=nullptr);
434  static C4SortObject *CreateByValue(int32_t iType, const C4ValueArray &Data, const C4Object *context=nullptr);
435 
436  void SortObjects(C4ValueArray *pArray);
437 };
438 
440 {
441 public:
443  ~C4SortObjectByValue() override;
444 
445 private:
446  int32_t *pVals{nullptr};
447  int32_t iSize{0};
448 
449 public:
450  // Overridables
451  int32_t Compare(C4Object *pObj1, C4Object *pObj2) override;
452  virtual int32_t CompareGetValue(C4Object *pOf) = 0;
453 
454  bool PrepareCache(const C4ValueArray *pObjs) override;
455  int32_t CompareCache(int32_t iObj1, int32_t iObj2, C4Object *pObj1, C4Object *pObj2) override;
456 
457 };
458 
459 class C4SortObjectReverse : public C4SortObject // reverse sort
460 {
461 public:
463  : C4SortObject(), pSort(pSort) {}
464  ~C4SortObjectReverse() override;
465 private:
466  C4SortObject *pSort;
467 
468 protected:
469  int32_t Compare(C4Object *pObj1, C4Object *pObj2) override;
470 
471  bool PrepareCache(const C4ValueArray *pObjs) override;
472  int32_t CompareCache(int32_t iObj1, int32_t iObj2, C4Object *pObj1, C4Object *pObj2) override;
473 };
474 
475 class C4SortObjectMultiple : public C4SortObject // apply next sort if previous compares to equality
476 {
477 public:
478  C4SortObjectMultiple(int32_t iCnt, C4SortObject **ppSorts, bool fFreeArray = true)
479  : C4SortObject(), fFreeArray(fFreeArray), iCnt(iCnt), ppSorts(ppSorts) {}
480  ~C4SortObjectMultiple() override;
481 private:
482  bool fFreeArray;
483  int32_t iCnt;
484  C4SortObject **ppSorts;
485 
486 protected:
487  int32_t Compare(C4Object *pObj1, C4Object *pObj2) override;
488 
489  bool PrepareCache(const C4ValueArray *pObjs) override;
490  int32_t CompareCache(int32_t iObj1, int32_t iObj2, C4Object *pObj1, C4Object *pObj2) override;
491 };
492 
493 class C4SortObjectDistance : public C4SortObjectByValue // sort by distance from point x/y
494 {
495 public:
496  C4SortObjectDistance(int iX, int iY)
497  : C4SortObjectByValue(), iX(iX), iY(iY) {}
498 private:
499  int iX, iY;
500 
501 protected:
502  int32_t CompareGetValue(C4Object *pFor) override;
503 };
504 
505 class C4SortObjectRandom : public C4SortObjectByValue // randomize order
506 {
507 public:
509 
510 protected:
511  int32_t CompareGetValue(C4Object *pFor) override;
512 };
513 
514 class C4SortObjectSpeed : public C4SortObjectByValue // sort by object xdir/ydir
515 {
516 public:
518 
519 protected:
520  int32_t CompareGetValue(C4Object *pFor) override;
521 };
522 
523 class C4SortObjectMass : public C4SortObjectByValue // sort by mass
524 {
525 public:
527 
528 protected:
529  int32_t CompareGetValue(C4Object *pFor) override;
530 };
531 
532 class C4SortObjectValue : public C4SortObjectByValue // sort by value
533 {
534 public:
536 
537 protected:
538  int32_t CompareGetValue(C4Object *pFor) override;
539 };
540 
541 class C4SortObjectFunc : public C4SortObjectByValue // sort by script function
542 {
543 public:
544  C4SortObjectFunc(C4String * Name): Name(Name) { }
545  void SetPar(int i, const C4Value &val);
546 private:
547  C4String * Name;
548  C4AulParSet Pars;
549 protected:
550  int32_t CompareGetValue(C4Object *pFor) override;
551 };
552 
553 #endif
~C4FindObjectAndStatic() override
Definition: C4FindObject.h:143
virtual bool UseShapes()
Definition: C4FindObject.h:96
C4Rect * GetBounds() override
Definition: C4FindObject.h:222
static C4FindObject * CreateByValue(const C4Value &Data, C4SortObject **ppSortObj=nullptr, const C4Object *context=nullptr, bool *has_layer_check=nullptr)
C4FindObjectCategory(int32_t iCategory)
Definition: C4FindObject.h:281
C4FindObjectActionTarget(C4Object *pActionTarget, int index)
Definition: C4FindObject.h:304
bool UseShapes() override
Definition: C4FindObject.h:210
virtual bool IsEnsured()
Definition: C4FindObject.h:98
C4Rect * GetBounds() override
Definition: C4FindObject.h:236
bool UseShapes() override
Definition: C4FindObject.h:131
bool UseShapes() override
Definition: C4FindObject.h:223
C4FindObjectFunc(C4String *Name)
Definition: C4FindObject.h:371
C4Rect * GetBounds() override
Definition: C4FindObject.h:263
C4FindObjectDef(C4PropList *def)
Definition: C4FindObject.h:178
C4FindObjectInRect(const C4Rect &rect)
Definition: C4FindObject.h:190
bool UseShapes() override
Definition: C4FindObject.h:237
Definition: C4Rect.h:27
C4FindObjectOnLine(int32_t x, int32_t y, int32_t x2, int32_t y2)
Definition: C4FindObject.h:229
C4FindObjectProperty(C4String *Name, const C4Value &Value)
Definition: C4FindObject.h:385
virtual C4Rect * GetBounds()
Definition: C4FindObject.h:95
C4Rect * GetBounds() override
Definition: C4FindObject.h:196
C4FindObject()=default
C4Rect * GetBounds() override
Definition: C4FindObject.h:209
virtual ~C4FindObject()
void SetSort(C4SortObject *pToSort)
C4FindObjectCondID
Definition: C4FindObject.h:23
void ForgetConditions()
Definition: C4FindObject.h:134
C4ValueArray * FindMany(const C4ObjectList &Objs)
friend class C4FindObjectAnd
Definition: C4FindObject.h:72
C4FindObjectProcedure(C4String *procedure)
Definition: C4FindObject.h:316
C4FindObjectAtPoint(int32_t x, int32_t y)
Definition: C4FindObject.h:203
C4FindObjectNot(C4FindObject *pCond)
Definition: C4FindObject.h:108
C4Rect * GetBounds() override
Definition: C4FindObject.h:157
int iCnt
Definition: TstC4NetIO.cpp:32
C4FindObjectController(int32_t controller)
Definition: C4FindObject.h:359
C4FindObjectInArray(C4ValueArray *pArray)
Definition: C4FindObject.h:410
C4FindObjectOwner(int32_t iOwner)
Definition: C4FindObject.h:347
bool IsEnsured() override
Definition: C4FindObject.h:132
bool IsImpossible() override
Definition: C4FindObject.h:115
virtual bool IsImpossible()
Definition: C4FindObject.h:97
C4FindObjectAtRect(int32_t x, int32_t y, int32_t wdt, int32_t hgt)
Definition: C4FindObject.h:216
C4FindObjectProperty(C4String *Name)
Definition: C4FindObject.h:384
C4FindObjectLayer(C4Object *pLayer)
Definition: C4FindObject.h:399
C4SortObjectFunc(C4String *Name)
Definition: C4FindObject.h:544
C4FindObjectOCF(int32_t ocf)
Definition: C4FindObject.h:269
C4SortObjectMultiple(int32_t iCnt, C4SortObject **ppSorts, bool fFreeArray=true)
Definition: C4FindObject.h:478
C4FindObjectAction(const char *szAction)
Definition: C4FindObject.h:293
int32_t Count(const C4ObjectList &Objs)
C4FindObjectCone(int32_t x, int32_t y, int32_t r, int32_t angle, int32_t width, int32_t prec=1)
Definition: C4FindObject.h:256
C4FindObjectAndStatic(int32_t iCnt, C4FindObject **ppConds)
Definition: C4FindObject.h:141
C4FindObjectExclude(C4Object *pExclude)
Definition: C4FindObject.h:167
bool UseShapes() override
Definition: C4FindObject.h:158
bool IsEnsured() override
Definition: C4FindObject.h:116
C4FindObjectDistance(int32_t x, int32_t y, int32_t r)
Definition: C4FindObject.h:243
C4SortObjectCondID
Definition: C4FindObject.h:54
virtual bool PrepareCache(const C4ValueArray *pObjs)
Definition: C4FindObject.h:429
C4SortObjectReverse(C4SortObject *pSort)
Definition: C4FindObject.h:462
C4SortObjectDistance(int iX, int iY)
Definition: C4FindObject.h:496
friend class C4FindObjectOr
Definition: C4FindObject.h:73
virtual bool Check(C4Object *pObj)=0
C4FindObjectContainer(C4Object *pContainer)
Definition: C4FindObject.h:328
C4Object * Find(const C4ObjectList &Objs)
virtual int32_t CompareCache(int32_t iObj1, int32_t iObj2, C4Object *pObj1, C4Object *pObj2)
Definition: C4FindObject.h:430
C4Rect * GetBounds() override
Definition: C4FindObject.h:250
C4Rect * GetBounds() override
Definition: C4FindObject.h:130
int iSize
Definition: TstC4NetIO.cpp:32
bool IsImpossible() override
Definition: C4FindObject.h:160