Пример #1
0
        service::~service()
        {
            INVARIANT(_thread);
            INVARIANT(_mail);

            if(!_done) stop();
        }
Пример #2
0
 chat_app::~chat_app()
 {
     INVARIANT(_conversation_service);
     INVARIANT(_conversation);
     INVARIANT(_mail_service);
     _mail_service->done();
 }
Пример #3
0
void  stream_write(stream_content&  content, index const  begin, byte const* const  data_begin, size const  num_bytes)
{
    index  num_output_bytes = 0ULL;
    index  page_begin = begin & ~(stream_page_size - 1ULL);
    index  page_offset = begin - page_begin;

    while (num_output_bytes < num_bytes)
    {
        size const  num_bytes_to_copy = std::min(stream_page_size - page_offset,num_bytes - num_output_bytes);

        stream_page&  page = content[page_begin];

        INVARIANT(num_bytes_to_copy > 0ULL);
        INVARIANT(page_offset + num_bytes_to_copy <= stream_page_size);
        std::copy(data_begin + num_output_bytes,
                  data_begin + num_output_bytes + num_bytes_to_copy,
                  page.data() + page_offset
                  );

        page_begin += stream_page_size;
        page_offset = 0ULL;
        num_output_bytes += num_bytes_to_copy;
    }

    INVARIANT(num_output_bytes == num_bytes);
}
Пример #4
0
            void script_app::clone_app()
            {
                INVARIANT(_app_service);
                INVARIANT(_app);

                install_app_gui(*_app, *_app_service, this);
            }
Пример #5
0
            void chat_app::send_message()
            {
                INVARIANT(_message);
                INVARIANT(_send);
                INVARIANT(_conversation);

                auto text = gui::convert(_message->text());

                ///don't send empty messages
                u::trim(text);
                if(text.empty()) return;

                //update gui
                _message->clear();
                auto self = _conversation->user_service()->user().info().name();
                add_text(make_message_str("blue", self, text));

                //send the message 
                _clock++;

                text_message tm;
                tm.text = text;
                tm.clock = _clock;

                send_all(tm.to_message());
                if(_conversation->contacts().list().empty()) add_text(make_message_str("red", "notice", "nobody here..."));
            }
Пример #6
0
        void session_widget::update_contact_select()
        {
            INVARIANT(_contact_select);
            INVARIANT(_session_service);
            INVARIANT(_session);
            INVARIANT(_add_contact);
            INVARIANT(_session_service->user_service());

            _contact_select->clear();
            for(auto p : _session_service->user_service()->user().contacts().list())
            {
                CHECK(p);
                //skip contact already in session
                if(_session->contacts().by_id(p->id())) continue;

                //skip contact which is disconnected
                if(!_session_service->user_service()->contact_available(p->id())) continue;
                _contact_select->addItem(p->name().c_str(), p->id().c_str());
            }

            bool enabled = _contact_select->count() > 0;

            _contact_select->setEnabled(enabled);
            _add_contact->setEnabled(enabled);
        }
Пример #7
0
            script_app::script_app(
                    app_ptr app, 
                    app_service_ptr as,
                    s::conversation_service_ptr conversation_s,
                    s::conversation_ptr conversation) :
                generic_app{},
                _from_id{conversation->user_service()->user().info().id()},
                _id{u::uuid()},
                _conversation_service{conversation_s},
                _conversation{conversation},
                _app{app},
                _app_service{as}
            {
                REQUIRE(conversation_s);
                REQUIRE(conversation);
                REQUIRE(app);
                REQUIRE(as);

                init();

                INVARIANT(_api);
                INVARIANT(_conversation_service);
                INVARIANT(_conversation);
                INVARIANT(_app);
                INVARIANT(_app_service);
                INVARIANT_FALSE(_id.empty());
            }
