Guest
Public paste!

boost::signal binding in chaiscript

By: a guest | May 6th, 2010 | Syntax: C++ | Size: 5.51 KB | Hits: 1,059 | Expires: Never
Copy text to clipboard
  1. /*
  2.  * File:   main.cpp
  3.  * Author: suicide
  4.  *
  5.  * Created on 21. März 2010, 16:27
  6.  */
  7.  
  8. #include <stdlib.h>
  9. #include <iostream>
  10. #include "chaiscript/chaiscript.hpp"
  11. #include "boost/shared_ptr.hpp"
  12. #include "boost/signal.hpp"
  13. #include <boost/config.hpp>
  14. #include <boost/type_traits/function_traits.hpp>
  15.  
  16.  
  17. template<
  18.     typename Signature, // function type R (T1, T2, ..., TN)
  19.     typename Combiner = boost::last_value<typename boost::function_traits<Signature>::result_type>,
  20.     typename Group = int,
  21.     typename GroupCompare = std::less<Group>,
  22.     typename SlotFunction = boost::function<Signature>
  23. >
  24. class PSignal : public boost::signals::detail::get_signal_impl<Signature, Combiner, Group, GroupCompare, SlotFunction>::type {
  25.  
  26. typedef typename boost::signals::detail::get_signal_impl<Signature, Combiner, Group, GroupCompare, SlotFunction>::type base_type;
  27.  
  28. public:
  29.     explicit PSignal(const Combiner& combiner = Combiner(), const GroupCompare& group_compare = GroupCompare()) : base_type(combiner,group_compare)
  30.     {
  31.     }
  32.     void initchai(chaiscript::ChaiScript& chai)
  33.     {
  34.         try
  35.         {
  36.             chai.add(chaiscript::fun(&PSignal<Signature>::chai_connect),"connect");
  37.             chai.add(chaiscript::fun(&boost::signals::connection::disconnect),"disconnect");
  38.             chai.add(chaiscript::fun(&boost::signals::connection::block),"block");
  39.             chai.add(chaiscript::fun(&boost::signals::connection::unblock),"unblock");
  40.             //todo: constructor() calling for emitting signal
  41.             chai.add(chaiscript::fun(&boost::signals::connection::blocked),"blocked");
  42.             chai.add(chaiscript::fun(&boost::signals::connection::connected),"connected");
  43.             //todo: chai.add(chaiscript::fun(&PSignal<Signature>::chai_disconnect),"disconnect");
  44.             chai.add(chaiscript::fun(&PSignal<Signature>::chai_disconnect_all_slots),"disconnect_all_slots");
  45.             chai.add(chaiscript::fun(&PSignal<Signature>::chai_empty),"empty");
  46.             chai.add(chaiscript::fun(&PSignal<Signature>::chai_num_slots),"num_slots");
  47.  
  48.         }
  49.         catch(...)
  50.         {
  51.             //todo:
  52.         }
  53.     }
  54.     boost::signals::connection chai_connect(const chaiscript::Proxy_Function &f)
  55.     {
  56.         try
  57.         {
  58.             return this->connect(chaiscript::functor<Signature>(f));
  59.         }
  60.         catch(...)
  61.         {
  62.             //todo:
  63.         }
  64.     }
  65.     void chai_disconnect(const chaiscript::Proxy_Function &f)
  66.     {
  67.         try
  68.         {
  69.             this->disconnect(chaiscript::functor<Signature>(f));
  70.         }
  71.         catch(...)
  72.         {
  73.             //todo:
  74.         }
  75.     }
  76.     void chai_disconnect_all_slots(void)
  77.     {
  78.         this->disconnect_all_slots();
  79.     }
  80.     bool chai_empty()
  81.     {
  82.         return this->empty();
  83.     }
  84.     std::size_t chai_num_slots()
  85.     {
  86.         return this->num_slots();
  87.     }
  88.   };
  89.  
  90.  
  91.  
  92. class test
  93. {
  94. public:
  95.     test(chaiscript::ChaiScript& chai) {this->sigUpdate.initchai(chai);}
  96.     void hallo(int x){std::cout<<"hallo"<<x<<std::endl;}
  97.    
  98.     PSignal<void ()> sigUpdate;
  99. };
  100.  
  101.  
  102. class app
  103. {
  104. public:
  105.     void run(){
  106.         this->chai.add(chaiscript::var(&chai), "chai");
  107.  
  108.         //test construction
  109.         this->chai.add(chaiscript::user_type<test>(), "test");
  110.         this->chai.add(chaiscript::constructor<test (chaiscript::ChaiScript&)>(), "test");
  111.         this->chai.eval("var testI := test(chai)"); //ok we have to do it this way, to pre
  112.         //test c++member function call
  113.         this->chai.add(chaiscript::fun(&test::hallo), "hallo");
  114.         this->chai.eval("testI.hallo(5)");
  115.         //test binding new function
  116.         this->chai.eval("def test::doit(){print(\"doit\")}");
  117.         this->chai.eval("testI.doit()");
  118.         //test overwriting c++ function //OVERWRITING DOES NOT WORK. it's ok.
  119.         this->chai.eval("def test::hallo(x){print(\"overwrittenhallo\")}");
  120.         this->chai.eval("testI.hallo(5)");
  121.         //test overwriting chai function //OVERWRITING DOES NOT WORK. it's ok.
  122.         this->chai.eval("def test::doit(){print(\"overwrittendoit\")}");
  123.         this->chai.eval("testI.doit()");
  124.         //test PSignal
  125.         this->chai.add(chaiscript::fun(&test::sigUpdate), "sigUpdate");
  126.  
  127.        /**
  128.         * not used becouse this way it sucks because you have to cast a class created in chai
  129.         * to a c++ class und then init it. so better do it the way shown above and initialise
  130.         * the signals in the test class constructor.
  131.         * i still have no idea how to call the signal from within chaiscript.
  132.         */
  133.         boost::shared_ptr<test> testI = this->chai.eval<boost::shared_ptr<test> >("testI");
  134.         //testI->sigUpdate.initchai(this->chai); //this is better done in the test constructor
  135.  
  136.         this->chai.eval("testI.sigUpdate.connect(fun(){print(\"sigupdate\")})");
  137.         testI->sigUpdate();//in c++ it works this way
  138.  
  139.         this->chai.eval("testI.sigUpdate()"); //how to call the 'emit' of a PSignal (=boost::signal)
  140.        
  141.  
  142.        /**
  143.         * what else does not work:
  144.         * create signals in chai:  var sig := PSignal<void ()>
  145.         *  does not work. template must be known at compiletime
  146.         *
  147.         * conclusion:
  148.         * you can use PSignal (=boost::signal)to connect und disconnect chai functions
  149.         * but you cannot create (and trigger?) them in chaiscript.
  150.         */
  151.     }
  152.  
  153.     chaiscript::ChaiScript chai;
  154. };
  155.  
  156.  
  157. int main(int argc, char** argv) {
  158.     app app;
  159.     app.run();
  160.     return (EXIT_SUCCESS);
  161. }