* move imageManager code into new imageManager.h/imageManager.cpp
[openc2e.git] / caosVar.h
blob9ec70410d1bab8f2febdfa2806a008f972538471
1 /*
2 * caosVar.h
3 * openc2e
5 * Created by Bryan Donlan on Thu Mar 10 2005.
6 * Copyright (c) 2004 Alyssa Milburn and Bryan Donlan. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
20 #ifndef CAOSVAR_H
21 #define CAOSVAR_H 1
23 #include <boost/variant.hpp>
24 #include "openc2e.h"
25 #include <string>
26 #include <cassert>
27 #include "AgentRef.h"
28 #include <typeinfo>
29 #include "physics.h"
31 class Agent;
33 class wrongCaosVarTypeException : public caosException {
34 public:
35 wrongCaosVarTypeException() throw() : caosException("Wrong caos variable type") {}
36 wrongCaosVarTypeException(const char *s) throw() : caosException(s) { }
37 wrongCaosVarTypeException(const std::string &s) throw() : caosException(s) { }
40 struct nulltype_tag { };
42 enum variableType {
43 CAOSNULL = 0, CAOSAGENT, CAOSINT, CAOSFLOAT, CAOSSTR, CAOSVEC
46 class caosVar {
47 private:
48 FRIEND_SERIALIZE(caosVar)
49 protected:
50 struct typeVisit : public boost::static_visitor<variableType> {
51 variableType operator()(int) const { return CAOSINT; }
52 variableType operator()(float) const { return CAOSFLOAT; }
53 variableType operator()(const std::string &) const { return CAOSSTR; }
54 variableType operator()(const AgentRef &) const { return CAOSAGENT; }
55 variableType operator()(nulltype_tag) const { return CAOSNULL; }
56 variableType operator()(const Vector<float> &) const { return CAOSVEC; }
59 #define BAD_TYPE(et, gt) \
60 const et &operator()(const gt &) const { \
61 throw wrongCaosVarTypeException( \
62 "Wrong caosVar type: Expected " #et ", got " #gt \
63 ); \
66 struct intVisit : public boost::static_visitor<int> {
67 int operator()(int i) const { return i; }
68 int operator()(float f) const {
69 // horror necessary for rounding without C99
70 int x = (int)f; float diff = f - x;
71 if (f >= 0.0f) {
72 if (diff >= 0.5f) return ++x; else return x;
73 } else {
74 if (diff <= -0.5f) return --x; else return x;
77 int operator()(const Vector<float> &v) const {
78 return (int)v.getMagnitude();
80 BAD_TYPE(int, std::string);
81 BAD_TYPE(int, AgentRef);
82 BAD_TYPE(int, nulltype_tag);
85 struct floatVisit : public boost::static_visitor<float> {
86 float operator()(int i) const { return (float)i; }
87 float operator()(float f) const { return f; }
88 float operator()(const Vector<float> &v) const { return v.getMagnitude(); }
89 BAD_TYPE(float, std::string);
90 BAD_TYPE(float, AgentRef);
91 BAD_TYPE(float, nulltype_tag);
94 struct stringVisit : public boost::static_visitor<const std::string &> {
95 const std::string &operator()(const std::string &s) const {
96 return s;
98 BAD_TYPE(std::string, AgentRef);
99 BAD_TYPE(std::string, nulltype_tag);
100 BAD_TYPE(std::string, int);
101 BAD_TYPE(std::string, float);
102 BAD_TYPE(std::string, Vector<float>);
105 struct agentVisit : public boost::static_visitor<const AgentRef &> {
106 const AgentRef &operator()(const AgentRef &a) const {
107 return a;
109 BAD_TYPE(AgentRef, std::string);
110 BAD_TYPE(AgentRef, nulltype_tag);
111 const AgentRef &operator()(int i) const;
112 BAD_TYPE(AgentRef, float);
113 BAD_TYPE(AgentRef, Vector<float>);
116 struct vectorVisit : public boost::static_visitor<const Vector<float> &> {
117 const Vector<float> &operator()(const Vector<float> &v) const {
118 return v;
120 BAD_TYPE(Vector<float>, std::string);
121 BAD_TYPE(Vector<float>, nulltype_tag);
122 BAD_TYPE(Vector<float>, int);
123 BAD_TYPE(Vector<float>, float);
124 BAD_TYPE(Vector<float>, AgentRef);
128 #undef BAD_TYPE
129 boost::variant<int, float, AgentRef, std::string, nulltype_tag, Vector<float> > value;
131 public:
132 variableType getType() const {
133 return boost::apply_visitor(typeVisit(), value);
136 void reset() {
137 value = nulltype_tag();
140 bool isNull() {
141 return getType() == CAOSNULL;
144 caosVar() {
147 ~caosVar() {
150 caosVar &operator=(const caosVar &copyFrom) {
151 value = copyFrom.value;
152 return *this;
155 caosVar(const caosVar &copyFrom) : value(copyFrom.value) { }
157 caosVar(int v) { setInt(v); }
158 caosVar(float v) { setFloat(v); }
159 caosVar(Agent *v) { setAgent(v); }
160 caosVar(const AgentRef &v) { setAgent(v); }
161 caosVar(const std::string &v) { setString(v); }
162 caosVar(const Vector<float> &v) { setVector(v); }
164 bool isEmpty() const { return getType() == CAOSNULL; }
165 bool hasInt() const { return getType() == CAOSINT; }
166 bool hasFloat() const { return getType() == CAOSFLOAT; }
167 bool hasAgent() const { return getType() == CAOSAGENT; }
168 bool hasString() const { return getType() == CAOSSTR; }
169 bool hasDecimal() const { return getType() == CAOSINT || getType() == CAOSFLOAT || getType() == CAOSVEC; }
170 bool hasNumber() const { return hasDecimal(); }
171 bool hasVector() const { return getType() == CAOSVEC; }
173 void setInt(int i) { value = i; }
174 void setFloat(float i) { value = i; }
175 void setAgent(Agent *i) {
176 value = AgentRef(i);
178 void setAgent(const AgentRef &r) {
179 value = r;
181 void setString(const std::string &i) {
182 value = i;
184 void setVector(const Vector<float> &v) {
185 value = v;
188 int getInt() const {
189 return boost::apply_visitor(intVisit(), value);
192 float getFloat() const {
193 return boost::apply_visitor(floatVisit(), value);
196 void getString(std::string &s) const {
197 s = getString();
200 const std::string &getString() const {
201 return boost::apply_visitor(stringVisit(), value);
204 boost::shared_ptr<Agent> getAgent() const {
205 return getAgentRef().lock();
208 const AgentRef &getAgentRef() const {
209 return boost::apply_visitor(agentVisit(), value);
212 const Vector<float> &getVector() const {
213 return boost::apply_visitor(vectorVisit(), value);
216 bool operator == (const caosVar &v) const;
217 bool operator != (const caosVar &v) const { return !(*this == v); }
218 bool operator > (const caosVar &v) const;
219 bool operator < (const caosVar &v) const;
221 std::string dump() const;
224 struct caosVarCompare {
225 bool operator()(const caosVar &v1, const caosVar &v2) const {
226 if (v1.getType() == v2.getType())
227 return v1 < v2;
228 else
229 return v1.getType() < v2.getType();
233 #endif
234 /* vim: set noet: */