<commit_before>#include <map>
#include <string>

#include "lukki-db-application.h"
#include "vtrc-common/vtrc-thread-pool.h"
#include "vtrc-common/vtrc-rpc-service-wrapper.h"
#include "vtrc-common/vtrc-connection-iface.h"
#include "vtrc-common/vtrc-closure-holder.h"

#include "vtrc-common/vtrc-rpc-channel.h"
#include "vtrc-common/vtrc-stub-wrapper.h"

#include "vtrc-server/vtrc-channels.h"

#include "protocol/lukkidb.pb.h"

#include "google/protobuf/descriptor.h"

#include "vtrc-bind.h"
#include "vtrc-ref.h"

#include "boost/asio.hpp"

namespace lukki_db {

    using namespace vtrc;

    namespace {

        typedef std::map<std::string, vtrc_example::lukki_string_list> db_type;

        class lukki_db_impl: public vtrc_example::lukki_db {

            typedef lukki_db_impl this_type;

            application              &app_;
            common::connection_iface *connection_;

        public:

            lukki_db_impl( application &app, common::connection_iface *c)
                :app_(app)
                ,connection_(c)
            { }

        private:

            /// simple closure method; Sets fail message
            /// if call was not success
            static void yks_closure( bool success, const std::string &mess,
                              ::google::protobuf::RpcController* controller,
                              vtrc::shared_ptr<common::closure_holder> holder)
            {
                if( !success ) {
                    controller->SetFailed( mess );
                }
            }

            void init(::google::protobuf::RpcController* /*controller*/,
                         const ::vtrc_example::empty* /*request*/,
                         ::vtrc_example::empty* /*response*/,
                         ::google::protobuf::Closure* done)
            {
                done->Run( );
            }

            void set(::google::protobuf::RpcController* controller,
                         const ::vtrc_example::value_set_req* request,
                         ::vtrc_example::empty* response,
                         ::google::protobuf::Closure* done)
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );
                app_.set( request->name( ), request->value( ),
                          vtrc::bind( &this_type::yks_closure,
                                      _1, _2, controller, holder) );
            }

            void upd(::google::protobuf::RpcController* controller,
                            const ::vtrc_example::value_set_req* request,
                            ::vtrc_example::empty* response,
                            ::google::protobuf::Closure* done)
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );
                app_.upd( request->name( ), request->value( ),
                          vtrc::bind( &this_type::yks_closure,
                                      _1, _2, controller, holder) );
            }

            void del(::google::protobuf::RpcController* controller,
                         const ::vtrc_example::name_req* request,
                         ::vtrc_example::empty* response,
                         ::google::protobuf::Closure* done)
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );

                app_.del( request->name( ),
                          vtrc::bind( &this_type::yks_closure,
                                      _1, _2, controller, holder) );

            }

            /// closure method with response message;
            /// Fills response if success
            /// Sets fail message if call was not success
            template <typename ResType>
            static void mess_closure( bool success, const std::string &mess,
                     vtrc::shared_ptr<ResType> res, ResType* response,
                     ::google::protobuf::RpcController* controller,
                     vtrc::shared_ptr<common::closure_holder> holder )
            {
                if( !success ) {
                    controller->SetFailed( mess );
                } else {
                    response->Swap( res.get( ) );
                }
            }

            void get(::google::protobuf::RpcController* controller,
                         const ::vtrc_example::name_req* request,
                         ::vtrc_example::lukki_string_list* response,
                         ::google::protobuf::Closure* done)
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );

                typedef vtrc_example::lukki_string_list res_type;

                vtrc::shared_ptr<res_type> res(new res_type);

                app_.get( request->name( ), res,
                           vtrc::bind( &this_type::mess_closure<res_type>,
                                  _1, _2,
                                  res, response, controller, holder) );
            }

            void stat(::google::protobuf::RpcController* controller,
                         const ::vtrc_example::empty* request,
                         ::vtrc_example::db_stat* response,
                         ::google::protobuf::Closure* done)
            {

                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );

                typedef vtrc_example::db_stat res_type;

                vtrc::shared_ptr<res_type> res(new res_type);
                app_.stat( res, vtrc::bind( &this_type::mess_closure<res_type>,
                                         _1, _2,
                                         res, response, controller, holder) );
            }

            void exist(::google::protobuf::RpcController* controller,
                     const ::vtrc_example::name_req* request,
                     ::vtrc_example::exist_res* response,
                     ::google::protobuf::Closure* done )
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );

                typedef vtrc_example::exist_res res_type;
                vtrc::shared_ptr<res_type> res (new res_type);
                app_.exist( request->name( ), res,
                            vtrc::bind( &this_type::mess_closure<res_type>,
                                        _1, _2,
                                        res, response, controller, holder ));

            }
            void subscribe(::google::protobuf::RpcController* controller,
                     const ::vtrc_example::empty* request,
                     ::vtrc_example::empty* response,
                     ::google::protobuf::Closure* done)
            {
                common::closure_holder holder(done);
                app_.subscribe_client( connection_ );
            }
        };
    }

    struct  application::impl {

        enum { RECORD_DELETED, RECORD_ADDED, RECORD_CHANGED };

        common::thread_pool             db_thread_;
        db_type                         db_;
        vtrc_example::db_stat           db_stat_;
        boost::asio::io_service::strand event_queue_;

        std::vector<server::listener_sptr>  listeners_;

        typedef vtrc::shared_ptr<common::rpc_channel> channel_sptr;
        typedef std::pair<
            common::connection_iface_wptr, channel_sptr
        > connection_channel_pair;

        typedef std::list<connection_channel_pair> subscriber_list_type;

        subscriber_list_type subscribers_;

        impl( boost::asio::io_service &rpc_service )
            :db_thread_(1)
            ,event_queue_(rpc_service)
        { }

        void on_new_connection( server::listener_sptr l,
                                const common::connection_iface *c )
        {
            std::cout << "New connection: "
                      << "\n\tep:     " << l->name( )
                      << "\n\tclient: " << c->name( )
                      << "\n"
                        ;
        }

        void on_stop_connection( server::listener_sptr l,
                                 const common::connection_iface *c )
        {
            std::cout << "Close connection: "
                      << c->name( ) << "\n";
        }

        void set( const std::string &name,
                  const vtrc_example::lukki_string_list &value,
                  const operation_closure &closure)
        {
            if( db_.find( name ) != db_.end( ) ) {
                if( closure ) closure( false, "Record already exists" );
            } else {
                db_stat_.set_set_requests( db_stat_.set_requests( ) + 1 );
                db_[name] = value;
                db_stat_.set_total_records( db_.size( ) );
                send_event( name , RECORD_ADDED );
                if( closure ) closure( true, "Success" );
            }
        }

        void upd( const std::string &name,
                  const vtrc_example::lukki_string_list &value,
                  const operation_closure &closure)
        {
            db_stat_.set_upd_requests( db_stat_.upd_requests( ) + 1 );
            db_type::iterator f( db_.find( name ));

            if( f == db_.end( ) ) {
                if( closure ) closure( false, "Record was not found" );
            } else {
                f->second.CopyFrom( value );
                send_event( name , RECORD_CHANGED );
                if( closure ) closure( true, "Success" );
            }
        }

        void get( const std::string &name,
                  vtrc::shared_ptr<vtrc_example::lukki_string_list> value,
                  const operation_closure &closure)
        {
            db_stat_.set_get_requests( db_stat_.get_requests( ) + 1 );
            db_type::const_iterator f( db_.find( name ));
            if( f == db_.end( ) ) {
                if( closure ) closure( false, "Record was not found" );
            } else {
                value->CopyFrom( f->second );
                if( closure ) closure( true, "Success" );
            }
        }

        void del( const std::string &name,
                  const operation_closure &closure)
        {
            db_stat_.set_del_requests( db_stat_.del_requests( ) + 1 );
            db_type::iterator f( db_.find( name ));
            if( f == db_.end( ) ) {
                if( closure ) closure( false, "Record was not found" );
            } else {
                db_.erase( f );
                send_event( name , RECORD_DELETED );
                if( closure ) closure( true, "Success" );
            }
        }

        void stat( vtrc::shared_ptr<vtrc_example::db_stat> stat,
                   const operation_closure &closure)
        {
            stat->CopyFrom( db_stat_ );
            if( closure ) closure( true, "Success" );
        }

        void exist( const std::string &name,
                    vtrc::shared_ptr<vtrc_example::exist_res> res,
                    const operation_closure &closure)
        {
            res->set_value( db_.find( name ) != db_.end( ) );
            if( closure ) closure( true, "Success" );
        }

        /// events
        void send_event( const std::string &record, unsigned changed )
        {
            event_queue_.post( vtrc::bind( &impl::send_event_impl, this,
                                           record, changed ) );
        }

        typedef vtrc_example::lukki_events_Stub       event_stub_type;
        typedef common::stub_wrapper<event_stub_type> stub_wrapper_type;

        void send_event( vtrc::shared_ptr<common::rpc_channel> channel,
                         const std::string &record, unsigned changed)
        {
            try {

                stub_wrapper_type s( channel );
                vtrc_example::name_req req;

                req.set_name( record );
                switch (changed) {
                case RECORD_DELETED:
                    s.call_request( &event_stub_type::value_removed, &req );
                    break;
                case RECORD_CHANGED:
                    s.call_request( &event_stub_type::value_changed, &req );
                    break;
                case RECORD_ADDED:
                    s.call_request( &event_stub_type::new_value, &req );
                    break;
                default:
                    break;
                }
            } catch( ... ) {
                ;;;
            }
        }

        void send_event_impl( const std::string &record, unsigned changed )
        {
            subscriber_list_type::iterator b(subscribers_.begin( ));
            while( b != subscribers_.end( ) ) {
                common::connection_iface_sptr lck(b->first.lock( ));
                if( lck ) {
                    send_event( b->second, record, changed );
                    ++b;
                } else {
                    b = subscribers_.erase( b );
                }
            }
        }

        void send_subscribed( common::rpc_channel &channel )
        {
            try {
                stub_wrapper_type stub(&channel);
                stub.call( &event_stub_type::subscribed );
            } catch( ... ) {
                ;;;
            }
        }

        void subscribe_impl( common::connection_iface_wptr conn )
        {
            common::connection_iface_sptr lck(conn.lock( ));
            if( lck ) {
                vtrc::shared_ptr<common::rpc_channel> channel
                    (server::channels::unicast::create_event_channel
                            ( lck, true ));
                subscribers_.push_back( std::make_pair(conn, channel) );
                send_subscribed( *channel );
            }
        }

        void subscribe_client( vtrc::common::connection_iface* conn )
        {
            event_queue_.post( vtrc::bind(&impl::subscribe_impl, this,
                               conn->weak_from_this( ) ));
        }

    };

    application::application( vtrc::common::pool_pair &pp )
        :vtrc::server::application(pp)
        ,impl_(new impl(pp.get_rpc_service( )))
    {

    }

    application::~application( )
    {
        delete impl_;
    }

    vtrc::shared_ptr<common::rpc_service_wrapper>
         application::get_service_by_name( vtrc::common::connection_iface* conn,
                                  const std::string &service_name )
    {
        if( service_name == lukki_db_impl::descriptor( )->full_name( ) ) {
            return vtrc::make_shared<common::rpc_service_wrapper>
                                        ( new lukki_db_impl( *this, conn ) );
        }
        return vtrc::shared_ptr<common::rpc_service_wrapper>( );
    }

    void application::attach_start_listener( server::listener_sptr listen )
    {
        listen->get_on_new_connection( ).connect(
                    vtrc::bind( &impl::on_new_connection, impl_, listen, _1 ));

        listen->get_on_stop_connection( ).connect(
                    vtrc::bind( &impl::on_stop_connection, impl_, listen, _1 ));

        listen->start( );
        impl_->listeners_.push_back( listen );
    }

    /// as far as we have only one thread for operations with our DB
    /// we have to push call to this thread
    /// so we don't need the locks for DB access :]
    void application::set( const std::string &name,
              const vtrc_example::lukki_string_list &value,
              const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
                    vtrc::bind( &impl::set, impl_,name, value, closure));
    }

    void application::upd( const std::string &name,
              const vtrc_example::lukki_string_list &value,
              const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
                    vtrc::bind( &impl::upd, impl_,name, value, closure));
    }

    void application::get( const std::string &name,
                       vtrc::shared_ptr<vtrc_example::lukki_string_list> value,
                       const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
                    vtrc::bind( &impl::get, impl_, name, value, closure));
    }

    void application::del( const std::string &name,
                           const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
                    vtrc::bind( &impl::del, impl_, name, closure));
    }

    void application::stat(vtrc::shared_ptr<vtrc_example::db_stat> stat,
                            const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
               vtrc::bind( &impl::stat, impl_, stat, closure));
    }

    void application::exist( const std::string &name,
                vtrc::shared_ptr<vtrc_example::exist_res> res,
                const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
               vtrc::bind( &impl::exist, impl_, name, res, closure));
    }

    void application::subscribe_client( vtrc::common::connection_iface* conn )
    {
        impl_->subscribe_client( conn );
    }

}

