Coder Social home page Coder Social logo

ubports / properties-cpp Goto Github PK

View Code? Open in Web Editor NEW
0.0 7.0 0.0 90 KB

Moved to https://gitlab.com/ubports/core/lib-cpp/properties-cpp

Home Page: https://gitlab.com/ubports/core/lib-cpp/properties-cpp

License: GNU Lesser General Public License v3.0

CMake 37.86% C++ 62.14%

properties-cpp's Introduction

properties-cpp {#mainpage}

process-cpp is a simple header-only implementation of properties and signals. It is meant to be used for developing low-level system services. Its main features include:

  • Thread-safe signal invocation and observer mgmt.
  • The ability to dispatch signal invocations via arbitrary event loops.
  • Typed properties with an in-place update mechanism that avoids unneccessary deep copies.
  • Well tested and documented.

A Textfield With an Observable Cursor Position

namespace
{
struct TextField
{
    void move_cursor_to(int new_position)
    {
        cursor_position.set(new_position);
    }
    
    core::Property<int> cursor_position;
};
}

TEST(Property, cursor_position_changes_are_transported_correctly)
{
    int position = -1;

    TextField tf;
    
    // Setup a connection to the cursor position property
    tf.cursor_position.changed().connect(
        [&position](int value) 
        { 
            position = value; 
        });

    // Move the cursor
    tf.move_cursor_to(22);

    // Check that the correct value has propagated
    EXPECT_EQ(22, position);
}

Integrating With Arbitrary Event Loops/Reactor Implementations

namespace
{
struct EventLoop
{
    typedef std::function<void()> Handler;

    void stop()
    {
        stop_requested = true;
    }

    void run()
    {
        while (!stop_requested)
        {
            std::unique_lock<std::mutex> ul(guard);
            wait_condition.wait_for(
                        ul,
                        std::chrono::milliseconds{500},
                        [this]() { return handlers.size() > 0; });

            while (handlers.size() > 0)
            {
                handlers.front()();
                handlers.pop();
            }
        }
    }

    void dispatch(const Handler& h)
    {
        std::lock_guard<std::mutex> lg(guard);
        handlers.push(h);
    }

    bool stop_requested = false;
    std::queue<Handler> handlers;
    std::mutex guard;
    std::condition_variable wait_condition;
};
}

TEST(Signal, installing_a_custom_dispatcher_ensures_invocation_on_correct_thread)
{
    // We instantiate an event loop and run it on a different thread than the main one.
    EventLoop dispatcher;
    std::thread dispatcher_thread{[&dispatcher]() { dispatcher.run(); }};
    std::thread::id dispatcher_thread_id = dispatcher_thread.get_id();

    // The signal that we want to dispatch via the event loop.
    core::Signal<int, double> s;

    static const int expected_invocation_count = 10000;

    // Setup the connection. For each invocation we check that the id of the
    // thread the handler is being called upon equals the thread that the
    // event loop is running upon.
    auto connection = s.connect(
                [&dispatcher, dispatcher_thread_id](int value, double d)
                {
                    EXPECT_EQ(dispatcher_thread_id,
                              std::this_thread::get_id());

                    std::cout << d << std::endl;

                    if (value == expected_invocation_count)
                        dispatcher.stop();
                });

    // Route the connection via the dispatcher
    connection.dispatch_via(
                std::bind(
                    &EventLoop::dispatch,
                    std::ref(dispatcher),
                    std::placeholders::_1));

    // Invoke the signal from the main thread.
    for (unsigned int i = 1; i <= expected_invocation_count; i++)
        s(i, 42.);

    if (dispatcher_thread.joinable())
        dispatcher_thread.join();
}

properties-cpp's People

Contributors

sil2100 avatar tjyrinki avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.