]> git.mxchange.org Git - simgear.git/blob - simgear/nasal/cppbind/cppbind_test.cxx
cppbind: Automatic conversion of derived ghosts and some cleanup/fixes
[simgear.git] / simgear / nasal / cppbind / cppbind_test.cxx
1 #include "Ghost.hxx"
2 #include "NasalHash.hxx"
3
4 #include <boost/shared_ptr.hpp>
5
6 #include <cstring>
7 #include <iostream>
8
9 #define VERIFY(a) \
10   if( !(a) ) \
11   { \
12     std::cerr << "failed: line " << __LINE__ << ": " << #a << std::endl; \
13     return 1; \
14   }
15
16 struct Base
17 {
18   naRef member(const nasal::CallContext&) { return naNil(); }
19   virtual ~Base(){};
20 };
21 struct Derived:
22   public Base
23 {
24   int _x;
25   int getX() const { return _x; }
26   void setX(int x) { _x = x; }
27 };
28 struct DoubleDerived:
29   public Derived
30 {
31
32 };
33 struct DoubleDerived2:
34   public Derived
35 {
36
37 };
38
39 typedef boost::shared_ptr<Base> BasePtr;
40 typedef boost::shared_ptr<Derived> DerivedPtr;
41 typedef boost::shared_ptr<DoubleDerived> DoubleDerivedPtr;
42 typedef boost::shared_ptr<DoubleDerived2> DoubleDerived2Ptr;
43
44 naRef member(Derived&, const nasal::CallContext&) { return naNil(); }
45 naRef member(DerivedPtr&, const nasal::CallContext&) { return naNil(); }
46
47 int main(int argc, char* argv[])
48 {
49   naContext c = naNewContext();
50   naRef r;
51
52   using namespace nasal;
53
54   r = to_nasal(c, "Test");
55   VERIFY( strncmp("Test", naStr_data(r), naStr_len(r)) == 0 );
56   VERIFY( from_nasal<std::string>(c, r) == "Test" );
57
58   r = to_nasal(c, std::string("Test"));
59   VERIFY( strncmp("Test", naStr_data(r), naStr_len(r)) == 0 );
60   VERIFY( from_nasal<std::string>(c, r) == "Test" );
61
62   r = to_nasal(c, 42);
63   VERIFY( naNumValue(r).num == 42 );
64   VERIFY( from_nasal<int>(c, r) == 42 );
65
66   r = to_nasal(c, 4.2f);
67   VERIFY( naNumValue(r).num == 4.2f );
68   VERIFY( from_nasal<float>(c, r) == 4.2f );
69
70   std::vector<int> vec;
71   r = to_nasal(c, vec);
72
73   r = to_nasal(c, "string");
74   try
75   {
76     from_nasal<int>(c, r);
77
78     std::cerr << "failed: Expected bad_nasal_cast to be thrown" << std::endl;
79     return 1;
80   }
81   catch(nasal::bad_nasal_cast&)
82   {}
83
84   Hash hash(c);
85   hash.set("vec", r);
86   hash.set("vec2", vec);
87   hash.set("name", "my-name");
88   hash.set("string", std::string("blub"));
89
90   r = to_nasal(c, hash);
91   VERIFY( naIsHash(r) );
92
93   VERIFY( hash.get<std::string>("name") == "my-name" );
94   VERIFY( naIsString(hash.get("name")) );
95
96   Hash mod = hash.createHash("mod");
97   mod.set("parent", hash);
98
99   Ghost<Base>::init("Base")
100     .method<&Base::member>("member");
101   Ghost<Derived>::init("Derived")
102     .bases<Base>()
103     .member("x", &Derived::getX, &Derived::setX)
104     .method_func<&member>("free_member");
105
106   naRef derived = Ghost<Derived>::create(c);
107   VERIFY( naIsGhost(derived) );
108   VERIFY( std::string("Derived") ==  naGhost_type(derived)->name );
109
110   Ghost<BasePtr>::init("BasePtr");
111   Ghost<DerivedPtr>::init("DerivedPtr")
112     .bases<BasePtr>()
113     .member("x", &Derived::getX, &Derived::setX)
114     .method_func<&member>("free_member");
115   Ghost<DoubleDerivedPtr>::init("DoubleDerivedPtr")
116     .bases<DerivedPtr>();
117   Ghost<DoubleDerived2Ptr>::init("DoubleDerived2Ptr")
118     .bases<DerivedPtr>();
119
120   BasePtr d( new Derived );
121   derived = Ghost<BasePtr>::create(c, d);
122   VERIFY( naIsGhost(derived) );
123   VERIFY( std::string("DerivedPtr") == naGhost_type(derived)->name );
124
125   BasePtr d2( new DoubleDerived );
126   derived = Ghost<BasePtr>::create(c, d2);
127   VERIFY( naIsGhost(derived) );
128   VERIFY( std::string("DoubleDerivedPtr") ==  naGhost_type(derived)->name );
129
130   BasePtr d3( new DoubleDerived2 );
131   derived = Ghost<BasePtr>::create(c, d3);
132   VERIFY( naIsGhost(derived) );
133   VERIFY( std::string("DoubleDerived2Ptr") ==  naGhost_type(derived)->name );
134
135   VERIFY( Ghost<BasePtr>::isBaseOf(derived) );
136   VERIFY( Ghost<DerivedPtr>::isBaseOf(derived) );
137   VERIFY( Ghost<DoubleDerived2Ptr>::isBaseOf(derived) );
138
139   VERIFY( Ghost<BasePtr>::fromNasal(c, derived) == d3 );
140   VERIFY( Ghost<BasePtr>::fromNasal(c, derived) != d2 );
141   VERIFY(    Ghost<DerivedPtr>::fromNasal(c, derived)
142           == boost::dynamic_pointer_cast<Derived>(d3) );
143   VERIFY(    Ghost<DoubleDerived2Ptr>::fromNasal(c, derived)
144           == boost::dynamic_pointer_cast<DoubleDerived2>(d3) );
145   VERIFY( !Ghost<DoubleDerivedPtr>::fromNasal(c, derived) );
146
147   // Check converting to Ghost if using Nasal hashes with actual ghost inside
148   // the hashes parents vector
149   std::vector<naRef> parents;
150   parents.push_back(hash.get_naRef());
151   parents.push_back(derived);
152
153   Hash obj(c);
154   obj.set("parents", parents);
155   VERIFY( Ghost<BasePtr>::fromNasal(c, obj.get_naRef()) == d3 );
156
157   // TODO actually do something with the ghosts...
158
159   naFreeContext(c);
160
161   return 0;
162 }