<commit_msg>examples<commit_after>#include <map>
#include <string>

#include "lukki-db-application.h"
#include "vtrc-common/vtrc-thread-pool.h"
#include "vtrc-common/vtrc-rpc-service-wrapper.h"
#include "vtrc-common/vtrc-connection-iface.h"
#include "vtrc-common/vtrc-closure-holder.h"

#include "vtrc-common/vtrc-rpc-channel.h"
#include "vtrc-common/vtrc-stub-wrapper.h"

#include "vtrc-server/vtrc-channels.h"

#include "protocol/lukkidb.pb.h"

#include "google/protobuf/descriptor.h"

#include "vtrc-bind.h"
#include "vtrc-ref.h"

#include "boost/asio.hpp"

namespace lukki_db {

    using namespace vtrc;

    namespace {

        typedef std::map<std::string, vtrc_example::lukki_string_list> db_type;

        class lukki_db_impl: public vtrc_example::lukki_db {

            typedef lukki_db_impl this_type;

            application              &app_;
            common::connection_iface *connection_;

        public:

            lukki_db_impl( application &app, common::connection_iface *c)
                :app_(app)
                ,connection_(c)
            { }

        private:

            /// simple closure method; Sets fail message
            /// if call was not success
            static void yks_closure( bool success, const std::string &mess,
                              ::google::protobuf::RpcController* controller,
                              vtrc::shared_ptr<common::closure_holder> holder)
            {
                if( !success ) {
                    controller->SetFailed( mess );
                }
            }

            void init(::google::protobuf::RpcController* /*controller*/,
                         const ::vtrc_example::empty* /*request*/,
                         ::vtrc_example::empty* /*response*/,
                         ::google::protobuf::Closure* done)
            {
                done->Run( );
            }

            void set(::google::protobuf::RpcController* controller,
                         const ::vtrc_example::value_set_req* request,
                         ::vtrc_example::empty* response,
                         ::google::protobuf::Closure* done)
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );
                app_.set( request->name( ), request->value( ),
                          vtrc::bind( &this_type::yks_closure,
                                      _1, _2, controller, holder) );
            }

