Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2023 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #ifndef MU_ENGRAVING_LD_ACCESS_DEV_H
23 : #define MU_ENGRAVING_LD_ACCESS_DEV_H
24 :
25 : #include <optional>
26 :
27 : #include "log.h"
28 :
29 : namespace mu::engraving {
30 : //! NOTE Enum for detect layoutdata bad access errors
31 : enum class LD_ACCESS : unsigned char {
32 : CHECK = 0, // should be correct; assert if still not
33 : BAD, // known to be bad; don’t assert, we’ll fix it later
34 : MAYBE_NOTINITED, // in this case it’s okay if we access it before it’s been inited
35 : PASS // for debug
36 : };
37 :
38 : #ifdef MUE_ENABLE_ENGRAVING_LD_ACCESS
39 :
40 : //! TODO Using this macro, we can collect and output debugging information to show the dependency tree
41 : #define LD_CONDITION(val) \
42 : if (!val) { \
43 : LOGE_T("LD_ACCESS")() << "BAD ACCESS to: " << #val << ", file: " << __FILE__ << ", line: " << __LINE__; \
44 : } \
45 :
46 : #else
47 : #define LD_CONDITION(val) (void)val;
48 : #endif
49 :
50 : // mark as independent
51 : #define LD_INDEPENDENT
52 :
53 : template<typename T>
54 : class ld_field_debug
55 : {
56 : public:
57 :
58 2232171 : ld_field_debug(const char* name, T def = T())
59 2232171 : : m_name(name), m_def(def) {}
60 :
61 1194783 : inline void reset() { m_val.reset(); }
62 :
63 1127368 : inline bool has_value() const { return m_val.has_value(); }
64 :
65 24055637 : inline const T& value(LD_ACCESS mode = LD_ACCESS::CHECK) const
66 : {
67 24055637 : if (!m_val.has_value()) {
68 : #ifdef MUE_ENABLE_ENGRAVING_LD_ACCESS
69 : if (mode == LD_ACCESS::CHECK) {
70 : LOGE_T("LD_ACCESS")() << "BAD ACCESS to: " << m_name;
71 : }
72 : #else
73 : UNUSED(mode);
74 : #endif
75 1999989 : return m_def;
76 : }
77 22055648 : return m_val.value();
78 : }
79 :
80 511818 : inline const T& operator()() const
81 : {
82 511818 : return value();
83 : }
84 :
85 5416384 : operator T() const {
86 5416384 : return value();
87 : }
88 :
89 5175913 : inline T& mut_value()
90 : {
91 5175913 : if (!m_val.has_value()) {
92 546832 : m_val = std::make_optional<T>(m_def);
93 : }
94 5175913 : return m_val.value();
95 : }
96 :
97 3039853 : inline void set_value(const T& v)
98 : {
99 3039853 : m_val = std::make_optional<T>(v);
100 3039853 : }
101 :
102 328860 : ld_field_debug& operator=(const T& v) { m_val = v; return *this; }
103 :
104 : private:
105 : const char* m_name = nullptr;
106 : T m_def;
107 : std::optional<T> m_val;
108 : };
109 :
110 : template<typename T>
111 : class ld_field_prod
112 : {
113 : public:
114 :
115 : ld_field_prod(const char*, T def = T())
116 : : m_val(def) {}
117 :
118 : inline void reset() { m_val = T(); }
119 :
120 : inline bool has_value() const { return true; }
121 :
122 : inline const T& value(LD_ACCESS = LD_ACCESS::CHECK) const
123 : {
124 : return m_val;
125 : }
126 :
127 : inline const T& operator()() const
128 : {
129 : return value();
130 : }
131 :
132 : operator T() const {
133 : return value();
134 : }
135 :
136 : inline T& mut_value()
137 : {
138 : return m_val;
139 : }
140 :
141 : inline void set_value(const T& v)
142 : {
143 : m_val = v;
144 : }
145 :
146 : ld_field_prod& operator=(const T& v) { m_val = v; return *this; }
147 :
148 : private:
149 : T m_val;
150 : };
151 :
152 : #ifdef NDEBUG
153 : template<typename T>
154 : using ld_field = ld_field_prod<T>;
155 : #else
156 : template<typename T>
157 : using ld_field = ld_field_debug<T>;
158 : #endif
159 : }
160 :
161 : #endif // MU_ENGRAVING_LD_ACCESS_DEV_H
|