root/OpenSceneGraph/trunk/examples/osgintrospection/osgintrospection.cpp @ 6941

Revision 6941, 9.1 kB (checked in by robert, 7 years ago)

From Martin Lavery and Robert Osfield, Updated examples to use a variation of the MIT License

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/* OpenSceneGraph example, osgintrospection.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18
19
20#include <osg/ref_ptr>
21
22#include <osgIntrospection/Reflection>
23#include <osgIntrospection/Type>
24#include <osgIntrospection/MethodInfo>
25#include <osgIntrospection/PropertyInfo>
26
27#include <osgDB/DynamicLibrary>
28
29#include <iostream>
30#include <algorithm>
31
32using namespace osgIntrospection;
33
34
35// borrowed from osgDB...
36std::string createLibraryNameForWrapper(const std::string& ext)
37{
38#if defined(WIN32)
39    // !! recheck evolving Cygwin DLL extension naming protocols !! NHV
40    #ifdef __CYGWIN__
41        return "cygosgwrapper_"+ext+".dll";
42    #elif defined(__MINGW32__)
43        return "libosgwrapper_"+ext+".dll";
44    #else
45        #ifdef _DEBUG
46            return "osgwrapper_"+ext+"d.dll";
47        #else
48            return "osgwrapper_"+ext+".dll";
49        #endif
50    #endif
51#elif macintosh
52    return "osgwrapper_"+ext;
53#elif defined(__hpux__)
54    // why don't we use PLUGIN_EXT from the makefiles here?
55    return "osgwrapper_"+ext+".sl";
56#else
57    return "osgwrapper_"+ext+".so";
58#endif
59
60}
61
62bool type_order(const Type *v1, const Type *v2)
63{
64    if (!v1->isDefined()) return v2->isDefined();
65    if (!v2->isDefined()) return false;
66    return v1->getQualifiedName().compare(v2->getQualifiedName()) < 0;
67}
68
69void print_method(const MethodInfo &mi)
70{
71    std::cout << "\t    ";
72
73    // display if the method is virtual
74    if (mi.isVirtual())
75        std::cout << "virtual ";
76
77    // display the method's return type if defined
78    if (mi.getReturnType().isDefined())
79        std::cout << mi.getReturnType().getQualifiedName() << " ";
80    else
81        std::cout << "[UNDEFINED TYPE] ";
82
83    // display the method's name
84    std::cout << mi.getName() << "(";
85
86    // display method's parameters
87    const ParameterInfoList &params = mi.getParameters();
88    for (ParameterInfoList::const_iterator k=params.begin(); k!=params.end(); ++k)
89    {
90        // get the ParameterInfo object that describes the
91        // current parameter
92        const ParameterInfo &pi = **k;
93
94        // display the parameter's modifier
95        if (pi.isIn())
96            std::cout << "IN";
97        if (pi.isOut())
98            std::cout << "OUT";
99        if (pi.isIn() || pi.isOut())
100            std::cout << " ";
101
102        // display the parameter's type name
103        if (pi.getParameterType().isDefined())
104            std::cout << pi.getParameterType().getQualifiedName();
105
106        // display the parameter's name if defined
107        if (!pi.getName().empty())
108            std::cout << " " << pi.getName();
109
110        if ((k+1)!=params.end())
111            std::cout << ", ";
112    }
113    std::cout << ")";
114    if (mi.isConst())
115        std::cout << " const";
116    if (mi.isPureVirtual())
117        std::cout << " = 0";
118    std::cout << "\n";
119}
120
121void print_type(const Type &type)
122{
123    // ignore pointer types and undefined types
124    if (!type.isDefined() || type.isPointer() || type.isReference())
125        return;
126
127    // print the type name
128    std::cout << type.getQualifiedName() << "\n";
129
130    // check whether the type is abstract
131    if (type.isAbstract()) std::cout << "\t[abstract]\n";
132
133    // check whether the type is atomic
134    if (type.isAtomic()) std::cout << "\t[atomic]\n";
135
136    // check whether the type is an enumeration. If yes, display
137    // the list of enumeration labels
138    if (type.isEnum())
139    {
140        std::cout << "\t[enum]\n";
141        std::cout << "\tenumeration values:\n";
142        const EnumLabelMap &emap = type.getEnumLabels();
143        for (EnumLabelMap::const_iterator j=emap.begin(); j!=emap.end(); ++j)
144        {
145            std::cout << "\t\t" << j->second << " = " << j->first << "\n";
146        }
147    }
148
149    // if the type has one or more base types, then display their
150    // names
151    if (type.getNumBaseTypes() > 0)
152    {
153        std::cout << "\tderived from: ";
154        for (int j=0; j<type.getNumBaseTypes(); ++j)
155        {
156            const Type &base = type.getBaseType(j);
157            if (base.isDefined())
158                std::cout << base.getQualifiedName() << "    ";
159            else
160                std::cout << "[undefined type]    ";
161        }
162        std::cout << "\n";
163    }
164
165    // display a list of public methods defined for the current type
166    const MethodInfoList &mil = type.getMethods();
167    if (!mil.empty())
168    {
169        std::cout << "\t* public methods:\n";
170        for (MethodInfoList::const_iterator j=mil.begin(); j!=mil.end(); ++j)
171        {
172            // get the MethodInfo object that describes the current
173            // method
174            const MethodInfo &mi = **j;
175
176            print_method(mi);
177        }
178    }
179
180    // display a list of protected methods defined for the current type
181    const MethodInfoList &bmil = type.getMethods(Type::PROTECTED_FUNCTIONS);
182    if (!bmil.empty())
183    {
184        std::cout << "\t* protected methods:\n";
185        for (MethodInfoList::const_iterator j=bmil.begin(); j!=bmil.end(); ++j)
186        {
187            // get the MethodInfo object that describes the current
188            // method
189            const MethodInfo &mi = **j;
190
191            print_method(mi);
192        }
193    }
194
195    // display a list of properties defined for the current type
196    const PropertyInfoList &pil = type.getProperties();
197    if (!pil.empty())
198    {
199        std::cout << "\t* properties:\n";
200        for (PropertyInfoList::const_iterator j=pil.begin(); j!=pil.end(); ++j)
201        {
202            // get the PropertyInfo object that describes the current
203            // property
204            const PropertyInfo &pi = **j;
205
206            std::cout << "\t    ";
207
208            std::cout << "{";
209            std::cout << (pi.canGet()? "G": " ");
210            std::cout << (pi.canSet()? "S": " ");
211            std::cout << (pi.canCount()? "C": " ");
212            std::cout << (pi.canAdd()? "A": " ");
213            std::cout << "}  ";
214
215            // display the property's name
216            std::cout << pi.getName();
217
218            // display the property's value type if defined
219            std::cout << " (";
220            if (pi.getPropertyType().isDefined())
221                std::cout << pi.getPropertyType().getQualifiedName();
222            else
223                std::cout << "UNDEFINED TYPE";
224            std::cout << ") ";
225
226            // check whether the property is an array property
227            if (pi.isArray())
228            {
229                std::cout << "  [ARRAY]";
230            }
231
232            // check whether the property is an indexed property
233            if (pi.isIndexed())
234            {
235                std::cout << "  [INDEXED]\n\t\t       indices:\n";
236
237                const ParameterInfoList &ind = pi.getIndexParameters();
238
239                // print the list of indices
240                int num = 1;
241                for (ParameterInfoList::const_iterator k=ind.begin(); k!=ind.end(); ++k, ++num)
242                {
243                    std::cout << "\t\t           " << num << ") ";
244                    const ParameterInfo &par = **k;
245                    std::cout << par.getParameterType().getQualifiedName() << " " << par.getName();
246                    std::cout << "\n";
247                }
248            }
249
250            std::cout << "\n";
251        }
252    }
253    std::cout << "\n" << std::string(75, '-') << "\n";
254}
255
256void print_types()
257{
258    // get the map of types that have been reflected
259    const TypeMap &tm = Reflection::getTypes();
260   
261    // create a sortable list of types
262    TypeList types(tm.size());
263    TypeList::iterator j = types.begin();
264    for (TypeMap::const_iterator i=tm.begin(); i!=tm.end(); ++i, ++j)
265        *j = i->second;
266   
267    // sort the map
268    std::sort(types.begin(), types.end(), &type_order);
269
270    // iterate through the type map and display some
271    // details for each type
272    for (TypeList::const_iterator i=types.begin(); i!=types.end(); ++i)
273    {
274        print_type(**i);
275    }
276}
277
278int main()
279{
280    // load the library of wrappers that reflect the
281    // classes defined in the 'osg' namespace. In the
282    // future this will be done automatically under
283    // certain circumstances (like deserialization).
284    osg::ref_ptr<osgDB::DynamicLibrary> osg_reflectors =
285        osgDB::DynamicLibrary::loadLibrary(createLibraryNameForWrapper("osg"));
286   
287    // display a detailed list of reflected types
288    try
289    {
290        print_types();
291    }
292    catch(const osgIntrospection::Exception &e)
293    {
294        std::cerr << e.what() << std::endl;
295    }
296
297    return 0;
298}
Note: See TracBrowser for help on using the browser.