xoreos  0.0.5
variable.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 #include <boost/make_shared.hpp>
26 
27 #include "src/common/error.h"
28 #include "src/common/ustring.h"
29 
33 
34 namespace Aurora {
35 
36 namespace NWScript {
37 
39  setType(type);
40 }
41 
44 
45  *this = value;
46 }
47 
48 Variable::Variable(float value) : _type(kTypeVoid) {
50 
51  *this = value;
52 }
53 
56 
57  *this = value;
58 }
59 
62 
63  *this = value;
64 }
65 
68 
69  *this = value;
70 }
71 
72 Variable::Variable(const EngineType *value) : _type(kTypeVoid) {
74 
75  *this = value;
76 }
77 
78 Variable::Variable(const EngineType &value) : _type(kTypeVoid) {
80 
81  *this = value;
82 }
83 
84 Variable::Variable(float x, float y, float z) : _type(kTypeVoid) {
86 
87  setVector(x, y, z);
88 }
89 
90 Variable::Variable(const Variable &var) : _type(kTypeVoid) {
91  *this = var;
92 }
93 
96 }
97 
98 void Variable::setType(Type type) {
99  _array.reset();
100 
101  if (_type == kTypeString)
102  delete _value._string;
103  else if (_type == kTypeObject)
104  delete _value._object;
105  else if (_type == kTypeEngineType)
106  delete _value._engineType;
107  else if (_type == kTypeScriptState)
108  delete _value._scriptState;
109 
110  _type = type;
111 
112  switch (_type) {
113  case kTypeVoid:
114  case kTypeAny:
115  break;
116 
117  case kTypeArray:
118  _array = boost::make_shared<Array>();
119  break;
120 
121  case kTypeInt:
122  _value._int = 0;
123  break;
124 
125  case kTypeFloat:
126  _value._float = 0.0f;
127  break;
128 
129  case kTypeString:
130  _value._string = new Common::UString;
131  break;
132 
133  case kTypeObject:
134  _value._object = new ObjectReference;
135  break;
136 
137  case kTypeVector:
138  _value._vector[0] = 0.0f;
139  _value._vector[1] = 0.0f;
140  _value._vector[2] = 0.0f;
141  break;
142 
143  case kTypeEngineType:
144  _value._engineType = 0;
145  break;
146 
147  case kTypeScriptState:
148  _value._scriptState = new ScriptState;
149  break;
150 
151  case kTypeReference:
152  _value._reference = 0;
153  break;
154 
155  default:
156  throw Common::Exception("Variable::setType(): Invalid type %d", type);
157  break;
158  }
159 }
160 
162  if (&var == this)
163  return *this;
164 
165  setType(var._type);
166 
167  if (_type == kTypeString)
168  *_value._string = *var._value._string;
169  else if (_type == kTypeObject)
170  *_value._object = *var._value._object;
171  else if (_type == kTypeEngineType)
172  *this = var._value._engineType;
173  else if (_type == kTypeScriptState)
174  *_value._scriptState = *var._value._scriptState;
175  else if (_type == kTypeArray)
176  _array = var._array;
177  else
178  _value = var._value;
179 
180  return *this;
181 }
182 
184  if (_type != kTypeInt)
185  throw Common::Exception("Can't assign an int value to a non-int variable");
186 
187  _value._int = value;
188 
189  return *this;
190 }
191 
193  if (_type != kTypeFloat)
194  throw Common::Exception("Can't assign a float value to a non-float variable");
195 
196  _value._float = value;
197 
198  return *this;
199 }
200 
202  if (_type != kTypeString)
203  throw Common::Exception("Can't assign a string value to a non-string variable");
204 
205  *_value._string = value;
206 
207  return *this;
208 }
209 
211  if (_type != kTypeObject)
212  throw Common::Exception("Can't assign an object value to a non-object variable");
213 
214  *_value._object = value;
215 
216  return *this;
217 }
218 
220  if (_type != kTypeObject)
221  throw Common::Exception("Can't assign an object value to a non-object variable");
222 
223  *_value._object = value;
224 
225  return *this;
226 }
227 
229  if (_type != kTypeEngineType)
230  throw Common::Exception("Can't assign an engine-type value to a non-engine-type variable");
231 
232  EngineType *engineType = value ? value->clone() : 0;
233 
234  delete _value._engineType;
235 
236  _value._engineType = engineType;
237 
238  return *this;
239 }
240 
242  *this = &value;
243 
244  return *this;
245 }
246 
247 bool Variable::operator==(const Variable &var) const {
248  if (this == &var)
249  return true;
250 
251  if (_type != var._type)
252  return false;
253 
254  switch (_type) {
255  case kTypeVoid:
256  return true;
257 
258  case kTypeInt:
259  return _value._int == var._value._int;
260 
261  case kTypeFloat:
262  return _value._float == var._value._float;
263 
264  case kTypeString:
265  return *_value._string == *var._value._string;
266 
267  case kTypeObject:
268  return *_value._object == *var._value._object;
269 
270  case kTypeVector:
271  return _value._vector[0] == var._value._vector[0] &&
272  _value._vector[1] == var._value._vector[1] &&
273  _value._vector[2] == var._value._vector[2];
274 
275  case kTypeArray:
276  return _array.get() && var._array.get() && *_array == *var._array;
277 
278  default:
279  break;
280  }
281 
282  return false;
283 }
284 
285 bool Variable::operator!=(const Variable &var) const {
286  return !(*this == var);
287 }
288 
290  return _type;
291 }
292 
294  if (_type != kTypeInt)
295  throw Common::Exception("Can't get an int value from a non-int variable");
296 
297  return _value._int;
298 }
299 
300 float Variable::getFloat() const {
301  if (_type != kTypeFloat)
302  throw Common::Exception("Can't get a float value from a non-float variable");
303 
304  return _value._float;
305 }
306 
308  if (_type != kTypeString)
309  throw Common::Exception("Can't get a string value from a non-string variable");
310 
311  return *_value._string;
312 }
313 
315  if (_type != kTypeString)
316  throw Common::Exception("Can't get a string value from a non-string variable");
317 
318  return *_value._string;
319 }
320 
322  if (_type != kTypeObject)
323  throw Common::Exception("Can't get an object value from a non-object variable");
324 
325  return **_value._object;
326 }
327 
329  if (_type != kTypeEngineType)
330  throw Common::Exception("Can't get an engine-type value from a non-engine-type variable");
331 
332  return _value._engineType;
333 }
334 
335 void Variable::setVector(float x, float y, float z) {
336  if (_type != kTypeVector)
337  throw Common::Exception("Can't assign a vector value to a non-vector variable");
338 
339  _value._vector[0] = x;
340  _value._vector[1] = y;
341  _value._vector[2] = z;
342 }
343 
344 void Variable::getVector(float &x, float &y, float &z) const {
345  if (_type != kTypeVector)
346  throw Common::Exception("Can't get a vector value from a non-vector variable");
347 
348  x = _value._vector[0];
349  y = _value._vector[1];
350  z = _value._vector[2];
351 }
352 
354  if (_type != kTypeArray)
355  throw Common::Exception("Can't get an array value from a non-array variable");
356 
357  assert(_array.get());
358 
359  return *_array;
360 }
361 
363  if (_type != kTypeArray)
364  throw Common::Exception("Can't get an array value from a non-array variable");
365 
366  assert(_array.get());
367 
368  return *_array;
369 }
370 
371 size_t Variable::getArraySize() const {
372  if (_type != kTypeArray)
373  throw Common::Exception("Can't get an array size from a non-array variable");
374 
375  assert(_array.get());
376 
377  return _array->size();
378 }
379 
380 void Variable::growArray(Type type, size_t size) {
381  if (_type != kTypeArray)
382  throw Common::Exception("Can't grow a non-array variable");
383 
384  assert(_array.get());
385 
386  if (!_array->empty() && (*_array)[0].get() && (*_array)[0]->getType() != type)
387  throw Common::Exception("Array type mismatch (%d vs %d)", (*_array)[0]->getType(), type);
388 
389  _array->reserve(size);
390  while (_array->size() < size)
391  _array->push_back(boost::make_shared<Variable>(Variable(type)));
392 }
393 
395  if (_type != kTypeScriptState)
396  throw Common::Exception("Can't get a script state value from a non-script-state variable");
397 
398  return *_value._scriptState;
399 }
400 
402  if (_type != kTypeScriptState)
403  throw Common::Exception("Can't get a script state value from a non-script-state variable");
404 
405  return *_value._scriptState;
406 }
407 
409  if (_type != kTypeReference)
410  throw Common::Exception("Can't get a reference value from a non-reference variable");
411 
412  return _value._reference;
413 }
414 
416  if (_type != kTypeReference)
417  throw Common::Exception("Can't assign a reference value to a non-reference variable");
418 
419  _value._reference = reference;
420 }
421 
422 } // End of namespace NWScript
423 
424 } // End of namespace Aurora
void setReference(Variable *reference)
Definition: variable.cpp:415
std::vector< boost::shared_ptr< Variable > > Array
Definition: variable.h:58
virtual EngineType * clone() const =0
Clone factory method.
NWScript variable.
A class holding an UTF-8 string.
Definition: ustring.h:48
boost::shared_ptr< Array > _array
Definition: variable.h:126
void growArray(Type type, size_t size)
Definition: variable.cpp:380
Exception that provides a stack of explanations.
Definition: error.h:36
ScriptState * _scriptState
Definition: variable.h:121
void getVector(float &x, float &y, float &z) const
Definition: variable.cpp:344
An NWScript engine type.
Basic exceptions to throw.
union Aurora::NWScript::Variable::@6 _value
EngineType * getEngineType() const
Definition: variable.cpp:328
Object * getObject() const
Definition: variable.cpp:321
size_t getArraySize() const
Definition: variable.cpp:371
void setVector(float x, float y, float z)
Definition: variable.cpp:335
Variable(Type type=kTypeVoid)
Definition: variable.cpp:38
A reference/pointer to another variable.
Definition: types.h:47
bool operator==(const Variable &var) const
Definition: variable.cpp:247
StackException Exception
Definition: error.h:59
ScriptState & getScriptState()
Definition: variable.cpp:394
ObjectReference * _object
Definition: variable.h:119
Variable & operator=(const Variable &var)
Definition: variable.cpp:161
Unicode string handling.
bool operator!=(const Variable &var) const
Definition: variable.cpp:285
void setType(Type type)
Definition: variable.cpp:98
Reference to an NWScript object.
"effect", "event", "location", "talent"...
Definition: types.h:43
const Array & getArray() const
Definition: variable.cpp:353
Common::UString & getString()
Definition: variable.cpp:314
Any other type.
Definition: types.h:48
Common::UString * _string
Definition: variable.h:118
EngineType * _engineType
Definition: variable.h:122
Variable * getReference() const
Definition: variable.cpp:408
int32_t int32
Definition: types.h:203