            void upd(::google::protobuf::RpcController* controller,
                            const ::vtrc_example::value_set_req* request,
                            ::vtrc_example::empty* response,
                            ::google::protobuf::Closure* done)
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );
                app_.upd( request->name( ), request->value( ),
                          vtrc::bind( &this_type::yks_closure,
                                      _1, _2, controller, holder) );
            }

            void del(::google::protobuf::RpcController* controller,
                         const ::vtrc_example::name_req* request,
                         ::vtrc_example::empty* response,
                         ::google::protobuf::Closure* done)
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );

                app_.del( request->name( ),
                          vtrc::bind( &this_type::yks_closure,
                                      _1, _2, controller, holder) );

            }

            /// closure method with response message;
            /// Fills response if success
            /// Sets fail message if call was not success
            template <typename ResType>
            static void mess_closure( bool success, const std::string &mess,
                     vtrc::shared_ptr<ResType> res, ResType* response,
                     ::google::protobuf::RpcController* controller,
                     vtrc::shared_ptr<common::closure_holder> holder )
            {
                if( !success ) {
                    controller->SetFailed( mess );
                } else {
                    response->Swap( res.get( ) );
                }
            }

            void get(::google::protobuf::RpcController* controller,
                         const ::vtrc_example::name_req* request,
                         ::vtrc_example::lukki_string_list* response,
                         ::google::protobuf::Closure* done)
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );

                typedef vtrc_example::lukki_string_list res_type;

                vtrc::shared_ptr<res_type> res(new res_type);

                app_.get( request->name( ), res,
                           vtrc::bind( &this_type::mess_closure<res_type>,
                                  _1, _2,
                                  res, response, controller, holder) );
            }

            void stat(::google::protobuf::RpcController* controller,
                         const ::vtrc_example::empty* request,
                         ::vtrc_example::db_stat* response,
                         ::google::protobuf::Closure* done)
            {

                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );

                typedef vtrc_example::db_stat res_type;

                vtrc::shared_ptr<res_type> res(new res_type);
                app_.stat( res, vtrc::bind( &this_type::mess_closure<res_type>,
                                         _1, _2,
                                         res, response, controller, holder) );
            }

            void exist(::google::protobuf::RpcController* controller,
                     const ::vtrc_example::name_req* request,
                     ::vtrc_example::exist_res* response,
                     ::google::protobuf::Closure* done )
            {
                vtrc::shared_ptr<common::closure_holder> holder(
                            common::closure_holder::create(done) );

                typedef vtrc_example::exist_res res_type;
                vtrc::shared_ptr<res_type> res (new res_type);
                app_.exist( request->name( ), res,
                            vtrc::bind( &this_type::mess_closure<res_type>,
                                        _1, _2,
                                        res, response, controller, holder ));

            }
            void subscribe(::google::protobuf::RpcController* controller,
                     const ::vtrc_example::empty* request,
                     ::vtrc_example::empty* response,
                     ::google::protobuf::Closure* done)
            {
                common::closure_holder holder(done);
                app_.subscribe_client( connection_ );
            }
        };
    }

    struct  application::impl {

        enum { RECORD_DELETED, RECORD_ADDED, RECORD_CHANGED };

        common::thread_pool             db_thread_;
        db_type                         db_;
        vtrc_example::db_stat           db_stat_;
        boost::asio::io_service::strand event_queue_;

        std::vector<server::listener_sptr>  listeners_;

        typedef vtrc::shared_ptr<common::rpc_channel> channel_sptr;
        typedef std::pair<
            common::connection_iface_wptr, channel_sptr
        > connection_channel_pair;

        typedef std::list<connection_channel_pair> subscriber_list_type;

        subscriber_list_type subscribers_;

        impl( boost::asio::io_service &rpc_service )
            :db_thread_(1)
            ,event_queue_(rpc_service)
        { }

        void on_new_connection( server::listener_sptr l,
                                const common::connection_iface *c )
        {
            std::cout << "New connection: "
                      << "\n\tep:     " << l->name( )
                      << "\n\tclient: " << c->name( )
                      << "\n"
                        ;
        }

        void on_stop_connection( server::listener_sptr l,
                                 const common::connection_iface *c )
        {
            std::cout << "Close connection: "
                      << c->name( ) << "\n";
        }

        void set( const std::string &name,
                  const vtrc_example::lukki_string_list &value,
                  const operation_closure &closure)
        {
            if( db_.find( name ) != db_.end( ) ) {
                if( closure ) closure( false, "Record already exists" );
            } else {
                db_stat_.set_set_requests( db_stat_.set_requests( ) + 1 );
                db_[name] = value;
                db_stat_.set_total_records( db_.size( ) );
                send_event( name , RECORD_ADDED );
                if( closure ) closure( true, "Success" );
            }
        }

        void upd( const std::string &name,
                  const vtrc_example::lukki_string_list &value,
                  const operation_closure &closure)
        {
            db_stat_.set_upd_requests( db_stat_.upd_requests( ) + 1 );
            db_type::iterator f( db_.find( name ));

            if( f == db_.end( ) ) {
                if( closure ) closure( false, "Record was not found" );
            } else {
                f->second.CopyFrom( value );
                send_event( name , RECORD_CHANGED );
                if( closure ) closure( true, "Success" );
            }
        }

        void get( const std::string &name,
                  vtrc::shared_ptr<vtrc_example::lukki_string_list> value,
                  const operation_closure &closure)
        {
            db_stat_.set_get_requests( db_stat_.get_requests( ) + 1 );
            db_type::const_iterator f( db_.find( name ));
            if( f == db_.end( ) ) {
                if( closure ) closure( false, "Record was not found" );
            } else {
                value->CopyFrom( f->second );
                if( closure ) closure( true, "Success" );
            }
        }

        void del( const std::string &name,
                  const operation_closure &closure)
        {
            db_stat_.set_del_requests( db_stat_.del_requests( ) + 1 );
            db_type::iterator f( db_.find( name ));
            if( f == db_.end( ) ) {
                if( closure ) closure( false, "Record was not found" );
            } else {
                db_.erase( f );
                send_event( name , RECORD_DELETED );
                if( closure ) closure( true, "Success" );
            }
        }

        void stat( vtrc::shared_ptr<vtrc_example::db_stat> stat,
                   const operation_closure &closure)
        {
            stat->CopyFrom( db_stat_ );
            if( closure ) closure( true, "Success" );
        }

        void exist( const std::string &name,
                    vtrc::shared_ptr<vtrc_example::exist_res> res,
                    const operation_closure &closure)
        {
            res->set_value( db_.find( name ) != db_.end( ) );
            if( closure ) closure( true, "Success" );
        }

        /// events
        void send_event( const std::string &record, unsigned changed )
        {
            event_queue_.post( vtrc::bind( &impl::send_event_impl, this,
                                           record, changed ) );
        }

        typedef vtrc_example::lukki_events_Stub       event_stub_type;
        typedef common::stub_wrapper<event_stub_type> stub_wrapper_type;

        void send_event( vtrc::shared_ptr<common::rpc_channel> channel,
                         const std::string &record, unsigned changed)
        {
            try {

                stub_wrapper_type s( channel );
                vtrc_example::name_req req;

                req.set_name( record );
                switch (changed) {
                case RECORD_DELETED:
                    s.call_request( &event_stub_type::value_removed, &req );
                    break;
                case RECORD_CHANGED:
                    s.call_request( &event_stub_type::value_changed, &req );
                    break;
                case RECORD_ADDED:
                    s.call_request( &event_stub_type::new_value, &req );
                    break;
                default:
                    break;
                }
            } catch( ... ) {
                ;;;
            }
        }

        void send_event_impl( const std::string &record, unsigned changed )
        {
            subscriber_list_type::iterator b(subscribers_.begin( ));
            while( b != subscribers_.end( ) ) {
                common::connection_iface_sptr lck(b->first.lock( ));
                if( lck ) {
                    send_event( b->second, record, changed );
                    ++b;
                } else {
                    b = subscribers_.erase( b );
                }
            }
        }

        void send_subscribed( common::rpc_channel &channel )
        {
            try {
                stub_wrapper_type stub(&channel);
                stub.call( &event_stub_type::subscribed );
            } catch( ... ) {
                ;;;
            }
        }

        void subscribe_impl( common::connection_iface_wptr conn )
        {
            common::connection_iface_sptr lck(conn.lock( ));
            if( lck ) {
                vtrc::shared_ptr<common::rpc_channel> channel
                    (server::channels::unicast::create_event_channel
                            ( lck, true ));
                subscribers_.push_back( std::make_pair(conn, channel) );
                send_subscribed( *channel );
            }
        }

        void subscribe_client( vtrc::common::connection_iface* conn )
        {
            event_queue_.post( vtrc::bind(&impl::subscribe_impl, this,
                               conn->weak_from_this( ) ));
        }

    };

    application::application( vtrc::common::pool_pair &pp )
        :vtrc::server::application(pp)
        ,impl_(new impl(pp.get_rpc_service( )))
    {

    }

    application::~application( )
    {
        delete impl_;
    }

    vtrc::shared_ptr<common::rpc_service_wrapper>
         application::get_service_by_name( vtrc::common::connection_iface* conn,
                                  const std::string &service_name )
    {
        if( service_name == lukki_db_impl::descriptor( )->full_name( ) ) {
            return vtrc::make_shared<common::rpc_service_wrapper>
                                        ( new lukki_db_impl( *this, conn ) );
        }
        return vtrc::shared_ptr<common::rpc_service_wrapper>( );
    }

    void application::attach_start_listener( server::listener_sptr listen )
    {
        listen->get_on_new_connection( ).connect(
                    vtrc::bind( &impl::on_new_connection, impl_, listen, _1 ));

        listen->get_on_stop_connection( ).connect(
                    vtrc::bind( &impl::on_stop_connection, impl_, listen, _1 ));

        listen->start( );
        impl_->listeners_.push_back( listen );
    }

    /// as far as we have only one thread for operations with our DB
    /// we have to push the calls to this thread
    /// so we don't need the locks for DB access :]
    void application::set( const std::string &name,
              const vtrc_example::lukki_string_list &value,
              const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
                    vtrc::bind( &impl::set, impl_,name, value, closure));
    }

    void application::upd( const std::string &name,
              const vtrc_example::lukki_string_list &value,
              const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
                    vtrc::bind( &impl::upd, impl_,name, value, closure));
    }

    void application::get( const std::string &name,
                       vtrc::shared_ptr<vtrc_example::lukki_string_list> value,
                       const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
                    vtrc::bind( &impl::get, impl_, name, value, closure));
    }

    void application::del( const std::string &name,
                           const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
                    vtrc::bind( &impl::del, impl_, name, closure));
    }

    void application::stat(vtrc::shared_ptr<vtrc_example::db_stat> stat,
                            const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
               vtrc::bind( &impl::stat, impl_, stat, closure));
    }

    void application::exist( const std::string &name,
                vtrc::shared_ptr<vtrc_example::exist_res> res,
                const operation_closure &closure)
    {
        impl_->db_thread_.get_io_service( ).post(
               vtrc::bind( &impl::exist, impl_, name, res, closure));
    }

    void application::subscribe_client( vtrc::common::connection_iface* conn )
    {
        impl_->subscribe_client( conn );
    }

}

<|endoftext|>


<commit_before>#include <osg/Texture2D>
#include <osg/TexGen>
#include <osg/Material>
#include <osg/LightSource>
#include <osg/Geode>
#include <osg/ShapeDrawable>

#include <osgUtil/CullVisitor>
#include <osgUtil/RenderToTextureStage>

#include "CreateShadowedScene.h"

using namespace osg;

class CreateShadowTextureCullCallback : public osg::NodeCallback
{
    public:

        CreateShadowTextureCullCallback(osg::Node* shadower,const osg::Vec3& position, const osg::Vec4& ambientLightColor, unsigned int textureUnit):
            _shadower(shadower),
            _position(position),
            _ambientLightColor(ambientLightColor),
            _unit(textureUnit),
            _shadowState(new osg::StateSet),
            _shadowedState(new osg::StateSet)
        {
            _texture = new osg::Texture2D;
            _texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
            _texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
            _texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
            _texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
            _texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
        }

        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
        {

            osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
            if (cullVisitor && (_texture.valid() && _shadower.valid()))
            {
                doPreRender(*node,*cullVisitor);

            }
            else
            {
                // must traverse the shadower
                traverse(node,nv);
            }
        }

    protected:

        void doPreRender(osg::Node& node, osgUtil::CullVisitor& cv);

        osg::ref_ptr<osg::Node>      _shadower;
        osg::ref_ptr<osg::Texture2D> _texture;
        osg::Vec3                    _position;
        osg::Vec4                    _ambientLightColor;
        unsigned int                 _unit;
        osg::ref_ptr<osg::StateSet>  _shadowState;
        osg::ref_ptr<osg::StateSet>  _shadowedState;

};

