Skip to content

kdbindings/binding_evaluator.h

Namespaces

Name
KDBindings
The main namespace of the KDBindings library.

Classes

Name
class KDBindings::BindingEvaluator
A BindingEvaluator provides a mechanism to control the exact time when a KDBindings::Binding is reevaluated.
class KDBindings::ImmediateBindingEvaluator

Source code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
  This file is part of KDBindings.

  SPDX-FileCopyrightText: 2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
  Author: Sean Harmer <sean.harmer@kdab.com>

  SPDX-License-Identifier: MIT

  Contact KDAB at <info@kdab.com> for commercial licensing options.
*/

#pragma once

#include <functional>
#include <map>
#include <memory>

namespace KDBindings {

class BindingEvaluator
{
    // We use pimpl here so that we can pass evaluators around by value (copies)
    // yet each copy refers to the same set of data
    struct Private {
        // TODO: Use std::vector here?
        std::map<int, std::function<void()>> m_bindingEvalFunctions;
        int m_currentId;
    };

public:
    BindingEvaluator() = default;

    BindingEvaluator(const BindingEvaluator &) noexcept = default;

    BindingEvaluator &operator=(const BindingEvaluator &) noexcept = default;

    BindingEvaluator(BindingEvaluator &&other) noexcept = delete;

    BindingEvaluator &operator=(BindingEvaluator &&other) noexcept = delete;

    void evaluateAll() const
    {
        // a std::map's ordering is deterministic, so the bindings are evaluated
        // in the order they were inserted, ensuring correct transitive dependency
        // evaluation.
        for (auto &[id, func] : m_d->m_bindingEvalFunctions)
            func();
    }

private:
    template<typename BindingType>
    int insert(BindingType *binding)
    {
        m_d->m_bindingEvalFunctions.insert({ ++(m_d->m_currentId),
                                             [=]() { binding->evaluate(); } });
        return m_d->m_currentId;
    }

    void remove(int id)
    {
        m_d->m_bindingEvalFunctions.erase(id);
    }

    std::shared_ptr<Private> m_d{ std::make_shared<Private>() };

    template<typename T, typename UpdaterT>
    friend class Binding;
};

class ImmediateBindingEvaluator final : public BindingEvaluator
{
public:
    static inline ImmediateBindingEvaluator instance()
    {
        static ImmediateBindingEvaluator evaluator;
        return evaluator;
    }
};

} // namespace KDBindings

Updated on 2024-03-19 at 00:03:31 +0000