lbp_1_extension.cpp

Go to the documentation of this file.
00001 /** @file lbp_1_extension.cpp 
00002 
00003 Registering a lua script with the libFAUDES run-time interface 
00004 
00005 This tutorial loads a luascript from file an registers it
00006 with the libFAUDES run-time interface. Thus, the script can be
00007 invoked by an application in the same way as built in functions.
00008 
00009 @ingroup Tutorials
00010 
00011 @include lbp_1_extension.cpp
00012 
00013 */
00014 
00015 
00016 
00017 // libfaudes include
00018 #include "libfaudes.h"
00019 
00020 // luafaudes plugin 
00021 #include "libluafaudes.h"
00022 
00023 // we make the faudes namespace available to our program
00024 using namespace faudes;
00025 
00026 
00027 /////////////////
00028 // main program
00029 /////////////////
00030 
00031 
00032 int main (int argc, char **argv) {
00033 
00034   // ******************** load/inspect lua function definition
00035 
00036   // load std registry for data types
00037   LoadRegistry("../../../include/libfaudes.rti");
00038 
00039   // initialize a lua function definition from file
00040   LuaFunctionDefinition lfdef1;
00041   lfdef1.Read("data/largegen.rti");
00042 
00043   // report to console
00044   std::cout << "################################\n";
00045   std::cout << "# lua extension from rti file\n";
00046   lfdef1.Write();
00047   std::cout << "################################\n";
00048 
00049   // run syntax check on script
00050   std::string err=lfdef1.SyntaxCheck();
00051   if(err=="")
00052     std::cout << "script seems ok\n";
00053   else {
00054     std::cout << err << "\n";
00055     return 1;
00056   }
00057 
00058   // test faudes type interface (assignment/equality)
00059   LuaFunctionDefinition lfdef2;
00060   lfdef2 = lfdef1;
00061   if(lfdef2!=lfdef1) {
00062     std::cout << "# ERR: the two definitions should be equal\n";
00063     exit(1);
00064   }
00065 
00066   // report to console
00067   std::cout << "################################\n";
00068   std::cout << "# copy of lua extension\n";
00069   lfdef2.Write();
00070   std::cout << "################################\n";
00071 
00072 
00073   // ******************** execute lua function via rti 
00074 
00075   // instantiate a function object 
00076   faudes::Function* fnct = lfdef2.NewFunction();
00077 
00078   // prepare arguments
00079   Integer cntq=10;
00080   Integer cnts=5;
00081   Generator gres;
00082 
00083   // set argumants
00084   fnct->Variant(0);
00085   fnct->ParamValue(0,&cntq);
00086   fnct->ParamValue(1,&cnts);
00087   fnct->ParamValue(2,&gres);
00088 
00089   // execute lua script
00090   fnct->Execute();
00091 
00092   // report statistics on result
00093   std::cout << "################################\n";
00094   std::cout << "# statistics \n";
00095   gres.SWrite();
00096   std::cout << "################################\n";
00097 
00098   // report test case
00099   FAUDES_TEST_DUMP("large gen",gres);
00100 
00101 
00102   // ******************** execute lua function via rti 
00103 
00104   // load/execute another function definition from file
00105   NameSet sres;
00106   LuaFunctionDefinition lfdef3;
00107   lfdef3.Read("data/xtractalph.rti");
00108   lfdef3.Write();
00109   faudes::Function* fnct3 = lfdef3.NewFunction();
00110   fnct3->Variant(0);
00111   fnct3->ParamValue(0,&gres);
00112   fnct3->ParamValue(1,&sres);
00113   fnct3->Execute();
00114 
00115   // on result
00116   std::cout << "################################\n";
00117   std::cout << "# alphabet \n";
00118   sres.Write();
00119   std::cout << "################################\n";
00120 
00121   // report test case
00122   FAUDES_TEST_DUMP("alphabet",sres);
00123 
00124 
00125 
00126   // ******************** advanced: C++ rtti / vtables / multiple inheritance
00127 
00128   // experiment with compiler's memory layout (base matches void, intermediate cast is fine)
00129   Generator* vgen_vgen = new Generator();
00130   Type*       vgen_ftype = ((Type*)(vgen_vgen));
00131   void*       vgen_void = ((void*)(vgen_vgen));
00132   void*       vgen_void_ftype = ((void*)(vgen_ftype));
00133   std::cout << "C++ casting of a Generator: " <<
00134     " vgen at " << &vgen_vgen << ", ftype at " << vgen_ftype << ", void at " << vgen_void << 
00135     ", void via ftype at " << vgen_void_ftype <<  "\n";
00136 
00137   // experiment with compiler's memory layout (base does not match void for multiple inheritance)
00138   Alphabet* cevs_cevs = new Alphabet();
00139   Type*       cevs_ftype = ((Type*)(cevs_cevs));
00140   void*       cevs_void = ((void*)(cevs_cevs));
00141   void*       cevs_void_ftype = ( (void*)(cevs_ftype));
00142   void*       cevs_dvoid_ftype = ( dynamic_cast<void*>(cevs_ftype));
00143   std::cout << "C++ casting a Alphabet: " <<
00144     " cevs at " << &cevs_cevs << ", ftype at " << cevs_ftype << ", void at " << cevs_void << 
00145     ", void via ftype at " << cevs_void_ftype << 
00146     ", dynamic-void via ftype at " << cevs_dvoid_ftype <<  "\n";
00147 
00148   // conclusion: depending on the compiler, casting to void* via different paths may 
00149   // very well result in a different result; when using dynamic_cast however, the compiler
00150   // has a chance and (at least) gcc manages; thus, dynamic cast is not only for down cats,
00151   // but also for up casts.
00152 
00153   // record test case
00154   FAUDES_TEST_DUMP("dynamic up-cast (a)", vgen_void_ftype== vgen_void);
00155   FAUDES_TEST_DUMP("dynamic up-cast (a)", cevs_dvoid_ftype== cevs_void);
00156 
00157   // delete my objects
00158   delete vgen_vgen;
00159   delete cevs_cevs;
00160 
00161 
00162 }
00163 
00164 

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen