libkazv
Loading...
Searching...
No Matches
clientutil.hpp
Go to the documentation of this file.
1/*
2 * This file is part of libkazv.
3 * SPDX-FileCopyrightText: 2021-2023 tusooa <tusooa@kazv.moe>
4 * SPDX-License-Identifier: AGPL-3.0-or-later
5 */
6
7
8#pragma once
9#include <libkazv-config.hpp>
10
11#include <string>
12#include <tuple>
13#include <immer/map.hpp>
14#include <zug/transducer/filter.hpp>
15#include <zug/transducer/eager.hpp>
16#include <lager/deps.hpp>
17#include <boost/container_hash/hash.hpp>
18#include <boost/serialization/string.hpp>
19
20#include <cursorutil.hpp>
21#include <jobinterface.hpp>
22#include <eventinterface.hpp>
24
25namespace Kazv
26{
27 struct ClientModel;
28
29 template<class K, class V, class List, class Func>
30 immer::map<K, V> merge(immer::map<K, V> map, List list, Func keyOf)
31 {
32 for (auto v : list) {
33 auto key = keyOf(v);
34 map = std::move(map).set(key, v);
35 }
36 return map;
37 }
38
39 inline std::string keyOfPresence(Event e) {
40 return e.sender();
41 }
42
43 inline std::string keyOfAccountData(Event e) {
44 return e.type();
45 }
46
47 inline std::string keyOfTimeline(Event e) {
48 return e.id();
49 }
50
51 inline std::string keyOfEphemeral(Event e) {
52 return e.type();
53 }
54
55
56 struct KeyOfState {
57 std::string type;
58 std::string stateKey;
59 friend bool operator==(const KeyOfState &a, const KeyOfState &b) = default;
60 };
61 template<class Archive>
62 void serialize(Archive &ar, KeyOfState &m, std::uint32_t const /* version */)
63 {
64 ar & m.type & m.stateKey;
65 }
66
68 return {e.type(), e.stateKey()};
69 }
70
71 template<class Context>
73 {
74 return lager::get<JobInterface &>(std::forward<Context>(ctx));
75 }
76
77 template<class Context>
79 {
80 return lager::get<EventInterface &>(std::forward<Context>(ctx));
81 }
82
105 template<class ImmerT1, class RangeT2, class Pred, class Func>
106 ImmerT1 sortedUniqueMerge(ImmerT1 base, RangeT2 addon, Pred exists, Func keyOf)
107 {
108 auto cmp = [=](auto a, auto b) {
109 return keyOf(a) < keyOf(b);
110 };
111
112 for (auto item : addon) {
113 if (exists(item)) {
114 continue;
115 }
116 // https://en.cppreference.com/w/cpp/algorithm/upper_bound.html
117 // *(it-1) <= item < *it
118 auto it = std::upper_bound(base.begin(), base.end(), item, cmp);
119 // If `it` is not the first iterator, and `*(it-1) == item`,
120 // then `item` is already in the list. Otherwise, we are guaranteed
121 // that `*(it-1)` either does not exist, or `*(it-1) < item`.
122 // In these cases, `item` is not in the list and we will need
123 // to add them.
124 if (it.index() != 0 && keyOf(item) == keyOf(*(it - 1))) {
125 continue;
126 }
127 auto index = it.index();
128 base = std::move(base).insert(index, item);
129 }
130
131 return base;
132 }
133
134 std::string increaseTxnId(std::string cur);
135
136 std::string getTxnId(Event event, ClientModel &m);
137}
138
139namespace std
140{
141 template<> struct hash<Kazv::KeyOfState>
142 {
143 std::size_t operator()(const Kazv::KeyOfState & k) const noexcept {
144 std::size_t seed = 0;
145 boost::hash_combine(seed, k.type);
146 boost::hash_combine(seed, k.stateKey);
147 return seed;
148 }
149 };
150}
151
152#define KAZV_WRAP_ATTR(_type, _d, _attr) \
153 inline auto _attr() const { \
154 KAZV_VERIFY_THREAD_ID(); \
155 return (_d)[&_type::_attr]; \
156 }
157
158BOOST_CLASS_VERSION(Kazv::KeyOfState, 0)
Definition context.hpp:130
Definition eventinterface.hpp:15
Definition event.hpp:21
std::string stateKey() const
Definition event.cpp:74
std::string type() const
Definition event.cpp:62
std::string id() const
returns the id of this event
Definition event.cpp:42
std::string sender() const
Definition event.cpp:49
Definition location.hpp:10
EventInterface & getEventEmitter(Context &&ctx)
Definition clientutil.hpp:78
std::string increaseTxnId(std::string cur)
Definition clientutil.cpp:14
std::string keyOfAccountData(Event e)
Definition clientutil.hpp:43
JobInterface & getJobHandler(Context &&ctx)
Definition clientutil.hpp:72
ImmerT1 sortedUniqueMerge(ImmerT1 base, RangeT2 addon, Pred exists, Func keyOf)
Merge addon into the sorted container base.
Definition clientutil.hpp:106
std::string getTxnId(Event, ClientModel &m)
Definition clientutil.cpp:19
KeyOfState keyOfState(Event e)
Definition clientutil.hpp:67
std::string keyOfEphemeral(Event e)
Definition clientutil.hpp:51
std::string keyOfPresence(Event e)
Definition clientutil.hpp:39
immer::map< K, V > merge(immer::map< K, V > map, List list, Func keyOf)
Definition clientutil.hpp:30
std::string keyOfTimeline(Event e)
Definition clientutil.hpp:47
void serialize(Archive &ar, ClientModel &m, std::uint32_t const version)
Definition client-model.hpp:633
Definition clientutil.hpp:140
Definition jobinterface.hpp:21
Definition clientutil.hpp:56
std::string type
Definition clientutil.hpp:57
std::string stateKey
Definition clientutil.hpp:58
friend bool operator==(const KeyOfState &a, const KeyOfState &b)=default
std::size_t operator()(const Kazv::KeyOfState &k) const noexcept
Definition clientutil.hpp:143