1 //~ vtl reflection, Maciej Leks, 2006
  2 #include <cstring>
  3 
  4 #include "vtl_reflection.hpp"
  5 
  6 class Parent
  7 {
  8 public:
  9         int a;
 10         double b;
 11         std::string str;
 12 
 13         Parent() { }
 14 
 15         double print(double number)
 16         {
 17                 VTL_PRINT("Parent::print() = %s %f", str.c_str(), number);
 18                 return number;
 19         }
 20 
 21         double sum(double a, double b)
 22         {
 23                 VTL_PRINT("Parent::sum(a,b), a=%f , b=%f", a, b);
 24                 return a + b;
 25         }
 26 
 27         virtual void test() {
 28                 VTL_PRINT("Parent::test", "");
 29         }
 30 
 31         RTTI_DECL(Parent, RTTI_NO_BC, (RTTI_FN(print), RTTI_FN(sum), RTTI_FN(test)), (RTTI_FLD(a), RTTI_FLD(b), RTTI_FLD(str)))
 32 };
 33 
 34 class Child : public Parent
 35 {
 36 public:
 37         Child() { }
 38 
 39         void test() {
 40                 VTL_PRINT("Child::test", "");
 41         }
 42 
 43         RTTI_DECL(Child, RTTI_BC(Parent), (RTTI_FN(print), RTTI_FN(test)), RTTI_NO_FLDS)
 44 };
 45 
 46 int main(int argc, char ** argv)
 47 {
 48         VTL_DEBUG_OFF();
 49 
 50         //Almost 'hello world' example
 51         {
 52                 Child foo;
 53                 vtl_obj obj = foo;
 54                 vtl_rtti* prt = obj.get_rtti(); //get rtti of the Child class
 55 
 56                 //Let's sum two numbers
 57                 vtl_fn_invoker* pfn = prt->function_by_name("sum");
 58                 vtl_args args;
 59 
 60                 args.push_back(2.0);
 61                 args.push_back(3.0);
 62 
 63                 vtl_obj sum_result = (*pfn)(obj, args);
 64 
 65                 //Let's print the result. We could print the result using sum_result object, but let's see how vtl_object passing mechanism works
 66                 args.clear(); //you can use vtl_args as many times as you need        
 67                 pfn = prt->function_by_name("print");
 68                 args.push_back(sum_result); //print method waits for double argument, but we also can use vtl_obj object as a wrapper 
 69                 vtl_obj print_result = (*pfn)(obj, args);
 70                 VTL_PRINT("Sum result is %f", *print_result.cast<double*>());
 71         }
 72 
 73         //Let's see how inheritance works
 74         {
 75                 Child foo;
 76                 Parent *p = &foo;
 77                 vtl_obj obj(p);
 78                 vtl_args args;
 79 
 80                 vtl_rtti* prt = obj.get_rtti();
 81                 vtl_fn_invoker* pfn = prt->function_by_name("test");
 82                 vtl_obj test_result = (*pfn)(obj, args);
 83         }
 84 
 85         //Field modification example   
 86         {
 87                 Child foo;
 88                 vtl_obj obj = foo;
 89                 vtl_rtti* prt = obj.get_rtti();
 90 
 91                 vtl_get_set_invoker* pgsinv = prt->field_by_name("str");
 92 
 93                 vtl_obj obj2 = std::string("My STRING"); //vtl_obj obj = "My STRING"; statement always corrupts stack. As yet do not use string constants.
 94                 pgsinv->set_value(obj, obj2); //
 95 
 96                 vtl_obj get_result = pgsinv->get_value(obj);
 97                 std::cout << "Child::str value is " << *get_result.cast<std::string*>()  << "." << std::endl;
 98         }
 99 
100         //another method of fetching rtti pointer
101         {
102                 vtl_rtti* prt = Child::_get_rtti(); //another possibility of getting vtl_rtti pointer
103         }
104 
105 
106         return 0;
107 }