Пример #8
0
        void queue_debug::update_graph()
        {
            INVARIANT(_in_graph);
            INVARIANT(_out_graph);

            auto px = _x;
            _x+=GRAPH_STEP;

            m::mailbox_stats* stats = nullptr; 
            
            if(_mailbox_stats) stats = _mailbox_stats;
            else
            {
                auto mb = _mailbox.lock();
                if(!mb) return;
                stats = &(mb->stats());
            }

            CHECK(stats);
            auto in_push = stats->in_push_count;
            auto in_pop = stats->in_pop_count;
            auto out_push = stats->out_push_count;
            auto out_pop = stats->out_pop_count;
            stats->reset();

            draw_graph(*_in_graph, px, _prev_in_push+2, _x, in_push+2, _in_max, QPen{QBrush{QColor{"red"}}, 0.5});
            draw_graph(*_in_graph, px, _prev_in_pop, _x, in_pop, _in_max, QPen{QBrush{QColor{"orange"}}, 0.5});
            draw_graph(*_out_graph, px, _prev_out_push+2, _x, out_push+2, _out_max, QPen{QBrush{QColor{"green"}}, 0.5});
            draw_graph(*_out_graph, px, _prev_out_pop, _x, out_pop, _out_max, QPen{QBrush{QColor{"blue"}}, 0.5});
                    
            _prev_in_push = in_push;
            _prev_in_pop = in_pop;
            _prev_out_push = out_push;
            _prev_out_pop = out_pop;
        }
Пример #9
0
            script_app::script_app(
                    const std::string& from_id, 
                    const std::string& id, 
                    app_ptr app, app_service_ptr as, 
                    s::conversation_service_ptr conversation_s,
                    s::conversation_ptr conversation) :
                generic_app{},
                _from_id{from_id},
                _id{id},
                _conversation_service{conversation_s},
                _conversation{conversation},
                _app{app},
                _app_service{as}
            {
                REQUIRE(conversation_s);
                REQUIRE(conversation);
                REQUIRE(app);
                REQUIRE(as);
                REQUIRE_FALSE(id.empty());

                init();

                INVARIANT(_api);
                INVARIANT(_conversation_service);
                INVARIANT(_conversation);
                INVARIANT(_app);
                INVARIANT(_app_service);
                INVARIANT_FALSE(_id.empty());
            }
