lbp_1_extension.cpp
Go to the documentation of this file.
1 /** @file lbp_1_extension.cpp
2 
3 Registering a lua script with the libFAUDES run-time interface
4 
5 This tutorial loads a luascript from file an registers it
6 with the libFAUDES run-time interface. Thus, the script can be
7 invoked by an application in the same way as built in functions.
8 
9 @ingroup Tutorials
10 
11 @include lbp_1_extension.cpp
12 
13 */
14 
15 
16 
17 // libfaudes include
18 #include "libfaudes.h"
19 
20 // luafaudes plugin
21 #include "libluafaudes.h"
22 
23 // we make the faudes namespace available to our program
24 using namespace faudes;
25 
26 
27 /////////////////
28 // main program
29 /////////////////
30 
31 
32 int main (int argc, char **argv) {
33 
34  // ******************** load/inspect lua function definition
35 
36  // load std registry for data types
37  LoadRegistry("../../../include/libfaudes.rti");
38 
39  // initialize a lua function definition from file
40  LuaFunctionDefinition lfdef1;
41  lfdef1.Read("data/largegen.rti");
42 
43  // report to console
44  std::cout << "################################\n";
45  std::cout << "# lua extension from rti file\n";
46  lfdef1.Write();
47  std::cout << "################################\n";
48 
49  // run syntax check on script
50  std::string err=lfdef1.SyntaxCheck();
51  if(err=="")
52  std::cout << "script seems ok\n";
53  else {
54  std::cout << err << "\n";
55  return 1;
56  }
57 
58  // test faudes type interface (assignment/equality)
59  LuaFunctionDefinition lfdef2;
60  lfdef2 = lfdef1;
61  if(lfdef2!=lfdef1) {
62  std::cout << "# ERR: the two definitions should be equal\n";
63  exit(1);
64  }
65 
66  // report to console
67  std::cout << "################################\n";
68  std::cout << "# copy of lua extension\n";
69  lfdef2.Write();
70  std::cout << "################################\n";
71 
72 
73  // ******************** execute lua function via rti
74 
75  // instantiate a function object
76  faudes::Function* fnct = lfdef2.NewFunction();
77 
78  // prepare arguments
79  Integer cntq=10;
80  Integer cnts=5;
81  Generator gres;
82 
83  // set argumants
84  fnct->Variant(0);
85  fnct->ParamValue(0,&cntq);
86  fnct->ParamValue(1,&cnts);
87  fnct->ParamValue(2,&gres);
88 
89  // execute lua script
90  fnct->Execute();
91 
92  // report statistics on result
93  std::cout << "################################\n";
94  std::cout << "# statistics \n";
95  gres.SWrite();
96  std::cout << "################################\n";
97 
98  // report test case
99  FAUDES_TEST_DUMP("large gen",gres);
100 
101 
102  // ******************** execute lua function via rti
103 
104  // load/execute another function definition from file
105  NameSet sres;
106  LuaFunctionDefinition lfdef3;
107  lfdef3.Read("data/xtractalph.rti");
108  lfdef3.Write();
109  faudes::Function* fnct3 = lfdef3.NewFunction();
110  fnct3->Variant(0);
111  fnct3->ParamValue(0,&gres);
112  fnct3->ParamValue(1,&sres);
113  fnct3->Execute();
114 
115  // on result
116  std::cout << "################################\n";
117  std::cout << "# alphabet \n";
118  sres.Write();
119  std::cout << "################################\n";
120 
121  // report test case
122  FAUDES_TEST_DUMP("alphabet",sres);
123 
124 
125 
126  // ******************** advanced: C++ rtti / vtables / multiple inheritance
127 
128  // experiment with compiler's memory layout (base matches void, intermediate cast is fine)
129  Generator* vgen_vgen = new Generator();
130  Type* vgen_ftype = ((Type*)(vgen_vgen));
131  void* vgen_void = ((void*)(vgen_vgen));
132  void* vgen_void_ftype = ((void*)(vgen_ftype));
133  std::cout << "C++ casting of a Generator: " <<
134  " vgen at " << &vgen_vgen << ", ftype at " << vgen_ftype << ", void at " << vgen_void <<
135  ", void via ftype at " << vgen_void_ftype << "\n";
136 
137  // experiment with compiler's memory layout (base does not match void for multiple inheritance)
138  Alphabet* cevs_cevs = new Alphabet();
139  Type* cevs_ftype = ((Type*)(cevs_cevs));
140  void* cevs_void = ((void*)(cevs_cevs));
141  void* cevs_void_ftype = ( (void*)(cevs_ftype));
142  void* cevs_dvoid_ftype = ( dynamic_cast<void*>(cevs_ftype));
143  std::cout << "C++ casting a Alphabet: " <<
144  " cevs at " << &cevs_cevs << ", ftype at " << cevs_ftype << ", void at " << cevs_void <<
145  ", void via ftype at " << cevs_void_ftype <<
146  ", dynamic-void via ftype at " << cevs_dvoid_ftype << "\n";
147 
148  // conclusion: depending on the compiler, casting to void* via different paths may
149  // very well lead to a different result; when using dynamic_cast however, the compiler
150  // has a chance and (at least) gcc manages; thus, dynamic cast is not only for down casts,
151  // but also for up casts.
152 
153  // record test case
154  FAUDES_TEST_DUMP("dynamic up-cast (a)", vgen_void_ftype== vgen_void);
155  FAUDES_TEST_DUMP("dynamic up-cast (a)", cevs_dvoid_ftype== cevs_void);
156 
157  // delete my objects
158  delete vgen_vgen;
159  delete cevs_cevs;
160 
161 
162 }
163 
164 

libFAUDES 2.24g --- 2014.09.15 --- c++ api documentaion by doxygen