void CreateShadowTextureCullCallback::doPreRender(osg::Node& node, osgUtil::CullVisitor& cv)
{

    const osg::BoundingSphere& bs = _shadower->getBound();
    if (!bs.valid())
    {
        osg::notify(osg::WARN) << "bb invalid"<<_shadower.get()<<std::endl;
        return;
    }

    // create the render to texture stage.
    osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage;

    // set up lighting.
    // currently ignore lights in the scene graph itself..
    // will do later.
    osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage();

    // set up the background color and clear mask.
    rtts->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
    //rtts->setClearMask(previous_stage->getClearMask());

    // set up to charge the same RenderStageLighting is the parent previous stage.
    rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());

    // record the render bin, to be restored after creation
    // of the render to text
    osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin();

    // set the current renderbin to be the newly created stage.
    cv.setCurrentRenderBin(rtts.get());

    float centerDistance = (_position-bs.center()).length();

    float znear = centerDistance-bs.radius();
    float zfar  = centerDistance+bs.radius();
    float zNearRatio = 0.001f;
    if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;

    // 2:1 aspect ratio as per flag geomtry below.
    float top   = (bs.radius()/centerDistance)*znear;
    float right = top;

    // set up projection.
    osg::RefMatrix* projection = new osg::RefMatrix;
    projection->makeFrustum(-right,right,-top,top,znear,zfar);

    cv.pushProjectionMatrix(projection);

    osg::RefMatrix* matrix = new osg::RefMatrix;
    matrix->makeLookAt(_position,bs.center(),osg::Vec3(0.0f,1.0f,0.0f));

    osg::Matrix MV = cv.getModelViewMatrix();

    // compute the matrix which takes a vertex from local coords into tex coords
    // will use this later to specify osg::TexGen..
    osg::Matrix MVPT =
                       *matrix *
                       *projection *
                       osg::Matrix::translate(1.0,1.0,1.0) *
                       osg::Matrix::scale(0.5f,0.5f,0.5f);

    cv.pushModelViewMatrix(matrix);

    // make the material black for a shadow.
    osg::Material* material = new osg::Material;
    material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f));
    material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f));
    material->setEmission(osg::Material::FRONT_AND_BACK,_ambientLightColor);
    material->setShininess(osg::Material::FRONT_AND_BACK,0.0f);
    _shadowState->setAttribute(material,osg::StateAttribute::OVERRIDE);

    cv.pushStateSet(_shadowState.get());

    {

        // traverse the shadower
        _shadower->accept(cv);

    }

    cv.popStateSet();

    // restore the previous model view matrix.
    cv.popModelViewMatrix();

    // restore the previous model view matrix.
    cv.popProjectionMatrix();

    // restore the previous renderbin.
    cv.setCurrentRenderBin(previousRenderBin);

    if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0)
    {
        // getting to this point means that all the shadower has been
        // culled by small feature culling or is beyond LOD ranges.
        return;
    }

    int height = 256;
    int width  = 256;

    const osg::Viewport& viewport = *cv.getViewport();

    // offset the impostor viewport from the center of the main window
    // viewport as often the edges of the viewport might be obscured by
    // other windows, which can cause image/reading writing problems.
    int center_x = viewport.x()+viewport.width()/2;
    int center_y = viewport.y()+viewport.height()/2;

    osg::Viewport* new_viewport = new osg::Viewport;
    new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height);
    rtts->setViewport(new_viewport);

    _shadowState->setAttribute(new_viewport);

    // and the render to texture stage to the current stages
    // dependancy list.
    cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get());

    // if one exist attach texture to the RenderToTextureStage.
    if (_texture.valid()) rtts->setTexture(_texture.get());

    // set up the stateset to decorate the shadower with the shadow texture
    // with the appropriate tex gen coords.
    TexGen* texgen = new TexGen;
    //texgen->setMatrix(MV);
    texgen->setMode(osg::TexGen::EYE_LINEAR);
    texgen->setPlane(osg::TexGen::S,osg::Plane(MVPT(0,0),MVPT(1,0),MVPT(2,0),MVPT(3,0)));
    texgen->setPlane(osg::TexGen::T,osg::Plane(MVPT(0,1),MVPT(1,1),MVPT(2,1),MVPT(3,1)));
    texgen->setPlane(osg::TexGen::R,osg::Plane(MVPT(0,2),MVPT(1,2),MVPT(2,2),MVPT(3,2)));
    texgen->setPlane(osg::TexGen::Q,osg::Plane(MVPT(0,3),MVPT(1,3),MVPT(2,3),MVPT(3,3)));

    cv.getRenderStage()->addPositionedTextureAttribute(0,new osg::RefMatrix(MV),texgen);

    _shadowedState->setTextureAttributeAndModes(_unit,_texture.get(),osg::StateAttribute::ON);
    _shadowedState->setTextureAttribute(_unit,texgen);
    _shadowedState->setTextureMode(_unit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
    _shadowedState->setTextureMode(_unit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
    _shadowedState->setTextureMode(_unit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
    _shadowedState->setTextureMode(_unit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);

    cv.pushStateSet(_shadowedState.get());

        // must traverse the shadower
        traverse(&node,&cv);

    cv.popStateSet();

}

// set up a light source with the shadower and shodower subgraphs below it
// with the appropriate callbacks set up.
osg::Group* createShadowedScene(osg::Node* shadower,osg::Node* shadowed,const osg::Vec3& lightPosition,float radius,unsigned int textureUnit)
{
    osg::LightSource* lightgroup = new osg::LightSource;

    osg::Light* light = new osg::Light;
    light->setPosition(osg::Vec4(lightPosition,1.0f));
    light->setLightNum(0);

    lightgroup->setLight(light);

    osg::Vec4 ambientLightColor(0.2,0.2f,0.2f,1.0f);

    // add the shadower
    lightgroup->addChild(shadower);

    // add the shadowed with the callback to generate the shadow texture.
    shadowed->setCullCallback(new CreateShadowTextureCullCallback(shadower,lightPosition,ambientLightColor,textureUnit));
    lightgroup->addChild(shadowed);

    osg::Geode* lightgeode = new osg::Geode;
    lightgeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
    lightgeode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(lightPosition,radius)));

    lightgroup->addChild(lightgeode);

    return lightgroup;
}

<commit_msg>Updated to use new TexGen method<commit_after>#include <osg/Texture2D>
#include <osg/TexGen>
#include <osg/Material>
#include <osg/LightSource>
#include <osg/Geode>
#include <osg/ShapeDrawable>

#include <osgUtil/CullVisitor>
#include <osgUtil/RenderToTextureStage>

#include "CreateShadowedScene.h"

using namespace osg;

class CreateShadowTextureCullCallback : public osg::NodeCallback
{
    public:

        CreateShadowTextureCullCallback(osg::Node* shadower,const osg::Vec3& position, const osg::Vec4& ambientLightColor, unsigned int textureUnit):
            _shadower(shadower),
            _position(position),
            _ambientLightColor(ambientLightColor),
            _unit(textureUnit),
            _shadowState(new osg::StateSet),
            _shadowedState(new osg::StateSet)
        {
            _texture = new osg::Texture2D;
            _texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
            _texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
            _texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::CLAMP_TO_BORDER);
            _texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::CLAMP_TO_BORDER);
            _texture->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
        }

        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
        {

            osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
            if (cullVisitor && (_texture.valid() && _shadower.valid()))
            {
                doPreRender(*node,*cullVisitor);

            }
            else
            {
                // must traverse the shadower
                traverse(node,nv);
            }
        }

    protected:

        void doPreRender(osg::Node& node, osgUtil::CullVisitor& cv);

        osg::ref_ptr<osg::Node>      _shadower;
        osg::ref_ptr<osg::Texture2D> _texture;
        osg::Vec3                    _position;
        osg::Vec4                    _ambientLightColor;
        unsigned int                 _unit;
        osg::ref_ptr<osg::StateSet>  _shadowState;
        osg::ref_ptr<osg::StateSet>  _shadowedState;

};

void CreateShadowTextureCullCallback::doPreRender(osg::Node& node, osgUtil::CullVisitor& cv)
{

    const osg::BoundingSphere& bs = _shadower->getBound();
    if (!bs.valid())
    {
        osg::notify(osg::WARN) << "bb invalid"<<_shadower.get()<<std::endl;
        return;
    }

    // create the render to texture stage.
    osg::ref_ptr<osgUtil::RenderToTextureStage> rtts = new osgUtil::RenderToTextureStage;

    // set up lighting.
    // currently ignore lights in the scene graph itself..
    // will do later.
    osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->getStage();

    // set up the background color and clear mask.
    rtts->setClearColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
    //rtts->setClearMask(previous_stage->getClearMask());

    // set up to charge the same RenderStageLighting is the parent previous stage.
    rtts->setRenderStageLighting(previous_stage->getRenderStageLighting());

    // record the render bin, to be restored after creation
    // of the render to text
    osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin();

    // set the current renderbin to be the newly created stage.
    cv.setCurrentRenderBin(rtts.get());

    float centerDistance = (_position-bs.center()).length();

    float znear = centerDistance-bs.radius();
    float zfar  = centerDistance+bs.radius();
    float zNearRatio = 0.001f;
    if (znear<zfar*zNearRatio) znear = zfar*zNearRatio;

    // 2:1 aspect ratio as per flag geomtry below.
    float top   = (bs.radius()/centerDistance)*znear;
    float right = top;

    // set up projection.
    osg::RefMatrix* projection = new osg::RefMatrix;
    projection->makeFrustum(-right,right,-top,top,znear,zfar);

    cv.pushProjectionMatrix(projection);

    osg::RefMatrix* matrix = new osg::RefMatrix;
    matrix->makeLookAt(_position,bs.center(),osg::Vec3(0.0f,1.0f,0.0f));

    osg::Matrix MV = cv.getModelViewMatrix();

    // compute the matrix which takes a vertex from local coords into tex coords
    // will use this later to specify osg::TexGen..
    osg::Matrix MVPT =
                       *matrix *
                       *projection *
                       osg::Matrix::translate(1.0,1.0,1.0) *
                       osg::Matrix::scale(0.5f,0.5f,0.5f);

    cv.pushModelViewMatrix(matrix);

    // make the material black for a shadow.
    osg::Material* material = new osg::Material;
    material->setAmbient(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f));
    material->setDiffuse(osg::Material::FRONT_AND_BACK,osg::Vec4(0.0f,0.0f,0.0f,1.0f));
    material->setEmission(osg::Material::FRONT_AND_BACK,_ambientLightColor);
    material->setShininess(osg::Material::FRONT_AND_BACK,0.0f);
    _shadowState->setAttribute(material,osg::StateAttribute::OVERRIDE);

    cv.pushStateSet(_shadowState.get());

    {

        // traverse the shadower
        _shadower->accept(cv);

    }

    cv.popStateSet();

    // restore the previous model view matrix.
    cv.popModelViewMatrix();

    // restore the previous model view matrix.
    cv.popProjectionMatrix();

    // restore the previous renderbin.
    cv.setCurrentRenderBin(previousRenderBin);

    if (rtts->getRenderGraphList().size()==0 && rtts->getRenderBinList().size()==0)
    {
        // getting to this point means that all the shadower has been
        // culled by small feature culling or is beyond LOD ranges.
        return;
    }

    int height = 256;
    int width  = 256;

    const osg::Viewport& viewport = *cv.getViewport();

    // offset the impostor viewport from the center of the main window
    // viewport as often the edges of the viewport might be obscured by
    // other windows, which can cause image/reading writing problems.
    int center_x = viewport.x()+viewport.width()/2;
    int center_y = viewport.y()+viewport.height()/2;

    osg::Viewport* new_viewport = new osg::Viewport;
    new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height);
    rtts->setViewport(new_viewport);

    _shadowState->setAttribute(new_viewport);

    // and the render to texture stage to the current stages
    // dependancy list.
    cv.getCurrentRenderBin()->getStage()->addToDependencyList(rtts.get());

    // if one exist attach texture to the RenderToTextureStage.
    if (_texture.valid()) rtts->setTexture(_texture.get());

    // set up the stateset to decorate the shadower with the shadow texture
    // with the appropriate tex gen coords.
    TexGen* texgen = new TexGen;
    //texgen->setMatrix(MV);
    texgen->setMode(osg::TexGen::EYE_LINEAR);
    texgen->setPlanesFromMatrix(MVPT);

    cv.getRenderStage()->addPositionedTextureAttribute(0,new osg::RefMatrix(MV),texgen);

    _shadowedState->setTextureAttributeAndModes(_unit,_texture.get(),osg::StateAttribute::ON);
    _shadowedState->setTextureAttribute(_unit,texgen);
    _shadowedState->setTextureMode(_unit,GL_TEXTURE_GEN_S,osg::StateAttribute::ON);
    _shadowedState->setTextureMode(_unit,GL_TEXTURE_GEN_T,osg::StateAttribute::ON);
    _shadowedState->setTextureMode(_unit,GL_TEXTURE_GEN_R,osg::StateAttribute::ON);
    _shadowedState->setTextureMode(_unit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);

    cv.pushStateSet(_shadowedState.get());

        // must traverse the shadower
        traverse(&node,&cv);

    cv.popStateSet();

}