Пример #10
0
void  memory_havoc(memory_content&  content, address const  begin, size const  num_bytes, byte const  value)
{
    index  num_output_bytes = 0ULL;
    address  page_begin = begin & ~(memory_page_size - 1ULL);
    index  page_offset = begin - page_begin;

    while (num_output_bytes < num_bytes)
    {
        size const  num_bytes_to_copy = std::min(memory_page_size - page_offset,num_bytes - num_output_bytes);

        memory_page&  page = content[page_begin];

        INVARIANT(num_bytes_to_copy > 0ULL);
        INVARIANT(page_offset + num_bytes_to_copy <= memory_page_size);
        std::fill(page.data() + page_offset,
                  page.data() + page_offset + num_bytes_to_copy,
                  value
                  );

        page_begin += memory_page_size;
        page_offset = 0ULL;
        num_output_bytes += num_bytes_to_copy;
    }

    INVARIANT(num_output_bytes == num_bytes);
}
Пример #11
0
void  stream_read(stream_content const&  content, index const  begin, byte* const  data_begin, size const  num_bytes)
{
    index  num_output_bytes = 0ULL;
    index  page_begin = begin & ~(stream_page_size - 1ULL);
    index  page_offset = begin - page_begin;

    while (num_output_bytes < num_bytes)
    {
        size const  num_bytes_to_copy = std::min(stream_page_size - page_offset,num_bytes - num_output_bytes);

        stream_page&  page = const_cast<stream_content&>(content)[page_begin];  //!< The const_cast is used to automatically create
                                                                                //!< a page with uninitialised data, if it is not in
                                                                                //!< the map yet.

        INVARIANT(num_bytes_to_copy > 0ULL);
        INVARIANT(page_offset + num_bytes_to_copy <= stream_page_size);
        std::copy(page.data() + page_offset,
                  page.data() + page_offset + num_bytes_to_copy,
                  data_begin + num_output_bytes);

        page_begin += stream_page_size;
        page_offset = 0ULL;
        num_output_bytes += num_bytes_to_copy;
    }

    INVARIANT(num_output_bytes == num_bytes);
}
scene_record_id_reverse_builder  scene_record_id_reverse_builder::run(
        tree_widget_item const*  tree_item,
        tree_widget_item** const  coord_system_item)
{
    ASSUMPTION(tree_item != nullptr);
    scene_record_id_reverse_builder  id_builder;
    if (represents_record(tree_item))
    {
        id_builder.m_record_name = get_tree_widget_item_name(tree_item);
        tree_item = as_tree_widget_item(tree_item->parent());
    }
    if (represents_folder(tree_item))
    {
        id_builder.m_folder_name = get_tree_widget_item_name(tree_item);
        tree_item = as_tree_widget_item(tree_item->parent());
    }
    INVARIANT(represents_coord_system(tree_item));
    if (coord_system_item != nullptr)
        *coord_system_item = const_cast<tree_widget_item*>(tree_item);
    for ( ; tree_item != nullptr; tree_item = as_tree_widget_item(tree_item->parent()))
    {
        INVARIANT(represents_coord_system(tree_item));
        id_builder.m_node_path.push_back(get_tree_widget_item_name(tree_item));
    }
    std::reverse(id_builder.m_node_path.begin(), id_builder.m_node_path.end());
    INVARIANT(!id_builder.m_node_path.empty());
    return id_builder;
}
Пример #13
0
        void contact_list_dialog::update_contacts()
        {
            INVARIANT(_list);
            INVARIANT(_service);

            _list->clear();
            _ui.clear();

            for(auto u : _service->user().contacts().list())
            {
                auto rm = make_x_button();
                std::stringstream ss;
                ss << "Remove `" << u->name() << "'";
                rm->setToolTip(ss.str().c_str());

                auto mapper = new QSignalMapper{this};
                mapper->setMapping(rm, QString(u->id().c_str()));
                connect(rm, SIGNAL(clicked()), mapper, SLOT(map()));
                connect(mapper, SIGNAL(mapped(QString)), this, SLOT(remove(QString)));

                auto ui = new user_info{u, _service, rm, false};
                _list->add(ui);
                _ui.push_back(ui);
            }

            _prev_contacts = _service->user().contacts().size();
        }
Пример #14
0
        void conversation_service::quit_conversation(const std::string& id)
        {
            u::mutex_scoped_lock l(_mutex);
            INVARIANT(_sender);
            INVARIANT(_post);

            //find conversation
            auto s = _conversations.find(id);
            if(s == _conversations.end()) return;

            CHECK(s->second);

            //send quit message to contacts in the conversation
            quit_conversation_msg ns;
            ns.conversation_id = s->second->id(); 
            auto m = ns.to_message();

            for(auto c : s->second->contacts().list())
            {
                CHECK(c);
                _sender->send(c->id(), m);
            }

            //remove conversation from map
            _conversations.erase(s);
            fire_quit_conversation_event(id);
        }
Пример #15
0
            void script_app::setup_decorations()
            {
                INVARIANT(_app);
                INVARIANT(_app_service);
                REQUIRE_FALSE(_clone);

                set_title(_app->name().c_str());

                _clone = new QPushButton;
                make_install(*_clone);

                //color the install icon depending on whether the app is already installed
                bool exists = _app_service->available_apps().count(_app->id());
                if(exists) 
                {
                    _clone->setToolTip(tr("update app"));
                    _clone->setStyleSheet("border: 0px; color: 'black';");
                }
                else
                {
                    _clone->setToolTip(tr("install app"));
                }

                connect(_clone, SIGNAL(clicked()), this, SLOT(clone_app()));

                layout()->addWidget(_clone, 0,2);

                ENSURE(_clone);
            }
