]> git.mxchange.org Git - simgear.git/blob - simgear/structure/SGExpression.hxx
Allow adding a contition to locked-track animation
[simgear.git] / simgear / structure / SGExpression.hxx
1 /* -*-c++-*-
2  *
3  * Copyright (C) 2006-2007 Mathias Froehlich 
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21
22 #ifndef _SG_EXPRESSION_HXX
23 #define _SG_EXPRESSION_HXX 1
24
25 #include <string>
26 #include <vector>
27 #include <functional>
28 #include <set>
29    
30 #include <simgear/props/condition.hxx>
31 #include <simgear/props/props.hxx>
32 #include <simgear/math/interpolater.hxx>
33 #include <simgear/math/SGMath.hxx>
34 #include <simgear/scene/model/persparam.hxx>
35 #include <simgear/structure/exception.hxx>
36 #include <simgear/structure/Singleton.hxx>
37
38 /// Expression tree implementation.
39
40 namespace simgear
41 {
42   namespace expression
43   {
44     enum Type {
45       BOOL = 0,
46       INT,
47       FLOAT,
48       DOUBLE
49     };
50     template<typename T> struct TypeTraits;
51     template<> struct TypeTraits<bool> {
52       static const Type typeTag = BOOL;
53     };
54     template<> struct TypeTraits<int> {
55       static const Type typeTag = INT;
56     };
57     template<> struct TypeTraits<float> {
58       static const Type typeTag = FLOAT;
59     };
60     template<> struct TypeTraits<double> {
61       static const Type typeTag = DOUBLE;
62     };
63
64     struct Value
65     {
66       Type typeTag;
67       union {
68         bool boolVal;
69         int intVal;
70         float floatVal;
71         double doubleVal;
72       } val;
73
74       Value() : typeTag(DOUBLE)
75       {
76         val.doubleVal = 0.0;
77       }
78
79       Value(bool val_) : typeTag(BOOL)
80       {
81         val.boolVal = val_;
82       }
83
84       Value(int val_) : typeTag(INT)
85       {
86         val.intVal = val_;
87       }
88
89       Value(float val_) : typeTag(FLOAT)
90       {
91         val.floatVal = val_;
92       }
93
94       Value(double val_) : typeTag(DOUBLE)
95       {
96         val.doubleVal = val_;
97       }
98
99     };
100
101     class Binding;
102   }
103
104   class Expression : public SGReferenced
105   {
106   public:
107     virtual ~Expression() {}
108     virtual expression::Type getType() const = 0;
109   };
110
111   const expression::Value eval(const Expression* exp,
112                                const expression::Binding* binding = 0);
113
114 }
115
116 template<typename T>
117 class SGExpression : public simgear::Expression {
118 public:
119   virtual ~SGExpression() {}
120   typedef T result_type;
121   typedef T operand_type;
122   virtual void eval(T&, const simgear::expression::Binding*) const = 0;
123
124   T getValue(const simgear::expression::Binding* binding = 0) const
125   { T value; eval(value, binding); return value; }
126
127   double getDoubleValue(const simgear::expression::Binding* binding = 0) const
128   { T value; eval(value, binding); return value; }
129
130   virtual bool isConst() const { return false; }
131   virtual SGExpression* simplify();
132   virtual simgear::expression::Type getType() const
133   {
134     return simgear::expression::TypeTraits<T>::typeTag;
135   }
136   virtual simgear::expression::Type getOperandType() const
137   {
138     return simgear::expression::TypeTraits<T>::typeTag;
139   }
140   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
141   { }
142 };
143
144 /// Constant value expression
145 template<typename T>
146 class SGConstExpression : public SGExpression<T> {
147 public:
148   SGConstExpression(const T& value = T()) : _value(value)
149   { }
150   void setValue(const T& value)
151   { _value = value; }
152   const T& getValue(const simgear::expression::Binding* binding = 0) const
153   { return _value; }
154   virtual void eval(T& value, const simgear::expression::Binding*) const
155   { value = _value; }
156   virtual bool isConst() const { return true; }
157 private:
158   T _value;
159 };
160
161 template<typename T>
162 SGExpression<T>*
163 SGExpression<T>::simplify()
164 {
165   if (isConst())
166     return new SGConstExpression<T>(getValue());
167   return this;
168 }
169
170 template<typename T>
171 class SGUnaryExpression : public SGExpression<T> {
172 public:
173   const SGExpression<T>* getOperand() const
174   { return _expression; }
175   SGExpression<T>* getOperand()
176   { return _expression; }
177   void setOperand(SGExpression<T>* expression)
178   {
179     if (!expression)
180       expression = new SGConstExpression<T>(T());
181     _expression = expression;
182   }
183   virtual bool isConst() const
184   { return getOperand()->isConst(); }
185   virtual SGExpression<T>* simplify()
186   {
187     _expression = _expression->simplify();
188     return SGExpression<T>::simplify();
189   }
190   
191   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
192     { _expression->collectDependentProperties(props); }  
193 protected:
194   SGUnaryExpression(SGExpression<T>* expression = 0)
195   { setOperand(expression); }
196
197 private:
198   SGSharedPtr<SGExpression<T> > _expression;
199 };
200
201 template<typename T>
202 class SGBinaryExpression : public SGExpression<T> {
203 public:
204   const SGExpression<T>* getOperand(size_t i) const
205   { return _expressions[i]; }
206   SGExpression<T>* getOperand(size_t i)
207   { return _expressions[i]; }
208   void setOperand(size_t i, SGExpression<T>* expression)
209   {
210     if (!expression)
211       expression = new SGConstExpression<T>(T());
212     if (2 <= i)
213       i = 0;
214     _expressions[i] = expression;
215   }
216
217   virtual bool isConst() const
218   { return getOperand(0)->isConst() && getOperand(1)->isConst(); }
219   virtual SGExpression<T>* simplify()
220   {
221     _expressions[0] = _expressions[0]->simplify();
222     _expressions[1] = _expressions[1]->simplify();
223     return SGExpression<T>::simplify();
224   }
225
226   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
227   {
228     _expressions[0]->collectDependentProperties(props);
229     _expressions[1]->collectDependentProperties(props); 
230   } 
231   
232 protected:
233   SGBinaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
234   { setOperand(0, expr0); setOperand(1, expr1); }
235   
236 private:
237   SGSharedPtr<SGExpression<T> > _expressions[2];
238 };
239
240 template<typename T>
241 class SGNaryExpression : public SGExpression<T> {
242 public:
243   size_t getNumOperands() const
244   { return _expressions.size(); }
245   const SGExpression<T>* getOperand(size_t i) const
246   { return _expressions[i]; }
247   SGExpression<T>* getOperand(size_t i)
248   { return _expressions[i]; }
249   size_t addOperand(SGExpression<T>* expression)
250   {
251     if (!expression)
252       return ~size_t(0);
253     _expressions.push_back(expression);
254     return _expressions.size() - 1;
255   }
256
257   template<typename Iter>
258   void addOperands(Iter begin, Iter end)
259   {
260     for (Iter iter = begin; iter != end; ++iter)
261       {
262         addOperand(static_cast< ::SGExpression<T>*>(*iter));
263       }
264   }
265
266   virtual bool isConst() const
267   {
268     for (size_t i = 0; i < _expressions.size(); ++i)
269       if (!_expressions[i]->isConst())
270         return false;
271     return true;
272   }
273   virtual SGExpression<T>* simplify()
274   {
275     for (size_t i = 0; i < _expressions.size(); ++i)
276       _expressions[i] = _expressions[i]->simplify();
277     return SGExpression<T>::simplify();
278   }
279
280   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
281   {
282     for (size_t i = 0; i < _expressions.size(); ++i)
283       _expressions[i]->collectDependentProperties(props);
284   } 
285 protected:
286   SGNaryExpression()
287   { }
288   SGNaryExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
289   { addOperand(expr0); addOperand(expr1); }
290   
291 private:
292   std::vector<SGSharedPtr<SGExpression<T> > > _expressions;
293 };
294
295
296
297
298 template<typename T>
299 class SGPropertyExpression : public SGExpression<T> {
300 public:
301   SGPropertyExpression(const SGPropertyNode* prop) : _prop(prop)
302   { }
303   void setPropertyNode(const SGPropertyNode* prop)
304   { _prop = prop; }
305   virtual void eval(T& value, const simgear::expression::Binding*) const
306   { doEval(value); }
307   
308   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
309     { props.insert(_prop.get()); }
310 private:
311   void doEval(float& value) const
312   { if (_prop) value = _prop->getFloatValue(); }
313   void doEval(double& value) const
314   { if (_prop) value = _prop->getDoubleValue(); }
315   void doEval(int& value) const
316   { if (_prop) value = _prop->getIntValue(); }
317   void doEval(long& value) const
318   { if (_prop) value = _prop->getLongValue(); }
319   void doEval(bool& value) const
320   { if (_prop) value = _prop->getBoolValue(); }
321   SGSharedPtr<const SGPropertyNode> _prop;
322 };
323
324 template<typename T>
325 class SGAbsExpression : public SGUnaryExpression<T> {
326 public:
327   SGAbsExpression(SGExpression<T>* expr = 0)
328     : SGUnaryExpression<T>(expr)
329   { }
330
331   virtual void eval(T& value, const simgear::expression::Binding* b) const
332   { value = getOperand()->getValue(b); if (value <= 0) value = -value; }
333
334   using SGUnaryExpression<T>::getOperand;
335 };
336
337 template<typename T>
338 class SGACosExpression : public SGUnaryExpression<T> {
339 public:
340   SGACosExpression(SGExpression<T>* expr = 0)
341     : SGUnaryExpression<T>(expr)
342   { }
343
344   virtual void eval(T& value, const simgear::expression::Binding* b) const
345   { value = acos((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
346
347   using SGUnaryExpression<T>::getOperand;
348 };
349
350 template<typename T>
351 class SGASinExpression : public SGUnaryExpression<T> {
352 public:
353   SGASinExpression(SGExpression<T>* expr = 0)
354     : SGUnaryExpression<T>(expr)
355   { }
356
357   virtual void eval(T& value, const simgear::expression::Binding* b) const
358   { value = asin((double)SGMisc<T>::clip(getOperand()->getValue(b), -1, 1)); }
359
360   using SGUnaryExpression<T>::getOperand;
361 };
362
363 template<typename T>
364 class SGATanExpression : public SGUnaryExpression<T> {
365 public:
366   SGATanExpression(SGExpression<T>* expr = 0)
367     : SGUnaryExpression<T>(expr)
368   { }
369
370   virtual void eval(T& value, const simgear::expression::Binding* b) const
371   { value = atan(getOperand()->getDoubleValue(b)); }
372
373   using SGUnaryExpression<T>::getOperand;
374 };
375
376 template<typename T>
377 class SGCeilExpression : public SGUnaryExpression<T> {
378 public:
379   SGCeilExpression(SGExpression<T>* expr = 0)
380     : SGUnaryExpression<T>(expr)
381   { }
382
383   virtual void eval(T& value, const simgear::expression::Binding* b) const
384   { value = ceil(getOperand()->getDoubleValue(b)); }
385
386   using SGUnaryExpression<T>::getOperand;
387 };
388
389 template<typename T>
390 class SGCosExpression : public SGUnaryExpression<T> {
391 public:
392   SGCosExpression(SGExpression<T>* expr = 0)
393     : SGUnaryExpression<T>(expr)
394   { }
395
396   virtual void eval(T& value, const simgear::expression::Binding* b) const
397   { value = cos(getOperand()->getDoubleValue(b)); }
398
399   using SGUnaryExpression<T>::getOperand;
400 };
401
402 template<typename T>
403 class SGCoshExpression : public SGUnaryExpression<T> {
404 public:
405   SGCoshExpression(SGExpression<T>* expr = 0)
406     : SGUnaryExpression<T>(expr)
407   { }
408
409   virtual void eval(T& value, const simgear::expression::Binding* b) const
410   { value = cosh(getOperand()->getDoubleValue(b)); }
411
412   using SGUnaryExpression<T>::getOperand;
413 };
414
415 template<typename T>
416 class SGExpExpression : public SGUnaryExpression<T> {
417 public:
418   SGExpExpression(SGExpression<T>* expr = 0)
419     : SGUnaryExpression<T>(expr)
420   { }
421
422   virtual void eval(T& value, const simgear::expression::Binding* b) const
423   { value = exp(getOperand()->getDoubleValue(b)); }
424
425   using SGUnaryExpression<T>::getOperand;
426 };
427
428 template<typename T>
429 class SGFloorExpression : public SGUnaryExpression<T> {
430 public:
431   SGFloorExpression(SGExpression<T>* expr = 0)
432     : SGUnaryExpression<T>(expr)
433   { }
434
435   virtual void eval(T& value, const simgear::expression::Binding* b) const
436   { value = floor(getOperand()->getDoubleValue(b)); }
437
438   using SGUnaryExpression<T>::getOperand;
439 };
440
441 template<typename T>
442 class SGLogExpression : public SGUnaryExpression<T> {
443 public:
444   SGLogExpression(SGExpression<T>* expr = 0)
445     : SGUnaryExpression<T>(expr)
446   { }
447
448   virtual void eval(T& value, const simgear::expression::Binding* b) const
449   { value = log(getOperand()->getDoubleValue(b)); }
450
451   using SGUnaryExpression<T>::getOperand;
452 };
453
454 template<typename T>
455 class SGLog10Expression : public SGUnaryExpression<T> {
456 public:
457   SGLog10Expression(SGExpression<T>* expr = 0)
458     : SGUnaryExpression<T>(expr)
459   { }
460
461   virtual void eval(T& value, const simgear::expression::Binding* b) const
462   { value = log10(getOperand()->getDoubleValue(b)); }
463
464   using SGUnaryExpression<T>::getOperand;
465 };
466
467 template<typename T>
468 class SGSinExpression : public SGUnaryExpression<T> {
469 public:
470   SGSinExpression(SGExpression<T>* expr = 0)
471     : SGUnaryExpression<T>(expr)
472   { }
473
474   virtual void eval(T& value, const simgear::expression::Binding* b) const
475   { value = sin(getOperand()->getDoubleValue(b)); }
476
477   using SGUnaryExpression<T>::getOperand;
478 };
479
480 template<typename T>
481 class SGSinhExpression : public SGUnaryExpression<T> {
482 public:
483   SGSinhExpression(SGExpression<T>* expr = 0)
484     : SGUnaryExpression<T>(expr)
485   { }
486
487   virtual void eval(T& value, const simgear::expression::Binding* b) const
488   { value = sinh(getOperand()->getDoubleValue(b)); }
489
490   using SGUnaryExpression<T>::getOperand;
491 };
492
493 template<typename T>
494 class SGSqrExpression : public SGUnaryExpression<T> {
495 public:
496   SGSqrExpression(SGExpression<T>* expr = 0)
497     : SGUnaryExpression<T>(expr)
498   { }
499
500   virtual void eval(T& value, const simgear::expression::Binding* b) const
501   { value = getOperand()->getValue(b); value = value*value; }
502
503   using SGUnaryExpression<T>::getOperand;
504 };
505
506 template<typename T>
507 class SGSqrtExpression : public SGUnaryExpression<T> {
508 public:
509   SGSqrtExpression(SGExpression<T>* expr = 0)
510     : SGUnaryExpression<T>(expr)
511   { }
512
513   virtual void eval(T& value, const simgear::expression::Binding* b) const
514   { value = sqrt(getOperand()->getDoubleValue(b)); }
515
516   using SGUnaryExpression<T>::getOperand;
517 };
518
519 template<typename T>
520 class SGTanExpression : public SGUnaryExpression<T> {
521 public:
522   SGTanExpression(SGExpression<T>* expr = 0)
523     : SGUnaryExpression<T>(expr)
524   { }
525
526   virtual void eval(T& value, const simgear::expression::Binding* b) const
527   { value = tan(getOperand()->getDoubleValue(b)); }
528
529   using SGUnaryExpression<T>::getOperand;
530 };
531
532 template<typename T>
533 class SGTanhExpression : public SGUnaryExpression<T> {
534 public:
535   SGTanhExpression(SGExpression<T>* expr = 0)
536     : SGUnaryExpression<T>(expr)
537   { }
538
539   virtual void eval(T& value, const simgear::expression::Binding* b) const
540   { value = tanh(getOperand()->getDoubleValue(b)); }
541
542   using SGUnaryExpression<T>::getOperand;
543 };
544
545 template<typename T>
546 class SGScaleExpression : public SGUnaryExpression<T> {
547 public:
548   SGScaleExpression(SGExpression<T>* expr = 0, const T& scale = T(1))
549     : SGUnaryExpression<T>(expr), _scale(scale)
550   { }
551   void setScale(const T& scale)
552   { _scale = scale; }
553   const T& getScale() const
554   { return _scale; }
555
556   virtual void eval(T& value, const simgear::expression::Binding* b) const
557   { value = _scale * getOperand()->getValue(b); }
558
559   virtual SGExpression<T>* simplify()
560   {
561     if (_scale == 1)
562       return getOperand()->simplify();
563     return SGUnaryExpression<T>::simplify();
564   }
565
566   using SGUnaryExpression<T>::getOperand;
567 private:
568   T _scale;
569 };
570
571 template<typename T>
572 class SGBiasExpression : public SGUnaryExpression<T> {
573 public:
574   SGBiasExpression(SGExpression<T>* expr = 0, const T& bias = T(0))
575     : SGUnaryExpression<T>(expr), _bias(bias)
576   { }
577
578   void setBias(const T& bias)
579   { _bias = bias; }
580   const T& getBias() const
581   { return _bias; }
582
583   virtual void eval(T& value, const simgear::expression::Binding* b) const
584   { value = _bias + getOperand()->getValue(b); }
585
586   virtual SGExpression<T>* simplify()
587   {
588     if (_bias == 0)
589       return getOperand()->simplify();
590     return SGUnaryExpression<T>::simplify();
591   }
592
593   using SGUnaryExpression<T>::getOperand;
594 private:
595   T _bias;
596 };
597
598 template<typename T>
599 class SGInterpTableExpression : public SGUnaryExpression<T> {
600 public:
601   SGInterpTableExpression(SGExpression<T>* expr,
602                           const SGInterpTable* interpTable) :
603     SGUnaryExpression<T>(expr),
604     _interpTable(interpTable)
605   { }
606
607   virtual void eval(T& value, const simgear::expression::Binding* b) const
608   {
609     if (_interpTable)
610       value = _interpTable->interpolate(getOperand()->getValue(b));
611   }
612
613   using SGUnaryExpression<T>::getOperand;
614 private:
615   SGSharedPtr<SGInterpTable const> _interpTable;
616 };
617
618 template<typename T>
619 class SGClipExpression : public SGUnaryExpression<T> {
620 public:
621   SGClipExpression(SGExpression<T>* expr)
622     : SGUnaryExpression<T>(expr),
623       _clipMin(SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min())),
624       _clipMax(SGLimits<T>::max())
625   { }
626   SGClipExpression(SGExpression<T>* expr,
627                    const T& clipMin, const T& clipMax)
628     : SGUnaryExpression<T>(expr),
629       _clipMin(clipMin),
630       _clipMax(clipMax)
631   { }
632
633   void setClipMin(const T& clipMin)
634   { _clipMin = clipMin; }
635   const T& getClipMin() const
636   { return _clipMin; }
637
638   void setClipMax(const T& clipMax)
639   { _clipMax = clipMax; }
640   const T& getClipMax() const
641   { return _clipMax; }
642
643   virtual void eval(T& value, const simgear::expression::Binding* b) const
644   {
645     value = SGMisc<T>::clip(getOperand()->getValue(b), _clipMin, _clipMax);
646   }
647
648   virtual SGExpression<T>* simplify()
649   {
650     if (_clipMin <= SGMisc<T>::min(-SGLimits<T>::max(), SGLimits<T>::min()) &&
651         _clipMax >= SGLimits<T>::max())
652       return getOperand()->simplify();
653     return SGUnaryExpression<T>::simplify();
654   }
655
656   using SGUnaryExpression<T>::getOperand;
657 private:
658   T _clipMin;
659   T _clipMax;
660 };
661
662 template<typename T>
663 class SGStepExpression : public SGUnaryExpression<T> {
664 public:
665   SGStepExpression(SGExpression<T>* expr = 0,
666                    const T& step = T(1), const T& scroll = T(0))
667     : SGUnaryExpression<T>(expr), _step(step), _scroll(scroll)
668   { }
669
670   void setStep(const T& step)
671   { _step = step; }
672   const T& getStep() const
673   { return _step; }
674
675   void setScroll(const T& scroll)
676   { _scroll = scroll; }
677   const T& getScroll() const
678   { return _scroll; }
679
680   virtual void eval(T& value, const simgear::expression::Binding* b) const
681   { value = apply_mods(getOperand()->getValue(b)); }
682
683   using SGUnaryExpression<T>::getOperand;
684
685 private:
686   T apply_mods(T property) const
687   {
688     if( _step <= SGLimits<T>::min() ) return property;
689
690     // apply stepping of input value
691     T modprop = floor(property/_step)*_step;
692
693     // calculate scroll amount (for odometer like movement)
694     T remainder = property <= SGLimits<T>::min() ? -fmod(property,_step) : (_step - fmod(property,_step));
695     if( remainder > SGLimits<T>::min() && remainder < _scroll )
696       modprop += (_scroll - remainder) / _scroll * _step;
697
698     return modprop;
699   }
700
701   T _step;
702   T _scroll;
703 };
704
705 template<typename T>
706 class SGEnableExpression : public SGUnaryExpression<T> {
707 public:
708   SGEnableExpression(SGExpression<T>* expr = 0,
709                      SGCondition* enable = 0,
710                      const T& disabledValue = T(0))
711     : SGUnaryExpression<T>(expr),
712       _enable(enable),
713       _disabledValue(disabledValue)
714   { }
715
716   const T& getDisabledValue() const
717   { return _disabledValue; }
718   void setDisabledValue(const T& disabledValue)
719   { _disabledValue = disabledValue; }
720
721   virtual void eval(T& value, const simgear::expression::Binding* b) const
722   {
723     if (_enable->test())
724       value = getOperand()->getValue(b);
725     else
726       value = _disabledValue;
727   }
728
729   virtual SGExpression<T>* simplify()
730   {
731     if (!_enable)
732       return getOperand()->simplify();
733     return SGUnaryExpression<T>::simplify();
734   }
735   
736   virtual void collectDependentProperties(std::set<const SGPropertyNode*>& props) const
737   {
738     SGUnaryExpression<T>::collectDependentProperties(props);
739     _enable->collectDependentProperties(props);
740   }
741
742   using SGUnaryExpression<T>::getOperand;
743 private:
744   SGSharedPtr<SGCondition> _enable;
745   T _disabledValue;
746 };
747
748 template<typename T>
749 class SGAtan2Expression : public SGBinaryExpression<T> {
750 public:
751   SGAtan2Expression(SGExpression<T>* expr0, SGExpression<T>* expr1)
752     : SGBinaryExpression<T>(expr0, expr1)
753   { }
754   virtual void eval(T& value, const simgear::expression::Binding* b) const
755   { value = atan2(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
756   using SGBinaryExpression<T>::getOperand;
757 };
758
759 template<typename T>
760 class SGDivExpression : public SGBinaryExpression<T> {
761 public:
762   SGDivExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
763     : SGBinaryExpression<T>(expr0, expr1)
764   { }
765   virtual void eval(T& value, const simgear::expression::Binding* b) const
766   { value = getOperand(0)->getValue(b) / getOperand(1)->getValue(b); }
767   using SGBinaryExpression<T>::getOperand;
768 };
769
770 template<typename T>
771 class SGModExpression : public SGBinaryExpression<T> {
772 public:
773   SGModExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
774     : SGBinaryExpression<T>(expr0, expr1)
775   { }
776   virtual void eval(T& value, const simgear::expression::Binding* b) const
777   { value = mod(getOperand(0)->getValue(b), getOperand(1)->getValue(b)); }
778   using SGBinaryExpression<T>::getOperand;
779 private:
780   int mod(const int& v0, const int& v1) const
781   { return v0 % v1; }
782   float mod(const float& v0, const float& v1) const
783   { return fmod(v0, v1); }
784   double mod(const double& v0, const double& v1) const
785   { return fmod(v0, v1); }
786 };
787
788 template<typename T>
789 class SGPowExpression : public SGBinaryExpression<T> {
790 public:
791   SGPowExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
792     : SGBinaryExpression<T>(expr0, expr1)
793   { }
794   virtual void eval(T& value, const simgear::expression::Binding* b) const
795   { value = pow(getOperand(0)->getDoubleValue(b), getOperand(1)->getDoubleValue(b)); }
796   using SGBinaryExpression<T>::getOperand;
797 };
798
799 template<typename T>
800 class SGSumExpression : public SGNaryExpression<T> {
801 public:
802   SGSumExpression()
803   { }
804   SGSumExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
805     : SGNaryExpression<T>(expr0, expr1)
806   { }
807   virtual void eval(T& value, const simgear::expression::Binding* b) const
808   {
809     value = T(0);
810     size_t sz = SGNaryExpression<T>::getNumOperands();
811     for (size_t i = 0; i < sz; ++i)
812       value += getOperand(i)->getValue(b);
813   }
814   using SGNaryExpression<T>::getValue;
815   using SGNaryExpression<T>::getOperand;
816 };
817
818 template<typename T>
819 class SGDifferenceExpression : public SGNaryExpression<T> {
820 public:
821   SGDifferenceExpression()
822   { }
823   SGDifferenceExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
824     : SGNaryExpression<T>(expr0, expr1)
825   { }
826   virtual void eval(T& value, const simgear::expression::Binding* b) const
827   {
828     value = getOperand(0)->getValue(b);
829     size_t sz = SGNaryExpression<T>::getNumOperands();
830     for (size_t i = 1; i < sz; ++i)
831       value -= getOperand(i)->getValue(b);
832   }
833   using SGNaryExpression<T>::getValue;
834   using SGNaryExpression<T>::getOperand;
835 };
836
837 template<typename T>
838 class SGProductExpression : public SGNaryExpression<T> {
839 public:
840   SGProductExpression()
841   { }
842   SGProductExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
843     : SGNaryExpression<T>(expr0, expr1)
844   { }
845   virtual void eval(T& value, const simgear::expression::Binding* b) const
846   {
847     value = T(1);
848     size_t sz = SGNaryExpression<T>::getNumOperands();
849     for (size_t i = 0; i < sz; ++i)
850       value *= getOperand(i)->getValue(b);
851   }
852   using SGNaryExpression<T>::getValue;
853   using SGNaryExpression<T>::getOperand;
854 };
855
856 template<typename T>
857 class SGMinExpression : public SGNaryExpression<T> {
858 public:
859   SGMinExpression()
860   { }
861   SGMinExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
862     : SGNaryExpression<T>(expr0, expr1)
863   { }
864   virtual void eval(T& value, const simgear::expression::Binding* b) const
865   {
866     size_t sz = SGNaryExpression<T>::getNumOperands();
867     if (sz < 1)
868       return;
869     
870     value = getOperand(0)->getValue(b);
871     for (size_t i = 1; i < sz; ++i)
872       value = SGMisc<T>::min(value, getOperand(i)->getValue(b));
873   }
874   using SGNaryExpression<T>::getOperand;
875 };
876
877 template<typename T>
878 class SGMaxExpression : public SGNaryExpression<T> {
879 public:
880   SGMaxExpression()
881   { }
882   SGMaxExpression(SGExpression<T>* expr0, SGExpression<T>* expr1)
883     : SGNaryExpression<T>(expr0, expr1)
884   { }
885   virtual void eval(T& value, const simgear::expression::Binding* b) const
886   {
887     size_t sz = SGNaryExpression<T>::getNumOperands();
888     if (sz < 1)
889       return;
890     
891     value = getOperand(0)->getValue(b);
892     for (size_t i = 1; i < sz; ++i)
893       value = SGMisc<T>::max(value, getOperand(i)->getValue(b));
894   }
895   using SGNaryExpression<T>::getOperand;
896 };
897
898 typedef SGExpression<int> SGExpressioni;
899 typedef SGExpression<float> SGExpressionf;
900 typedef SGExpression<double> SGExpressiond;
901 typedef SGExpression<bool> SGExpressionb;
902
903 typedef SGSharedPtr<SGExpressioni> SGExpressioni_ref;
904 typedef SGSharedPtr<SGExpressionf> SGExpressionf_ref;
905 typedef SGSharedPtr<SGExpressiond> SGExpressiond_ref;
906 typedef SGSharedPtr<SGExpressionb> SGExpressionb_ref;
907
908 /**
909  * Global function to make an expression out of properties.
910
911   <clip>
912     <clipMin>0</clipMin>
913     <clipMax>79</clipMax>
914     <abs>
915       <sum>
916         <rad2deg>
917           <property>sim/model/whatever-rad</property>
918         </rad2deg>
919         <property>sim/model/someother-deg</property>
920         <value>-90</value>
921       </sum>
922     </abs>
923   <clip>
924
925 will evaluate to an expression:
926
927 SGMisc<T>::clip(abs(deg2rad*sim/model/whatever-rad + sim/model/someother-deg - 90), clipMin, clipMax);
928
929  */
930 SGExpression<int>*
931 SGReadIntExpression(SGPropertyNode *inputRoot,
932                     const SGPropertyNode *configNode);
933
934 SGExpression<float>*
935 SGReadFloatExpression(SGPropertyNode *inputRoot,
936                       const SGPropertyNode *configNode);
937
938 SGExpression<double>*
939 SGReadDoubleExpression(SGPropertyNode *inputRoot,
940                        const SGPropertyNode *configNode);
941
942 SGExpression<bool>*
943 SGReadBoolExpression(SGPropertyNode *inputRoot,
944                      const SGPropertyNode *configNode);
945
946 namespace simgear
947 {
948   namespace expression
949   {
950   struct ParseError : public sg_exception
951   {
952       ParseError(const string& message = std::string())
953           : sg_exception(message) {}
954   };
955     
956   // Support for binding variables around an expression.
957   class Binding
958   {
959   public:
960       virtual ~Binding() {}
961       const virtual Value* getBindings() const = 0;
962       virtual Value* getBindings() = 0;
963   };
964
965   class VariableLengthBinding : public Binding
966   {
967   public:
968       const Value* getBindings() const
969       {
970           if (_bindings.empty())
971               return 0;
972           else
973               return &_bindings[0];
974       }
975       Value* getBindings()
976       {
977           if (_bindings.empty())
978               return 0;
979           else
980               return &_bindings[0];
981       }
982       std::vector<Value> _bindings;
983   };
984
985   template<int Size> class FixedLengthBinding : public Binding
986   {
987   public:
988       Value* getBindings()
989       {
990           return &_bindings[0];
991       }
992       const Value* getBindings() const
993       {
994           return &_bindings[0];
995       }
996       Value _bindings[Size];
997   };
998
999   struct VariableBinding
1000   {
1001       VariableBinding() : type(expression::DOUBLE), location(-1) {}
1002
1003       VariableBinding(const std::string& name_, expression::Type type_,
1004                       int location_)
1005           : name(name_), type(type_), location(location_)
1006       {
1007       }
1008       std::string name;
1009       expression::Type type;
1010       int location;
1011   };
1012
1013   class BindingLayout
1014   {
1015   public:
1016       size_t addBinding(const std::string& name, expression::Type type);
1017       bool findBinding(const string& name, VariableBinding& result) const;
1018       std::vector<VariableBinding> bindings;
1019   };
1020
1021   class Parser {
1022   public:
1023       typedef Expression* (*exp_parser)(const SGPropertyNode* exp,
1024                                         Parser* parser);
1025       void addParser(const std::string& name, exp_parser parser)
1026       {
1027           getParserMap().insert(std::make_pair(name, parser));
1028       }
1029       Expression* read(const SGPropertyNode* exp)
1030       {
1031           ParserMap& map = getParserMap();
1032           ParserMap::iterator itr = map.find(exp->getName());
1033           if (itr == map.end())
1034               throw ParseError(string("unknown expression ") + exp->getName());
1035           exp_parser parser = itr->second;
1036           return (*parser)(exp, this);
1037       }
1038       // XXX vector of SGSharedPtr?
1039       bool readChildren(const SGPropertyNode* exp,
1040                         std::vector<Expression*>& result);
1041       /**
1042        * Function that parses a property tree, producing an expression.
1043        */
1044       typedef std::map<const std::string, exp_parser> ParserMap;
1045       virtual ParserMap& getParserMap() = 0;
1046       /**
1047        * After an expression is parsed, the binding layout may contain
1048        * references that need to be bound during evaluation.
1049        */
1050       BindingLayout& getBindingLayout() { return _bindingLayout; }
1051   protected:
1052       BindingLayout _bindingLayout;
1053   };
1054
1055   class ExpressionParser : public Parser
1056   {
1057   public:
1058       ParserMap& getParserMap()
1059       {
1060           return ParserMapSingleton::instance()->_parserTable;
1061       }
1062       static void addExpParser(const std::string&, exp_parser);
1063   protected:
1064       struct ParserMapSingleton : public simgear::Singleton<ParserMapSingleton>
1065       {
1066           ParserMap _parserTable;
1067       };
1068   };
1069
1070   /**
1071    * Constructor for registering parser functions.
1072    */
1073   struct ExpParserRegistrar
1074   {
1075       ExpParserRegistrar(const std::string& token, Parser::exp_parser parser)
1076       {
1077           ExpressionParser::addExpParser(token, parser);
1078       }
1079   };
1080
1081   }
1082
1083   /**
1084    * Access a variable definition. Use a location from a BindingLayout.
1085    */
1086   template<typename T>
1087   class VariableExpression : public ::SGExpression<T> {
1088   public:
1089     VariableExpression(int location) : _location(location) {}
1090     virtual ~VariableExpression() {}
1091     virtual void eval(T& value, const simgear::expression::Binding* b) const
1092     {
1093       const expression::Value* values = b->getBindings();
1094       value = *reinterpret_cast<const T *>(&values[_location].val);
1095     }
1096   protected:
1097     int _location;
1098
1099   };
1100
1101   /**
1102    * An n-ary expression where the types of the argument aren't the
1103    * same as the return type.
1104    */
1105   template<typename T, typename OpType>
1106   class GeneralNaryExpression : public ::SGExpression<T> {
1107   public:
1108     typedef OpType operand_type;
1109     size_t getNumOperands() const
1110     { return _expressions.size(); }
1111     const ::SGExpression<OpType>* getOperand(size_t i) const
1112     { return _expressions[i]; }
1113     ::SGExpression<OpType>* getOperand(size_t i)
1114     { return _expressions[i]; }
1115     size_t addOperand(::SGExpression<OpType>* expression)
1116     {
1117       if (!expression)
1118         return ~size_t(0);
1119       _expressions.push_back(expression);
1120       return _expressions.size() - 1;
1121     }
1122     
1123     template<typename Iter>
1124     void addOperands(Iter begin, Iter end)
1125     {
1126       for (Iter iter = begin; iter != end; ++iter)
1127         {
1128           addOperand(static_cast< ::SGExpression<OpType>*>(*iter));
1129         }
1130     }
1131     
1132     virtual bool isConst() const
1133     {
1134       for (size_t i = 0; i < _expressions.size(); ++i)
1135         if (!_expressions[i]->isConst())
1136           return false;
1137       return true;
1138     }
1139     virtual ::SGExpression<T>* simplify()
1140     {
1141       for (size_t i = 0; i < _expressions.size(); ++i)
1142         _expressions[i] = _expressions[i]->simplify();
1143       return SGExpression<T>::simplify();
1144     }
1145
1146     simgear::expression::Type getOperandType() const
1147     {
1148       return simgear::expression::TypeTraits<OpType>::typeTag;
1149     }
1150     
1151   protected:
1152     GeneralNaryExpression()
1153     { }
1154     GeneralNaryExpression(::SGExpression<OpType>* expr0,
1155                           ::SGExpression<OpType>* expr1)
1156     { addOperand(expr0); addOperand(expr1); }
1157
1158     std::vector<SGSharedPtr<SGExpression<OpType> > > _expressions;
1159   };
1160
1161   /**
1162    * A predicate that wraps, for example the STL template predicate
1163    * expressions like std::equal_to.
1164    */
1165   template<typename OpType, template<typename PredOp> class Pred>
1166   class PredicateExpression : public GeneralNaryExpression<bool, OpType> {
1167   public:
1168     PredicateExpression()
1169     {
1170     }
1171     PredicateExpression(::SGExpression<OpType>* expr0,
1172                         ::SGExpression<OpType>* expr1)
1173       : GeneralNaryExpression<bool, OpType>(expr0, expr1)
1174     {
1175     }
1176     virtual void eval(bool& value, const simgear::expression::Binding* b) const
1177     {
1178       size_t sz = this->getNumOperands();
1179       if (sz != 2)
1180         return;
1181       value = _pred(this->getOperand(0)->getValue(b),
1182                     this->getOperand(1)->getValue(b));
1183     }
1184   protected:
1185     Pred<OpType> _pred;
1186   };
1187
1188   template<template<typename OT> class Pred, typename OpType>
1189   PredicateExpression<OpType, Pred>*
1190   makePredicate(SGExpression<OpType>* op1, SGExpression<OpType>* op2)
1191   {
1192     return new PredicateExpression<OpType, Pred>(op1, op2);
1193   }
1194   
1195   template<typename OpType>
1196   class EqualToExpression : public PredicateExpression<OpType, std::equal_to>
1197   {
1198   public:
1199     EqualToExpression() {}
1200     EqualToExpression(::SGExpression<OpType>* expr0,
1201                       ::SGExpression<OpType>* expr1)
1202       : PredicateExpression<OpType, std::equal_to>(expr0, expr1)
1203     {
1204     }
1205   };
1206
1207   template<typename OpType>
1208   class LessExpression : public PredicateExpression<OpType, std::less>
1209   {
1210   public:
1211     LessExpression() {}
1212     LessExpression(::SGExpression<OpType>* expr0, ::SGExpression<OpType>* expr1)
1213       : PredicateExpression<OpType, std::less>(expr0, expr1)
1214     {
1215     }
1216   };
1217
1218   template<typename OpType>
1219   class LessEqualExpression
1220     : public PredicateExpression<OpType, std::less_equal>
1221   {
1222   public:
1223     LessEqualExpression() {}
1224     LessEqualExpression(::SGExpression<OpType>* expr0,
1225                         ::SGExpression<OpType>* expr1)
1226       : PredicateExpression<OpType, std::less_equal>(expr0, expr1)
1227     {
1228     }
1229   };
1230
1231   class NotExpression : public ::SGUnaryExpression<bool>
1232   {
1233   public:
1234     NotExpression(::SGExpression<bool>* expr = 0)
1235       : ::SGUnaryExpression<bool>(expr)
1236     {
1237     }
1238     void eval(bool& value, const expression::Binding* b) const
1239     {
1240       value = !getOperand()->getValue(b);
1241     }
1242   };
1243
1244   class OrExpression : public ::SGNaryExpression<bool>
1245   {
1246   public:
1247     void eval(bool& value, const expression::Binding* b) const
1248     {
1249       value = false;
1250       for (int i = 0; i < (int)getNumOperands(); ++i) {
1251         value = value || getOperand(i)->getValue(b);
1252         if (value)
1253           return;
1254       }
1255     }
1256   };
1257
1258   class AndExpression : public ::SGNaryExpression<bool>
1259   {
1260   public:
1261     void eval(bool& value, const expression::Binding* b) const
1262     {
1263       value = true;
1264       for (int i = 0; i < (int)getNumOperands(); ++i) {
1265         value = value && getOperand(i)->getValue(b);
1266         if (!value)
1267           return;
1268       }
1269     }
1270   };
1271
1272   /**
1273    * Convert an operand from OpType to T.
1274    */
1275   template<typename T, typename OpType>
1276   class ConvertExpression : public GeneralNaryExpression<T, OpType>
1277   {
1278   public:
1279     ConvertExpression() {}
1280     ConvertExpression(::SGExpression<OpType>* expr0)
1281     {
1282       this->addOperand(expr0);
1283     }
1284     virtual void eval(T& value, const simgear::expression::Binding* b) const
1285     {
1286       typename ConvertExpression::operand_type result;
1287       this->_expressions.at(0)->eval(result, b);
1288       value = result;
1289     }
1290   };
1291 }
1292 #endif // _SG_EXPRESSION_HXX