// set up a light source with the shadower and shodower subgraphs below it
// with the appropriate callbacks set up.
osg::Group* createShadowedScene(osg::Node* shadower,osg::Node* shadowed,const osg::Vec3& lightPosition,float radius,unsigned int textureUnit)
{
    osg::LightSource* lightgroup = new osg::LightSource;

    osg::Light* light = new osg::Light;
    light->setPosition(osg::Vec4(lightPosition,1.0f));
    light->setLightNum(0);

    lightgroup->setLight(light);

    osg::Vec4 ambientLightColor(0.2,0.2f,0.2f,1.0f);

    // add the shadower
    lightgroup->addChild(shadower);

    // add the shadowed with the callback to generate the shadow texture.
    shadowed->setCullCallback(new CreateShadowTextureCullCallback(shadower,lightPosition,ambientLightColor,textureUnit));
    lightgroup->addChild(shadowed);

    osg::Geode* lightgeode = new osg::Geode;
    lightgeode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
    lightgeode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(lightPosition,radius)));

    lightgroup->addChild(lightgeode);

    return lightgroup;
}

<|endoftext|>


<commit_before>#include "simplerendering.hpp"
#include <glutils/baseshader.hpp>
#include <glutils/uniform.hpp>
#include <gl_core_3_3.h>
#include <iostream>
#include <gimgui/logic/attributepopulator.hpp>
#include <gimgui/logic/allpropagator.hpp>
#include <gimgui/logic/absolutemap.hpp>
#include <helpers/vec2.hpp>
#include <helpers/color.hpp>
#include <glutils/projection.hpp>
#include <GLFW/glfw3.h>
#include <window.hpp>

SimpleRendering::SimpleRendering(const Vec2& viewSize):
    mQuit(false),
    mTriangles(Buffer::ARRAY_BUFFER),
    mColors(Buffer::ARRAY_BUFFER),
    mGui(
    {
        gim::Element({"container"},
        {
            {"color",    Color({140, 35, 24})},
            {"position", Vec2({200, 150})},
            {"size",     Vec2({400, 300})}
        },
        {
            gim::Element({"child"},
            {
                {"color",    Color({94, 140, 106})},
                {"position", Vec2({20, 20})},
                {"size",     Vec2({50, 50})}
            }),
            gim::Element({"child"},
            {
                {"color",    Color({136, 166, 94})},
                {"position", Vec2({90, 20})},
                {"size",     Vec2({50, 50})}
            }),
            gim::Element({"child"},
            {
                {"color",    Color({191, 179, 90})},
                {"position", Vec2({20, 90})},
                {"size",     Vec2({120, 50})}
            })
        })
    })
{
    //rendering
    mVao.bind();

    mTriangles.bind();

    mTriangles.setData(std::vector<float>(
    {
        -1.0f,  1.0f, 0.0f,
         1.0f, -1.0f, 0.0f,
         1.0f,  1.0f, 0.0f
    }));

    mColors.bind();

    mColors.setData(std::vector<float>(
    {
         1.0f,  1.0f, 0.0f,
         1.0f,  0.0f, 1.0f,
         0.0f,  1.0f, 1.0f
    }));

    mVao.setVertexAttribute(0, 3, mTriangles);
    mVao.setVertexAttribute(1, 3, mColors);

    mVao.unbind();

    mBaseShader.setSource(BaseShader::vertexSource, BaseShader::fragmentSource);
    mBaseShader.compile();

    Projection proj;
    mProjection = proj.createOrthoProjection(0.0f, (GLfloat)viewSize.x, 0.0f, (GLfloat)viewSize.y, 0.000000001f, 100.0f);
}

void SimpleRendering::loop()
{
    //guiing
    gim::AllPropagator all(mGui.root());

    std::vector<float> triangles;
    std::vector<float> colors;
    gim::Element* element;

    gim::AbsoluteMap<Vec2> absolutePositions("position");

    while((element = all.next()))
    {
        const Vec2& position = absolutePositions.getAbsoluteOf(*element);
        const Vec2& size = element->getAttribute<Vec2>("size");
        std::vector<float> triangle(
        {
            (float)position.x         ,  (float)position.y         , 0.0f,
            (float)position.x         ,  (float)position.y + size.y, 0.0f,
            (float)position.x + size.x,  (float)position.y + size.y, 0.0f,
            (float)position.x         ,  (float)position.y         , 0.0f,
            (float)position.x + size.x,  (float)position.y         , 0.0f,
            (float)position.x + size.x,  (float)position.y + size.y, 0.0f
        });

        triangles.insert(triangles.end(), triangle.begin(), triangle.end());

        const Color& color = element->getAttribute<Color>("color");

        std::vector<float> colorList(
        {
            color.r / 255.0f, color.g / 255.0f, color.b / 255.0f,
            color.r / 255.0f, color.g / 255.0f, color.b / 255.0f,
            color.r / 255.0f, color.g / 255.0f, color.b / 255.0f,
            color.r / 255.0f, color.g / 255.0f, color.b / 255.0f,
            color.r / 255.0f, color.g / 255.0f, color.b / 255.0f,
            color.r / 255.0f, color.g / 255.0f, color.b / 255.0f
        });

        colors.insert(colors.end(), colorList.begin(), colorList.end());
    }

    mTriangles.setData(triangles);
    mColors.setData(colors);

    //rendering
    mVao.bind();
    mBaseShader.activate();
    mBaseShader.setUniform("projection", UniformType::MAT4X4, &mProjection[0]);

    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glDrawArrays(GL_TRIANGLES, 0, mTriangles.getElementAmount());
}

void SimpleRendering::setViewSize(const Vec2& viewSize)
{
    Projection proj;
    mProjection = proj.createOrthoProjection(0.0f, (GLfloat)viewSize.x, 0.0f, (GLfloat)viewSize.y, 0.000000001f, 100.0f);
}

void SimpleRendering::keyEvent(int32_t key)
{
    if(key == GLFW_KEY_ESCAPE)
        quit();
}

bool SimpleRendering::isTerminated() const
{
    return mQuit;
}

void SimpleRendering::handleEvents(const Events& events)
{
    for(auto newSize : events.resizeEvents)
    {
        setViewSize(newSize);
    }

    for(int32_t key : events.keyEvents)
    {
        if(key == GLFW_KEY_ESCAPE)
            quit();
        else if(key == GLFW_KEY_D)
        {
            Vec2 pos = mGui.root().getAttribute<Vec2>("position") + Vec2({20, 20});
            mGui.root().setAttribute("position", pos);
        }
    }
}

void SimpleRendering::quit()
{
    mQuit = true;
}
<commit_msg>Now using renderdatagenerator<commit_after>#include "simplerendering.hpp"
#include <glutils/baseshader.hpp>
#include <glutils/uniform.hpp>
#include <gl_core_3_3.h>
#include <iostream>
#include <gimgui/logic/renderdatagenerator.hpp>
#include <helpers/vec2.hpp>
#include <helpers/color.hpp>
#include <glutils/projection.hpp>
#include <GLFW/glfw3.h>
#include <window.hpp>

SimpleRendering::SimpleRendering(const Vec2& viewSize):
    mQuit(false),
    mTriangles(Buffer::ARRAY_BUFFER),
    mColors(Buffer::ARRAY_BUFFER),
    mGui(
    {
        gim::Element({"container"},
        {
            {"color",    Color({140, 35, 24})},
            {"position", Vec2({200, 150})},
            {"size",     Vec2({400, 300})}
        },
        {
            gim::Element({"child"},
            {
                {"color",    Color({94, 140, 106})},
                {"position", Vec2({20, 20})},
                {"size",     Vec2({50, 50})}
            }),
            gim::Element({"child"},
            {
                {"color",    Color({136, 166, 94})},
                {"position", Vec2({90, 20})},
                {"size",     Vec2({50, 50})}
            }),
            gim::Element({"child"},
            {
                {"color",    Color({191, 179, 90})},
                {"position", Vec2({20, 90})},
                {"size",     Vec2({120, 50})}
            })
        })
    })
{
    //rendering
    mVao.bind();

    mTriangles.bind();

    mTriangles.setData(std::vector<float>(
    {
        -1.0f,  1.0f, 0.0f,
         1.0f, -1.0f, 0.0f,
         1.0f,  1.0f, 0.0f
    }));

    mColors.bind();

    mColors.setData(std::vector<float>(
    {
         1.0f,  1.0f, 0.0f,
         1.0f,  0.0f, 1.0f,
         0.0f,  1.0f, 1.0f
    }));

    mVao.setVertexAttribute(0, 3, mTriangles);
    mVao.setVertexAttribute(1, 3, mColors);

    mVao.unbind();

    mBaseShader.setSource(BaseShader::vertexSource, BaseShader::fragmentSource);
    mBaseShader.compile();

    Projection proj;
    mProjection = proj.createOrthoProjection(0.0f, (GLfloat)viewSize.x, 0.0f, (GLfloat)viewSize.y, 0.000000001f, 100.0f);
}

