1 #ifndef OPENSIM_PROPERTY_OBJ_ARRAY_H_
2 #define OPENSIM_PROPERTY_OBJ_ARRAY_H_
3 /* -------------------------------------------------------------------------- *
4  *                        OpenSim:  PropertyObjArray.h                        *
5  * -------------------------------------------------------------------------- *
6  * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
7  * See http://opensim.stanford.edu and the NOTICE file for more information.  *
8  * OpenSim is developed at Stanford University and supported by the US        *
9  * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
10  * through the Warrior Web program.                                           *
11  *                                                                            *
12  * Copyright (c) 2005-2017 Stanford University and the Authors                *
13  * Author(s): Frank C. Anderson                                               *
14  *                                                                            *
15  * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
16  * not use this file except in compliance with the License. You may obtain a  *
17  * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
18  *                                                                            *
19  * Unless required by applicable law or agreed to in writing, software        *
20  * distributed under the License is distributed on an "AS IS" BASIS,          *
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
22  * See the License for the specific language governing permissions and        *
23  * limitations under the License.                                             *
24  * -------------------------------------------------------------------------- */
25 
26 /* Note: This code was originally developed by Realistic Dynamics Inc.
27  * Author: Frank C. Anderson
28  */
29 
30 
31 // INCLUDES
32 #include "osimCommonDLL.h"
33 #include <string>
34 #include "ArrayPtrs.h"
35 #include "Property_Deprecated.h"
36 #include "Object.h"
37 
38 
39 //=============================================================================
40 //=============================================================================
41 namespace OpenSim {
42 
43 /**
44  * Class PropertyObjArray extends class Property.
45  * Assumes template T is a class derived from Object.
46  *
47  * @version 1.0
48  * @author Frank C. Anderson
49  */
50 template<class T = Object>
51 class PropertyObjArray : public Property_Deprecated
52 {
53 
54 //=============================================================================
55 // DATA
56 //=============================================================================
57 private:
58     /** Array of objects. */
59     ArrayPtrs<T> _array;
60 
61 //=============================================================================
62 // METHODS
63 //=============================================================================
64     //--------------------------------------------------------------------------
65     // CONSTRUCTION
66     //--------------------------------------------------------------------------
67 public:
68     PropertyObjArray(const std::string &aName = "",const ArrayPtrs<T> &aArray = ArrayPtrs<T>())
Property_Deprecated(ObjArray,aName)69     :   Property_Deprecated(ObjArray, aName), _array(aArray) {}
PropertyObjArray(const PropertyObjArray<T> & aProperty)70     PropertyObjArray(const PropertyObjArray<T> &aProperty)
71     :   Property_Deprecated(aProperty) { _array = aProperty._array; }
72 
isArrayProperty()73     bool isArrayProperty() const override {return true;}
74 
clone()75     PropertyObjArray* clone() const override
76     {   return new PropertyObjArray<T>(*this); }
77 
getNumValues()78     int getNumValues() const override {return getArraySize();}
isObjectProperty()79     bool isObjectProperty() const override {return true;}
isAcceptableObjectTag(const std::string & objectTypeTag)80     bool isAcceptableObjectTag
81         (const std::string& objectTypeTag) const override {return true;}
getValueAsObject(int index)82     const Object& getValueAsObject(int index) const override
83     {  return *getValueObjPtr(index); }
updValueAsObject(int index)84     Object& updValueAsObject(int index) override
85     {
86         return const_cast<Object&>(*getValueObjPtr(index));
87     }
setValueAsObject(const Object & obj,int index)88     void setValueAsObject(const Object& obj, int index) override
89     {   _array.set(index, dynamic_cast<T*>(obj.clone())); }
90 
91     //--------------------------------------------------------------------------
92     // OPERATORS
93     //--------------------------------------------------------------------------
94 public:
95     PropertyObjArray& operator=(const PropertyObjArray &aProperty) {
96         Property_Deprecated::operator=(aProperty);
97         _array = aProperty._array;
98         return (*this);
99     }
100 
assign(const AbstractProperty & that)101     void assign(const AbstractProperty& that) override {
102         try {
103             *this = dynamic_cast<const PropertyObjArray&>(that);
104         } catch(const std::bad_cast&) {
105             OPENSIM_THROW(InvalidArgument,
106                           "Unsupported type. Expected: " + this->getTypeName() +
107                           " | Received: " + that.getTypeName());
108         }
109     }
110 
111     //--------------------------------------------------------------------------
112     // GET AND SET
113     //--------------------------------------------------------------------------
114 public:
isValidObject(const Object * obj)115     bool isValidObject(const Object *obj) const override
116     { return dynamic_cast<const T*>(obj)!=0; }
117     // TYPE
getTypeName()118     std::string getTypeName() const override
119     {   return T::getClassName(); }
120     // VALUE as String
toString()121     std::string toString() const override
122     {return "(Array of objects)";}
123     // SIZE
getArraySize()124     int getArraySize() const override { return _array.getSize(); }
125     // VALUE
getValueObjPtr(int index)126     const Object* getValueObjPtr(int index) const override { return (Object*)_array.get(index); }
appendValue(Object * obj)127     void appendValue(Object *obj) override {
128         if(!isValidObject(obj))
129             throw Exception("PropertyObjArray: ERR- Attempting to append invalid object of type "
130             + obj->getConcreteClassName(), __FILE__,__LINE__);
131         _array.append(static_cast<T*>(obj));
132     }
clearObjArray()133     void clearObjArray() override { _array.setSize(0); }
134 
135     // Other members (not in Property base class)
setValue(const ArrayPtrs<T> & aArray)136     void setValue(const ArrayPtrs<T> &aArray) { _array = aArray; }
137     // This helps avoid the -Woverloaded-virtual warning with Clang (the method
138     // above otherwise hides the virtual setValue() methods in the base class).
139     using Property_Deprecated::setValue;
getValueObjArray()140     ArrayPtrs<T>& getValueObjArray() { return _array; }
141 #ifndef SWIG
getValueObjArray()142     const ArrayPtrs<T>& getValueObjArray() const { return _array; }
143     bool operator==(const Property_Deprecated& aProperty) const override {
144         // base class
145         bool equal=(Property_Deprecated::operator==(aProperty));
146         if (equal) {
147             PropertyObjArray& other = ((PropertyObjArray&)aProperty);
148             if (_array.getSize()>0 && other._array.getSize()>0){
149                 if (_array.getSize()==other._array.getSize()){
150                     for(int i=0; i<_array.getSize() && equal; i++){
151                         equal = (*(_array.get(i)))==(*(other._array.get(i)));
152                     }
153                     return equal;
154                 }
155                 else
156                     return false;
157             }
158             else
159                 return ((_array.getSize()==0) && (other._array.getSize()==0));
160         }
161         return equal;
162     }
163 #endif
164 
165 //=============================================================================
166 };  // END of class PropertyObjArray
167 
168 } //namespace
169 //=============================================================================
170 //=============================================================================
171 
172 #endif // OPENSIM_PROPERTY_OBJ_ARRAY_H_
173