Пример #16
0
            speaker::speaker(api::backend* back, qt_frontend* front, const std::string& codec) : _back{back}, _front{front}
            {
                REQUIRE(back);
                REQUIRE(front);
                INVARIANT(_back);
                INVARIANT(_front);

                _f.setSampleRate(SAMPLE_RATE); 
                _f.setChannelCount(CHANNELS); 
                _f.setSampleSize(SAMPLE_SIZE); 
                _f.setSampleType(QAudioFormat::SignedInt); 
                _f.setByteOrder(QAudioFormat::LittleEndian); 
                _f.setCodec(Q_CODEC.c_str()); 
                _t = parse_codec(codec);

                QAudioDeviceInfo i{QAudioDeviceInfo::defaultOutputDevice()};
                if (!i.isFormatSupported(_f)) _f = i.nearestFormat(_f);
                LOG << "using speaker device: " << convert(i.deviceName()) << std::endl;

                _o = new QAudioOutput{i, _f, _front};

                CHECK_GREATER_EQUAL(static_cast<size_t>(_f.sampleRate()), SAMPLE_RATE);
                _rep = _f.sampleRate() / SAMPLE_RATE;
                _channels = _f.channelCount();

                if(_t == codec_type::opus) _opus = std::make_shared<u::opus_decoder>();
            }
Пример #17
0
        void session_widget::check_mail()
        try
        {
            INVARIANT(_messages);
            INVARIANT(_session);
            INVARIANT(_session_service);
            INVARIANT(_session_service->user_service());
            INVARIANT(_session->mail());

            m::message m;
            while(_session->mail()->pop_inbox(m))
            {
                //for now show encoded message
                //TODO: use factory class to create gui from messages
                if(m.meta.type == ms::NEW_APP)
                {
                    _messages->add_new_app(m);
                }
                else if(m.meta.type == s::event::SESSION_SYNCED)
                {
                    update_contacts();
                }
                else if(m.meta.type == s::event::CONTACT_REMOVED)
                {
                    update_contacts();

                    s::event::contact_removed r;
                    s::event::convert(m, r);

                    auto c = _session_service->user_service()->by_id(r.contact_id);
                    if(!c) continue;

                    add(contact_alert(c, "quit session"));
                }
                else if(m.meta.type == us::event::CONTACT_CONNECTED)
                {
                    update_contacts();
                }
                else if(m.meta.type == us::event::CONTACT_DISCONNECTED)
                {
                    update_contacts();
                }
                else
                {
                    std::stringstream s;
                    s << m;

                    _messages->add(new unknown_message{s.str()});
                }
            }
        }
        catch(std::exception& e)
        {
            std::cerr << "session: error in check_mail. " << e.what() << std::endl;
        }
        catch(...)
        {
            std::cerr << "session: unexpected error in check_mail." << std::endl;
        }
Пример #18
0
        void app_area::add_chat_app()
        {
            INVARIANT(_conversation);
            INVARIANT(_conversation_service);

            //create chat app
            auto t = new a::chat_app{_conversation_service, _conversation};
            add(t, nullptr, ""); 
        }
Пример #19
0
            void chat_app::join()
            {
                INVARIANT(_sender);
                INVARIANT(_conversation);
                INVARIANT(_conversation->user_service());

                joined_message jm;
                send_all(jm.to_message());
            }
Пример #20
0
 script_app::~script_app()
 {
     INVARIANT(_app);
     INVARIANT(_back);
     LOG << "closing app " << _app->name() << "(" << _app->id() << ")" << std::endl;
     _front->stop();
     _back->stop();
     LOG << "closed app " << _app->name() << "(" << _app->id() << ")" << std::endl;
 }
Пример #21
0
        master_post_office::~master_post_office()
        {
            INVARIANT(_in_thread);
            INVARIANT(_out_thread);

            _done = true;
            _out.done();
            _in_thread->join();
            _out_thread->join();
        }
Пример #22
0
    // TODO: Implement correct resize (reserve + push_back's, or pop_back's if we handle non-empty)
    void reserve(size_t new_size) {
	INVARIANT(empty(),"Lame implementation only does reserve when empty");
	INVARIANT(new_size > 0 && new_size < std::numeric_limits<size_t>::max(), 
                  "Must have size at least 1, and at most size_t::max() - 1");
	new_size += 1; // for the empty entry that always exists
	q_front = q_back = 0;
	allocator.deallocate(deque, q_size);
	q_size = new_size;
	deque = allocator.allocate(q_size);
    }