void SimpleRendering::loop()
{
    //guiing
    gim::RenderDataGenerator<Vec2, Color> generator;

    auto renderDatas = generator.generate(mGui.root());

    //rendering
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    mVao.bind();
    mBaseShader.activate();
    mBaseShader.setUniform("projection", UniformType::MAT4X4, &mProjection[0]);

    for(auto renderData : renderDatas)
    {
        mTriangles.setData(renderData.positions);
        mColors.setData(renderData.colors);

        glDrawArrays(GL_TRIANGLES, 0, mTriangles.getElementAmount());
    }
}

void SimpleRendering::setViewSize(const Vec2& viewSize)
{
    Projection proj;
    mProjection = proj.createOrthoProjection(0.0f, (GLfloat)viewSize.x, 0.0f, (GLfloat)viewSize.y, 0.000000001f, 100.0f);
}

void SimpleRendering::keyEvent(int32_t key)
{
    if(key == GLFW_KEY_ESCAPE)
        quit();
}

bool SimpleRendering::isTerminated() const
{
    return mQuit;
}

void SimpleRendering::handleEvents(const Events& events)
{
    for(auto newSize : events.resizeEvents)
    {
        setViewSize(newSize);
    }

    for(int32_t key : events.keyEvents)
    {
        if(key == GLFW_KEY_ESCAPE)
            quit();
        else if(key == GLFW_KEY_D)
        {
            Vec2 pos = mGui.root().getAttribute<Vec2>("position") + Vec2({20, 20});
            mGui.root().setAttribute("position", pos);
        }
    }
}

void SimpleRendering::quit()
{
    mQuit = true;
}
<|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 */

#include <numeric>
#include <thread>

#include <adios2.h>
#include <adios2/common/ADIOSMacros.h>
#include <adios2/helper/adiosFunctions.h>
#include <gtest/gtest.h>

using namespace adios2;

size_t print_lines = 0;
size_t to_print_lines = 10;

template <class T>
void GenData(std::vector<std::complex<T>> &data, const size_t step)
{
    for (size_t i = 0; i < data.size(); ++i)
    {
        data[i] = {static_cast<T>(i + 10000 + step * 100),
                   static_cast<T>(i + 10000)};
    }
}

template <class T>
void GenData(std::vector<T> &data, const size_t step)
{
    for (size_t i = 0; i < data.size(); ++i)
    {
        data[i] = i + 10000 + step * 100;
    }
}

template <class T>
void PrintData(const T *data, const size_t size, const size_t step)
{
    std::cout << "Step: " << step << " [";
    size_t printsize = 32;
    if (size < printsize)
    {
        printsize = size;
    }
    for (size_t i = 0; i < printsize; ++i)
    {
        std::cout << data[i] << " ";
    }
    std::cout << "]" << std::endl;
}

template <class T>
void VerifyData(const std::complex<T> *data, const size_t size, size_t step)
{
    std::vector<std::complex<T>> tmpdata(size);
    GenData(tmpdata, step);
    for (size_t i = 0; i < size; ++i)
    {
        ASSERT_EQ(data[i], tmpdata[i]);
    }
}

template <class T>
void VerifyData(const T *data, const size_t size, size_t step)
{
    std::vector<T> tmpdata(size);
    GenData(tmpdata, step);
    for (size_t i = 0; i < size; ++i)
    {
        ASSERT_EQ(data[i], tmpdata[i]);
    }
}

template <class T>
void VerifyData(const std::vector<T> &data, const size_t step)
{
    VerifyData(data.data(), data.size(), step);
}

void DataManWriter(const Dims &shape, const Dims &start, const Dims &count,
                   const size_t steps, const adios2::Params &engineParams)
{
    size_t datasize = std::accumulate(count.begin(), count.end(), 1,
                                      std::multiplies<size_t>());
    adios2::ADIOS adios;
    adios2::IO dataManIO = adios.DeclareIO("WAN");
    dataManIO.SetEngine("DataMan");
    dataManIO.SetParameters(engineParams);
    std::vector<char> myChars(datasize);
    std::vector<unsigned char> myUChars(datasize);
    std::vector<short> myShorts(datasize);
    std::vector<unsigned short> myUShorts(datasize);
    std::vector<int> myInts(datasize);
    std::vector<unsigned int> myUInts(datasize);
    std::vector<float> myFloats(datasize);
    std::vector<double> myDoubles(datasize);
    std::vector<std::complex<float>> myComplexes(datasize);
    std::vector<std::complex<double>> myDComplexes(datasize);
    auto bpChars =
        dataManIO.DefineVariable<char>("bpChars", shape, start, count);
    auto bpUChars = dataManIO.DefineVariable<unsigned char>("bpUChars", shape,
                                                            start, count);
    auto bpShorts =
        dataManIO.DefineVariable<short>("bpShorts", shape, start, count);
    auto bpUShorts = dataManIO.DefineVariable<unsigned short>(
        "bpUShorts", shape, start, count);
    auto bpInts = dataManIO.DefineVariable<int>("bpInts", shape, start, count);
    auto bpUInts =
        dataManIO.DefineVariable<unsigned int>("bpUInts", shape, start, count);
    auto bpFloats =
        dataManIO.DefineVariable<float>("bpFloats", shape, start, count);
    auto bpDoubles =
        dataManIO.DefineVariable<double>("bpDoubles", shape, start, count);
    auto bpComplexes = dataManIO.DefineVariable<std::complex<float>>(
        "bpComplexes", shape, start, count);
    auto bpDComplexes = dataManIO.DefineVariable<std::complex<double>>(
        "bpDComplexes", shape, start, count);
    auto bpUInt64s = dataManIO.DefineVariable<uint64_t>("bpUInt64s");
    dataManIO.DefineAttribute<int>("AttInt", 110);
    adios2::Engine dataManWriter =
        dataManIO.Open("stream", adios2::Mode::Write);
    for (uint64_t i = 0; i < steps; ++i)
    {
        dataManWriter.BeginStep();
        GenData(myChars, i);
        GenData(myUChars, i);
        GenData(myShorts, i);
        GenData(myUShorts, i);
        GenData(myInts, i);
        GenData(myUInts, i);
        GenData(myFloats, i);
        GenData(myDoubles, i);
        GenData(myComplexes, i);
        GenData(myDComplexes, i);
        dataManWriter.Put(bpChars, myChars.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUChars, myUChars.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpShorts, myShorts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUShorts, myUShorts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpInts, myInts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUInts, myUInts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpFloats, myFloats.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpDoubles, myDoubles.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpComplexes, myComplexes.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpDComplexes, myDComplexes.data(),
                          adios2::Mode::Sync);
        dataManWriter.Put(bpUInt64s, i);
        dataManWriter.EndStep();
    }
    dataManWriter.Close();
}

void DataManReader(const Dims &shape, const Dims &start, const Dims &count,
                   const size_t steps, const adios2::Params &engineParams)
{
    size_t datasize = std::accumulate(count.begin(), count.end(), 1,
                                      std::multiplies<size_t>());
    adios2::ADIOS adios;
    adios2::IO dataManIO = adios.DeclareIO("WAN");
    dataManIO.SetEngine("DataMan");
    dataManIO.SetParameters(engineParams);
    adios2::Engine dataManReader = dataManIO.Open("stream", adios2::Mode::Read);

    std::vector<char> myChars(datasize);
    std::vector<unsigned char> myUChars(datasize);
    std::vector<short> myShorts(datasize);
    std::vector<unsigned short> myUShorts(datasize);
    std::vector<int> myInts(datasize);
    std::vector<unsigned int> myUInts(datasize);
    std::vector<float> myFloats(datasize);
    std::vector<double> myDoubles(datasize);
    std::vector<std::complex<float>> myComplexes(datasize);
    std::vector<std::complex<double>> myDComplexes(datasize);
    bool received_steps = false;
    size_t currentStep;
    while (true)
    {
        adios2::StepStatus status = dataManReader.BeginStep(StepMode::Read, 5);
        if (status == adios2::StepStatus::OK)
        {
            received_steps = true;
            const auto &vars = dataManIO.AvailableVariables();
            ASSERT_EQ(vars.size(), 11);
            currentStep = dataManReader.CurrentStep();
            adios2::Variable<char> bpChars =
                dataManIO.InquireVariable<char>("bpChars");
            adios2::Variable<unsigned char> bpUChars =
                dataManIO.InquireVariable<unsigned char>("bpUChars");
            adios2::Variable<short> bpShorts =
                dataManIO.InquireVariable<short>("bpShorts");
            adios2::Variable<unsigned short> bpUShorts =
                dataManIO.InquireVariable<unsigned short>("bpUShorts");
            adios2::Variable<int> bpInts =
                dataManIO.InquireVariable<int>("bpInts");
            adios2::Variable<unsigned int> bpUInts =
                dataManIO.InquireVariable<unsigned int>("bpUInts");
            adios2::Variable<float> bpFloats =
                dataManIO.InquireVariable<float>("bpFloats");
            adios2::Variable<double> bpDoubles =
                dataManIO.InquireVariable<double>("bpDoubles");
            adios2::Variable<std::complex<float>> bpComplexes =
                dataManIO.InquireVariable<std::complex<float>>("bpComplexes");
            adios2::Variable<std::complex<double>> bpDComplexes =
                dataManIO.InquireVariable<std::complex<double>>("bpDComplexes");
            adios2::Variable<uint64_t> bpUInt64s =
                dataManIO.InquireVariable<uint64_t>("bpUInt64s");
            auto charsBlocksInfo = dataManReader.AllStepsBlocksInfo(bpChars);
            bpChars.SetSelection({start, count});
            bpUChars.SetSelection({start, count});
            bpShorts.SetSelection({start, count});
            bpUShorts.SetSelection({start, count});
            bpInts.SetSelection({start, count});
            bpUInts.SetSelection({start, count});
            bpFloats.SetSelection({start, count});
            bpDoubles.SetSelection({start, count});
            bpComplexes.SetSelection({start, count});
            bpDComplexes.SetSelection({start, count});
            dataManReader.Get(bpChars, myChars.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUChars, myUChars.data(), adios2::Mode::Sync);
            dataManReader.Get(bpShorts, myShorts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUShorts, myUShorts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpInts, myInts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUInts, myUInts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpFloats, myFloats.data(), adios2::Mode::Sync);
            dataManReader.Get(bpDoubles, myDoubles.data(), adios2::Mode::Sync);
            dataManReader.Get(bpComplexes, myComplexes.data(),
                              adios2::Mode::Sync);
            dataManReader.Get(bpDComplexes, myDComplexes.data(),
                              adios2::Mode::Sync);
            uint64_t stepValue;
            dataManReader.Get(bpUInt64s, &stepValue, adios2::Mode::Sync);
            ASSERT_EQ(currentStep, stepValue);
            VerifyData(myChars, currentStep);
            VerifyData(myUChars, currentStep);
            VerifyData(myShorts, currentStep);
            VerifyData(myUShorts, currentStep);
            VerifyData(myInts, currentStep);
            VerifyData(myUInts, currentStep);
            VerifyData(myFloats, currentStep);
            VerifyData(myDoubles, currentStep);
            VerifyData(myComplexes, currentStep);
            VerifyData(myDComplexes, currentStep);
            dataManReader.EndStep();
        }
        else if (status == adios2::StepStatus::EndOfStream)
        {
            break;
        }
        else if (status == adios2::StepStatus::NotReady)
        {
            continue;
        }
    }
    if (received_steps)
    {
        auto attInt = dataManIO.InquireAttribute<int>("AttInt");
        ASSERT_EQ(110, attInt.Data()[0]);
        ASSERT_NE(111, attInt.Data()[0]);
    }
    dataManReader.Close();
}

