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

Revision 6303, 8.2 kB (checked in by robert, 8 years ago)

From Mike Wittman, updates to support new protected method support

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