Пример #23
0
        session_widget::session_widget(
                s::session_service_ptr session_service,
                s::session_ptr session,
                a::app_service_ptr app_service) :
            _session_service{session_service},
            _session{session},
            _app_service{app_service},
            _messages{new message_list{app_service, session}}
        {
            REQUIRE(session_service);
            REQUIRE(session);
            REQUIRE(app_service);

            _layout = new QGridLayout;

            _contact_select = new QComboBox;
            _add_contact = new QPushButton{"+"};
            _add_contact->setMaximumSize(20,20);
            connect(_add_contact, SIGNAL(clicked()), this, SLOT(add_contact()));

            update_contact_select();

            _contacts = new contact_list{_session_service->user_service(), _session->contacts()};

            auto* cw = new QWidget;
            auto* cl = new QGridLayout;

            cw->setLayout(cl);
            cl->addWidget(_contact_select, 0,0);
            cl->addWidget(_add_contact, 0, 1);
            cl->addWidget(_contacts, 1, 0, 1, 2);
            cw->resize(CW_WIDTH, cw->height());

            _splitter = new QSplitter{Qt::Horizontal};
            _splitter->addWidget(_messages);
            _splitter->addWidget(cw);
            _splitter->setStretchFactor(0, 1);
            _splitter->setStretchFactor(1, 0);
           
            _layout->addWidget(_splitter);

            setLayout(_layout);
            _layout->setContentsMargins(0,0,0,0);

            //setup mail timer
            auto *t2 = new QTimer(this);
            connect(t2, SIGNAL(timeout()), this, SLOT(check_mail()));
            t2->start(TIMER_SLEEP);

            INVARIANT(_session_service);
            INVARIANT(_session);
            INVARIANT(_messages);
            INVARIANT(_layout);
            INVARIANT(_app_service);
        }
Пример #24
0
        conversation_ptr conversation_service::sync_conversation(
                const std::string& from_id,
                const std::string& id, 
                const user::contact_list& contacts,
                const app_addresses& apps)
        {
            INVARIANT(_post);
            INVARIANT(_user_service);
            INVARIANT(_sender);

            u::mutex_scoped_lock l(_mutex);

            bool is_new = false;
            conversation_ptr s;

            auto sp = _conversations.find(id);

            //conversation does not exist, create it
            if(sp == _conversations.end())
            {
                //create new conversation
                s = std::make_shared<conversation>(id, _user_service, _post);
                _conversations[id] = s;

                //add new conversation to post office
                _post->add(s->mail());
                is_new = true;
            }
            else s = sp->second;

            //add contacts to conversation
            CHECK(s);
            for(auto c : contacts.list())
            {
                CHECK(c);
                add_contact_to_conversation(c, s);
            }

            //add apps in conversation
            id_set need_apps;
            for(const auto& app : apps)
            {
                if(s->has_app(app)) continue;
                LOG << "conversation: " << s->id() << " needs app with address: " << app << std::endl;
                need_apps.insert(need_apps.end(), app);
            }

            //done creating conversation, fire event
            if(is_new) fire_new_conversation_event(id);

            //request apps that are needed
            request_apps(from_id, s, need_apps);

            return s;
        }
Пример #25
0
 void microphone::start()
 {
     INVARIANT(_i);
     INVARIANT(_api);
     if(!_d)
     {
         _d = _i->start();
         if(_d) _api->connect_sound(_id, _i, _d);
     }
     _recording = true;
 }
Пример #26
0
        void debug_win::update_mailboxes()
        {
            INVARIANT(_post);
            INVARIANT(_mailboxes);

            if(_post->boxes().size() == _total_mailboxes) return;

            add_mailboxes(*_post, *_mailboxes, _added_mailboxes);

            _total_mailboxes = _post->boxes().size();
        }
