9std::mutex WidgetState::m_mutex;
11WidgetState Widget::emptyState(0, 0, 0, 0, 0, 0);
19 snprintf(buf,
sizeof(buf),
"%lx",
WidgetPos(x, y, w, h).encoded());
20 m_data.set(
"p",
new rbjson::String(buf));
23 m_data.set(
"tab", tab);
28 std::unique_lock<std::mutex> lock(m_mutex);
29 return m_data.getString(key, def);
33 std::unique_lock<std::mutex> lock(m_mutex);
34 return m_data.getInt(key, def);
38 std::unique_lock<std::mutex> lock(m_mutex);
39 return m_data.getDouble(key, def);
43 std::unique_lock<std::mutex> lock(m_mutex);
44 return m_data.getBool(key, def);
51 std::unique_lock<std::mutex> lock(m_mutex);
53 const auto* old = m_data.get(key);
54 if (old !=
nullptr && old->equals(*value)) {
59 m_data.set(key, value);
60 markChangedLocked(key);
68 std::unique_lock<std::mutex> lock(m_mutex);
70 auto* obj = m_data.getObject(objectName);
72 obj =
new rbjson::Object;
73 m_data.set(objectName, obj);
75 const auto* old = obj->get(propertyName);
76 if (old !=
nullptr && old->equals(*value)) {
82 obj->set(propertyName, value);
83 markChangedLocked(objectName);
87bool WidgetState::popChanges(rbjson::Object& state) {
88 std::unique_lock<std::mutex> lock(m_mutex);
89 if (m_bloom_tick == 0)
92 const auto& m = m_data.members();
93 for (
auto itr = m.begin(); itr != m.end(); ++itr) {
94 if (wasChangedInTickLocked(itr->name, itr->name_len)) {
95 state.set(std::string(itr->name, itr->name_len), itr->value->copy());
102static inline uint32_t
murmur3_32(
const uint8_t* key,
size_t len, uint32_t seed) {
105 const uint32_t* key_x4 = (
const uint32_t*)key;
108 uint32_t k = *key_x4++;
110 k = (k << 15) | (k >> 17);
113 h = (h << 13) | (h >> 19);
114 h = (h * 5) + 0xe6546b64;
116 key = (
const uint8_t*)key_x4;
127 k = (k << 15) | (k >> 17);
146 std::unique_lock<std::mutex> lock(m_mutex);
147 markChangedLocked(key);
150void WidgetState::markChangedLocked(
const std::string& key) {
152 const auto bit =
murmur3_32((uint8_t*)key.c_str(), key.size(), i) % 16;
153 m_bloom_global |= (1 << bit);
154 m_bloom_tick |= (1 << bit);
157 UI.notifyStateChange();
160void WidgetState::markGlobalChangedLocked(
const std::string& key) {
162 const auto bit =
murmur3_32((uint8_t*)key.c_str(), key.size(), i) % 16;
163 m_bloom_global |= (1 << bit);
167bool WidgetState::wasChangedInTickLocked(
const char *key,
size_t key_len)
const {
169 const auto bit =
murmur3_32((uint8_t*)key, key_len, i) % 16;
170 if ((m_bloom_tick & (1 << bit)) == 0)
176bool WidgetState::remarkAllChanges() {
177 std::unique_lock<std::mutex> lock(m_mutex);
178 if (m_bloom_global == 0)
180 m_bloom_tick = m_bloom_global;
static uint32_t murmur3_32(const uint8_t *key, size_t len, uint32_t seed)
static constexpr int hash_count