class DataManEngineTest : public ::testing::Test
{
public:
    DataManEngineTest() = default;
};

#ifdef ADIOS2_HAVE_ZEROMQ
TEST_F(DataManEngineTest, 1DSuperLarge)
{
    // set parameters
    Dims shape = {200000};
    Dims start = {0};
    Dims count = {200000};
    size_t steps = 10;

    // run workflow
    adios2::Params readerEngineParams = {{"IPAddress", "127.0.0.1"},
                                         {"Port", "13480"},
                                         {"MaxStepBufferSize", "20000000"},
                                         {"TransportMode", "reliable"}};
    auto r = std::thread(DataManReader, shape, start, count, steps,
                         readerEngineParams);
    adios2::Params writerEngineParams = {{"IPAddress", "127.0.0.1"},
                                         {"Port", "13480"},
                                         {"TransportMode", "reliable"}};
    auto w = std::thread(DataManWriter, shape, start, count, steps,
                         writerEngineParams);
    w.join();
    r.join();
}
#endif // ZEROMQ

int main(int argc, char **argv)
{
    int result;
    ::testing::InitGoogleTest(&argc, argv);
    result = RUN_ALL_TESTS();

    return result;
}
<commit_msg>reduced buffer size to make memory sanitizer happy<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 */

#include <numeric>
#include <thread>

#include <adios2.h>
#include <adios2/common/ADIOSMacros.h>
#include <adios2/helper/adiosFunctions.h>
#include <gtest/gtest.h>

using namespace adios2;

size_t print_lines = 0;
size_t to_print_lines = 10;

template <class T>
void GenData(std::vector<std::complex<T>> &data, const size_t step)
{
    for (size_t i = 0; i < data.size(); ++i)
    {
        data[i] = {static_cast<T>(i + 10000 + step * 100),
                   static_cast<T>(i + 10000)};
    }
}

template <class T>
void GenData(std::vector<T> &data, const size_t step)
{
    for (size_t i = 0; i < data.size(); ++i)
    {
        data[i] = i + 10000 + step * 100;
    }
}

template <class T>
void PrintData(const T *data, const size_t size, const size_t step)
{
    std::cout << "Step: " << step << " [";
    size_t printsize = 32;
    if (size < printsize)
    {
        printsize = size;
    }
    for (size_t i = 0; i < printsize; ++i)
    {
        std::cout << data[i] << " ";
    }
    std::cout << "]" << std::endl;
}

template <class T>
void VerifyData(const std::complex<T> *data, const size_t size, size_t step)
{
    std::vector<std::complex<T>> tmpdata(size);
    GenData(tmpdata, step);
    for (size_t i = 0; i < size; ++i)
    {
        ASSERT_EQ(data[i], tmpdata[i]);
    }
}

template <class T>
void VerifyData(const T *data, const size_t size, size_t step)
{
    std::vector<T> tmpdata(size);
    GenData(tmpdata, step);
    for (size_t i = 0; i < size; ++i)
    {
        ASSERT_EQ(data[i], tmpdata[i]);
    }
}

template <class T>
void VerifyData(const std::vector<T> &data, const size_t step)
{
    VerifyData(data.data(), data.size(), step);
}

void DataManWriter(const Dims &shape, const Dims &start, const Dims &count,
                   const size_t steps, const adios2::Params &engineParams)
{
    size_t datasize = std::accumulate(count.begin(), count.end(), 1,
                                      std::multiplies<size_t>());
    adios2::ADIOS adios;
    adios2::IO dataManIO = adios.DeclareIO("WAN");
    dataManIO.SetEngine("DataMan");
    dataManIO.SetParameters(engineParams);
    std::vector<char> myChars(datasize);
    std::vector<unsigned char> myUChars(datasize);
    std::vector<short> myShorts(datasize);
    std::vector<unsigned short> myUShorts(datasize);
    std::vector<int> myInts(datasize);
    std::vector<unsigned int> myUInts(datasize);
    std::vector<float> myFloats(datasize);
    std::vector<double> myDoubles(datasize);
    std::vector<std::complex<float>> myComplexes(datasize);
    std::vector<std::complex<double>> myDComplexes(datasize);
    auto bpChars =
        dataManIO.DefineVariable<char>("bpChars", shape, start, count);
    auto bpUChars = dataManIO.DefineVariable<unsigned char>("bpUChars", shape,
                                                            start, count);
    auto bpShorts =
        dataManIO.DefineVariable<short>("bpShorts", shape, start, count);
    auto bpUShorts = dataManIO.DefineVariable<unsigned short>(
        "bpUShorts", shape, start, count);
    auto bpInts = dataManIO.DefineVariable<int>("bpInts", shape, start, count);
    auto bpUInts =
        dataManIO.DefineVariable<unsigned int>("bpUInts", shape, start, count);
    auto bpFloats =
        dataManIO.DefineVariable<float>("bpFloats", shape, start, count);
    auto bpDoubles =
        dataManIO.DefineVariable<double>("bpDoubles", shape, start, count);
    auto bpComplexes = dataManIO.DefineVariable<std::complex<float>>(
        "bpComplexes", shape, start, count);
    auto bpDComplexes = dataManIO.DefineVariable<std::complex<double>>(
        "bpDComplexes", shape, start, count);
    auto bpUInt64s = dataManIO.DefineVariable<uint64_t>("bpUInt64s");
    dataManIO.DefineAttribute<int>("AttInt", 110);
    adios2::Engine dataManWriter =
        dataManIO.Open("stream", adios2::Mode::Write);
    for (uint64_t i = 0; i < steps; ++i)
    {
        dataManWriter.BeginStep();
        GenData(myChars, i);
        GenData(myUChars, i);
        GenData(myShorts, i);
        GenData(myUShorts, i);
        GenData(myInts, i);
        GenData(myUInts, i);
        GenData(myFloats, i);
        GenData(myDoubles, i);
        GenData(myComplexes, i);
        GenData(myDComplexes, i);
        dataManWriter.Put(bpChars, myChars.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUChars, myUChars.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpShorts, myShorts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUShorts, myUShorts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpInts, myInts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpUInts, myUInts.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpFloats, myFloats.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpDoubles, myDoubles.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpComplexes, myComplexes.data(), adios2::Mode::Sync);
        dataManWriter.Put(bpDComplexes, myDComplexes.data(),
                          adios2::Mode::Sync);
        dataManWriter.Put(bpUInt64s, i);
        dataManWriter.EndStep();
    }
    dataManWriter.Close();
}