Пример #27
0
void  widgets::update_record_in_the_tree(
        async::key_type const&  key,
        async::cached_resource_info const&  old_info,
        async::cached_resource_info const&  new_info,
        bool const  is_just_being_loaded
        )
{
    TMPROF_BLOCK();

    QTreeWidgetItem*  data_type_node = nullptr;
    {
        auto const  items = findItems(QString(key.get_data_type_name().c_str()), Qt::MatchFlag::MatchExactly, 0);
        INVARIANT(items.size() == 1);
        data_type_node = items.front();
    }
    QTreeWidgetItem*  uid_node = nullptr;
    {
        std::string const  uid = get_tree_resource_uid(key);
        for (int i = 0, n = data_type_node->childCount(); i != n; ++i)
        {
            auto const  item = data_type_node->child(i);
            std::string const  item_name = qtgl::to_string(item->text(0));
            if (item_name == uid)
            {
                uid_node = item;
                break;
            }
        }
        INVARIANT(uid_node != nullptr);
    }

    uid_node->setIcon(0, *choose_icon(new_info.get_load_state(), is_just_being_loaded));
    if (qtgl::to_string(uid_node->text(0)) != key.get_unique_id())
    {
        std::string const  item_refs_name = qtgl::to_string(uid_node->text(1));
        int const  old_num_refs = std::atoi(item_refs_name.c_str());
        int const  new_num_refs = old_num_refs + ((int)new_info.get_ref_count() - (int)old_info.get_ref_count());
        uid_node->setText(1, QString(std::to_string(new_num_refs).c_str()));
    }
    else
    {
        uid_node->setText(1, QString(std::to_string(new_info.get_ref_count()).c_str()));
    }
    if (new_info.get_error_message().empty())
        uid_node->setToolTip(0, "");
    else
        uid_node->setToolTip(0, QString(new_info.get_error_message().c_str()));

    std::string const  item_refs_name = qtgl::to_string(data_type_node->text(1));
    int const  old_num_refs = std::atoi(item_refs_name.c_str());
    int const  new_num_refs = old_num_refs + ((int)new_info.get_ref_count() - (int)old_info.get_ref_count());
    data_type_node->setText(1, QString(std::to_string(new_num_refs).c_str()));
}
Пример #28
0
            void chat_app::contact_quit(const std::string& id)
            {
                REQUIRE_FALSE(id.empty());
                INVARIANT(_messages);
                INVARIANT(_conversation);

                auto c = _conversation->user_service()->by_id(id);
                if(!c) return;

                std::stringstream s;
                s << c->name() << " quit";
                add_text(make_message_str("red", "notice", s.str()));
            }
Пример #29
0
            void chat_app::check_mail(m::message m) 
            try
            {
                INVARIANT(_conversation);
                INVARIANT(_conversation_service);

                if(m::is_remote(m)) m::expect_symmetric(m);
                else m::expect_plaintext(m);

                if(m.meta.type == MESSAGE)
                {
                    text_message t;
                    t.from_message(m);

                    auto c = _conversation->contacts().by_id(t.from_id);
                    if(!c) return;

                    //older clients do not have clocks
                    if(t.has_clock)
                    {
                        //discard resent messages
                        if(t.clock <= _clock) return;

                        //merge clocks
                        _clock += t.clock;
                    }

                    add_text(make_message_str("black", c->name(), t.text));

                    _conversation_service->fire_conversation_alert(_conversation->id(), visible());
                    alerted();
                }
                else if(m.meta.type == JOINED)
                {
                    joined_message t;
                    t.from_message(m);
                    contact_joined(t.from_id);
                }
                else
                {
                    LOG << "chat sample received unknown message `" << m.meta.type << "'" << std::endl;
                }
            }
            catch(std::exception& e)
            {
                LOG << "chat_app: error in check_mail. " << e.what() << std::endl;
            }
            catch(...)
            {
                LOG << "chat_app: unexpected error in check_mail." << std::endl;
            }
Пример #30
0
            void script_app::received_event_message(const m::message& m)
            {
                REQUIRE_EQUAL(m.meta.type, l::EVENT_MESSAGE);
                INVARIANT(_conversation);
                INVARIANT(_api);

                auto id = m.meta.extra["from_id"].as_string();

                if(!_conversation->user_service()->by_id(id)) 
                    return;

                l::event_message em{m, _api.get()};
                _api->event_received(em);
            }