void DataManReader(const Dims &shape, const Dims &start, const Dims &count,
                   const size_t steps, const adios2::Params &engineParams)
{
    size_t datasize = std::accumulate(count.begin(), count.end(), 1,
                                      std::multiplies<size_t>());
    adios2::ADIOS adios;
    adios2::IO dataManIO = adios.DeclareIO("WAN");
    dataManIO.SetEngine("DataMan");
    dataManIO.SetParameters(engineParams);
    adios2::Engine dataManReader = dataManIO.Open("stream", adios2::Mode::Read);

    std::vector<char> myChars(datasize);
    std::vector<unsigned char> myUChars(datasize);
    std::vector<short> myShorts(datasize);
    std::vector<unsigned short> myUShorts(datasize);
    std::vector<int> myInts(datasize);
    std::vector<unsigned int> myUInts(datasize);
    std::vector<float> myFloats(datasize);
    std::vector<double> myDoubles(datasize);
    std::vector<std::complex<float>> myComplexes(datasize);
    std::vector<std::complex<double>> myDComplexes(datasize);
    bool received_steps = false;
    size_t currentStep;
    while (true)
    {
        adios2::StepStatus status = dataManReader.BeginStep(StepMode::Read, 5);
        if (status == adios2::StepStatus::OK)
        {
            received_steps = true;
            const auto &vars = dataManIO.AvailableVariables();
            ASSERT_EQ(vars.size(), 11);
            currentStep = dataManReader.CurrentStep();
            adios2::Variable<char> bpChars =
                dataManIO.InquireVariable<char>("bpChars");
            adios2::Variable<unsigned char> bpUChars =
                dataManIO.InquireVariable<unsigned char>("bpUChars");
            adios2::Variable<short> bpShorts =
                dataManIO.InquireVariable<short>("bpShorts");
            adios2::Variable<unsigned short> bpUShorts =
                dataManIO.InquireVariable<unsigned short>("bpUShorts");
            adios2::Variable<int> bpInts =
                dataManIO.InquireVariable<int>("bpInts");
            adios2::Variable<unsigned int> bpUInts =
                dataManIO.InquireVariable<unsigned int>("bpUInts");
            adios2::Variable<float> bpFloats =
                dataManIO.InquireVariable<float>("bpFloats");
            adios2::Variable<double> bpDoubles =
                dataManIO.InquireVariable<double>("bpDoubles");
            adios2::Variable<std::complex<float>> bpComplexes =
                dataManIO.InquireVariable<std::complex<float>>("bpComplexes");
            adios2::Variable<std::complex<double>> bpDComplexes =
                dataManIO.InquireVariable<std::complex<double>>("bpDComplexes");
            adios2::Variable<uint64_t> bpUInt64s =
                dataManIO.InquireVariable<uint64_t>("bpUInt64s");
            auto charsBlocksInfo = dataManReader.AllStepsBlocksInfo(bpChars);
            bpChars.SetSelection({start, count});
            bpUChars.SetSelection({start, count});
            bpShorts.SetSelection({start, count});
            bpUShorts.SetSelection({start, count});
            bpInts.SetSelection({start, count});
            bpUInts.SetSelection({start, count});
            bpFloats.SetSelection({start, count});
            bpDoubles.SetSelection({start, count});
            bpComplexes.SetSelection({start, count});
            bpDComplexes.SetSelection({start, count});
            dataManReader.Get(bpChars, myChars.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUChars, myUChars.data(), adios2::Mode::Sync);
            dataManReader.Get(bpShorts, myShorts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUShorts, myUShorts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpInts, myInts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpUInts, myUInts.data(), adios2::Mode::Sync);
            dataManReader.Get(bpFloats, myFloats.data(), adios2::Mode::Sync);
            dataManReader.Get(bpDoubles, myDoubles.data(), adios2::Mode::Sync);
            dataManReader.Get(bpComplexes, myComplexes.data(),
                              adios2::Mode::Sync);
            dataManReader.Get(bpDComplexes, myDComplexes.data(),
                              adios2::Mode::Sync);
            uint64_t stepValue;
            dataManReader.Get(bpUInt64s, &stepValue, adios2::Mode::Sync);
            ASSERT_EQ(currentStep, stepValue);
            VerifyData(myChars, currentStep);
            VerifyData(myUChars, currentStep);
            VerifyData(myShorts, currentStep);
            VerifyData(myUShorts, currentStep);
            VerifyData(myInts, currentStep);
            VerifyData(myUInts, currentStep);
            VerifyData(myFloats, currentStep);
            VerifyData(myDoubles, currentStep);
            VerifyData(myComplexes, currentStep);
            VerifyData(myDComplexes, currentStep);
            dataManReader.EndStep();
        }
        else if (status == adios2::StepStatus::EndOfStream)
        {
            break;
        }
        else if (status == adios2::StepStatus::NotReady)
        {
            continue;
        }
    }
    if (received_steps)
    {
        auto attInt = dataManIO.InquireAttribute<int>("AttInt");
        ASSERT_EQ(110, attInt.Data()[0]);
        ASSERT_NE(111, attInt.Data()[0]);
    }
    dataManReader.Close();
}

class DataManEngineTest : public ::testing::Test
{
public:
    DataManEngineTest() = default;
};

#ifdef ADIOS2_HAVE_ZEROMQ
TEST_F(DataManEngineTest, 1DSuperLarge)
{
    // set parameters
    Dims shape = {100000};
    Dims start = {0};
    Dims count = {100000};
    size_t steps = 10;

    // run workflow
    adios2::Params readerEngineParams = {{"IPAddress", "127.0.0.1"},
                                         {"Port", "13480"},
                                         {"MaxStepBufferSize", "10000000"},
                                         {"TransportMode", "reliable"}};
    auto r = std::thread(DataManReader, shape, start, count, steps,
                         readerEngineParams);
    adios2::Params writerEngineParams = {{"IPAddress", "127.0.0.1"},
                                         {"Port", "13480"},
                                         {"TransportMode", "reliable"}};
    auto w = std::thread(DataManWriter, shape, start, count, steps,
                         writerEngineParams);
    w.join();
    r.join();
}
#endif // ZEROMQ

int main(int argc, char **argv)
{
    int result;
    ::testing::InitGoogleTest(&argc, argv);
    result = RUN_ALL_TESTS();

    return result;
}
<|endoftext|>


<commit_before>/*=============================================================================
# Filename: CppAPIExample.cpp
# Author: Bookug Lobert
# Mail: 1181955272@qq.com
# Last Modified: 2016-02-21 21:32
# Description: originally written by hanshuo, modified by zengli
=============================================================================*/

#include "GstoreConnector.h"
#include <string>
#include <iostream>
using namespace std;
// before run this example, you must start up the GStore server at first (use command ./gserver).
int main(int argc, char * argv[])
{
    // initialize the GStore server's IP address and port.
    cout << "in" <<endl;
    GstoreConnector gc("172.31.222.93", 9016);
    cout << "out"<<endl;
    // build a new database by a RDF file.
    // note that the relative path is related to gserver

	gc.build("test", "data/lubm/LUBM_10.n3", "root", "123456");

	//load the database that you've build.
	gc.load("test", "root", "123456");
    // then you can execute SPARQL query on this database.
    std::string sparql = "select ?x where \
                         { \
                         ?x    <rdf:type>    <ub:UndergraduateStudent>. \
                         ?y    <ub:name> <Course1>. \
                         ?x    <ub:takesCourse>  ?y. \
                         ?z    <ub:teacherOf>    ?y. \
                         ?z    <ub:name> <FullProfessor1>. \
                         ?z    <ub:worksFor>    ?w. \
                         ?w    <ub:name>    <Department0>. \
                         }";
    std::string answer = gc.query("root", "123456", "test", sparql);
    std::cout << answer << std::endl;

    // unload this database.
    gc.unload("test", "root", "123456");
    // also, you can load some exist database directly and then query.
    gc.load("lubm", "root", "123456");
    answer = gc.query("root", "123456", "lubm", sparql);
    std::cout << answer << std::endl;

	//you can monitor a database
	answer = gc.monitor("lubm");
	std::cout << answer << std::endl;

	//add a user(with username: Jack, password: 2)
	answer = gc.user("add_user", "root", "123456", "Jack", "2");
	std::cout << answer << std::endl;

	//add privilege to user Jack(add_query, add_load, add_unload)
	answer = gc.user("add_query", "root", "123456", "Jack", "lubm");
	std::cout << answer << std::endl;

	//then Jack can query the database LUBM10
	answer = gc.query("Jack", "2", "lubm", sparql);
	std::cout << answer << std::endl;

	//delete privilege of user Jack(delete_query, delete_load, delete_unload)
	answer = gc.user("delete_query", "root", "123456", "Jack", "lubm");
	std::cout << answer << std::endl;

	//delete user(with username: Jack, password: 2)
	answer = gc.user("delete_user", "root", "123456", "Jack", "2");
	std::cout << answer << std::endl;

	gc.unload("lubm", "root", "123456");

	return 0;
}

<commit_msg>add an example of new query funtion<commit_after>/*=============================================================================
# Filename: CppAPIExample.cpp
# Author: Bookug Lobert
# Mail: 1181955272@qq.com
# Last Modified: 2016-02-21 21:32
# Description: originally written by hanshuo, modified by zengli
=============================================================================*/

#include "GstoreConnector.h"
#include <string>
#include <iostream>
using namespace std;
// before run this example, you must start up the GStore server at first (use command ./gserver).
int main(int argc, char * argv[])
{
    // initialize the GStore server's IP address and port.
    cout << "in" <<endl;
    GstoreConnector gc("172.31.222.93", 9016);
    cout << "out"<<endl;
    // build a new database by a RDF file.
    // note that the relative path is related to gserver

	gc.build("test", "data/lubm/LUBM_10.n3", "root", "123456");

	//load the database that you've build.
	gc.load("test", "root", "123456");
    // then you can execute SPARQL query on this database.
    std::string sparql = "select ?x where \
                         { \
                         ?x    <rdf:type>    <ub:UndergraduateStudent>. \
                         ?y    <ub:name> <Course1>. \
                         ?x    <ub:takesCourse>  ?y. \
                         ?z    <ub:teacherOf>    ?y. \
                         ?z    <ub:name> <FullProfessor1>. \
                         ?z    <ub:worksFor>    ?w. \
                         ?w    <ub:name>    <Department0>. \
                         }";
    std::string answer = gc.query("root", "123456", "test", sparql);
    std::cout << answer << std::endl;

    // make a SPARQL query and save the result in ans.txt
    gc.query("root", "123456", "test", sparql, "ans.txt");

    // unload this database.
    gc.unload("test", "root", "123456");
    // also, you can load some exist database directly and then query.
    gc.load("lubm", "root", "123456");
    answer = gc.query("root", "123456", "lubm", sparql);
    std::cout << answer << std::endl;

	//you can monitor a database
	answer = gc.monitor("lubm");
	std::cout << answer << std::endl;

	//add a user(with username: Jack, password: 2)
	answer = gc.user("add_user", "root", "123456", "Jack", "2");
	std::cout << answer << std::endl;

	//add privilege to user Jack(add_query, add_load, add_unload)
	answer = gc.user("add_query", "root", "123456", "Jack", "lubm");
	std::cout << answer << std::endl;

	//then Jack can query the database LUBM10
	answer = gc.query("Jack", "2", "lubm", sparql);
	std::cout << answer << std::endl;

	//delete privilege of user Jack(delete_query, delete_load, delete_unload)
	answer = gc.user("delete_query", "root", "123456", "Jack", "lubm");
	std::cout << answer << std::endl;

	//delete user(with username: Jack, password: 2)
	answer = gc.user("delete_user", "root", "123456", "Jack", "2");
	std::cout << answer << std::endl;

	gc.unload("lubm", "root", "123456");

	return 0;
}

<|endoftext|>