libscratchcpp
A library for C++ based Scratch project players
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4
5#include <string>
6
7#include "value.h"
8#include "entity.h"
9#include "string_pool.h"
10#include "string_functions.h"
11#include "stringptr.h"
12#include "veque.h"
13
14namespace libscratchcpp
15{
16
17class Target;
18class Monitor;
19class ListPrivate;
20
27{
28 public:
29 List(const std::string &id, const std::string &name);
30 List(const List &) = delete;
31
32 ~List();
33
34 const std::string &name();
35 void setName(const std::string &name);
36
37 Target *target() const;
38 void setTarget(Target *target);
39
40 Monitor *monitor() const;
42
44 inline ValueData *data() const { return m_rawDataPtr; }
45
50 inline ValueData *const *dataPtr() const { return &m_rawDataPtr; }
51
56 inline size_t *sizePtr() { return &m_size; }
57
62 inline const size_t *allocatedSizePtr() const { return m_dataPtr->sizePtr(); }
63
65 inline size_t size() const { return m_size; }
66
68 inline bool empty() const { return m_size == 0; }
69
71 inline size_t indexOf(const ValueData &value) const
72 {
73 for (size_t i = 0; i < m_size; i++) {
74 if (value_equals(&m_dataPtr->operator[](i), &value))
75 return i;
76 }
77
78 return -1;
79 }
80
82 inline size_t indexOf(const Value &value) const { return indexOf(value.data()); }
83
85 inline bool contains(const ValueData &value) const { return (indexOf(value) != -1); }
86
88 inline bool contains(const Value &value) const { return contains(value.data()); }
89
91 inline void clear()
92 {
93 // Keep at least 200,000 items allocated if the list has more
94 constexpr size_t limit = 200000;
95 m_size = 0;
96
97 if (m_dataPtr->size() > limit)
98 reserve(limit);
99 }
100
103 {
104 m_size++;
105 reserve(getAllocSize(m_size));
106 return m_dataPtr->operator[](m_size - 1);
107 }
108
110 inline void append(const ValueData &value) { value_assign_copy(&appendEmpty(), &value); }
111
113 inline void append(const Value &value) { append(value.data()); }
114
116 inline void removeAt(size_t index)
117 {
118 assert(index >= 0 && index < size());
119 std::rotate(m_dataPtr->begin() + index, m_dataPtr->begin() + index + 1, m_dataPtr->begin() + m_size);
120 m_size--;
121 }
122
124 inline ValueData &insertEmpty(size_t index)
125 {
126 assert(index >= 0 && index <= size());
127 m_size++;
128 reserve(getAllocSize(m_size));
129 std::rotate(m_dataPtr->rbegin() + m_dataPtr->size() - m_size, m_dataPtr->rbegin() + m_dataPtr->size() - m_size + 1, m_dataPtr->rend() - index);
130 return m_dataPtr->operator[](index);
131 }
132
134 inline void insert(size_t index, const ValueData &value) { value_assign_copy(&insertEmpty(index), &value); }
135
137 inline void insert(size_t index, const Value &value) { insert(index, value.data()); }
138
140 inline void replace(size_t index, const ValueData &value)
141 {
142 assert(index >= 0 && index < size());
143 value_assign_copy(&m_dataPtr->operator[](index), &value);
144 }
145
147 inline void replace(size_t index, const Value &value) { replace(index, value.data()); }
148
149 inline ValueData &operator[](size_t index)
150 {
151 assert(index >= 0 && index < size());
152 return m_dataPtr->operator[](index);
153 }
154
156 inline void toStringPtr(StringPtr *dst) const
157 {
158 veque::veque<StringPtr *> strings;
159 size_t size = 0;
160 strings.reserve(m_size);
161 bool digits = true;
162 size_t i;
163
164 for (i = 0; i < m_size; i++) {
165 const ValueData *item = &m_dataPtr->operator[](i);
166 StringPtr *str = string_pool_new();
167 value_toStringPtr(item, str);
168 strings.push_back(str);
169 size += strings.back()->size;
170
171 if (value_isValidNumber(item) && !value_isBool(item) && strings.back()->size > 0) {
172 double doubleNum = value_toDouble(item);
173 long num = value_toLong(item);
174
175 if (doubleNum != num) {
176 digits = false;
177 break;
178 }
179
180 if (num < 0 || num >= 10) {
181 digits = false;
182 break;
183 }
184 } else {
185 digits = false;
186 break;
187 }
188 }
189
190 dst->size = 0;
191
192 if (digits) {
193 string_alloc(dst, size);
194
195 for (i = 0; i < strings.size(); i++) {
196 memcpy(dst->data + dst->size, strings[i]->data, strings[i]->size * sizeof(char16_t));
197 dst->size += strings[i]->size;
198 string_pool_free(strings[i]);
199 }
200
201 for (; i < m_size; i++) {
202 StringPtr *item = string_pool_new();
203 value_toStringPtr(&m_dataPtr->operator[](i), item);
204 size += item->size + 1;
205 string_alloc(dst, size);
206 memcpy(dst->data + dst->size, item->data, item->size * sizeof(char16_t));
207 dst->size += item->size;
208 string_pool_free(item);
209 }
210 } else {
211 size += strings.size() - 1;
212 string_alloc(dst, size);
213
214 for (i = 0; i < strings.size(); i++) {
215 memcpy(dst->data + dst->size, strings[i]->data, strings[i]->size * sizeof(char16_t));
216 dst->size += strings[i]->size;
217 string_pool_free(strings[i]);
218
219 if (i + 1 < m_size)
220 dst->data[dst->size++] = u' ';
221 }
222
223 for (; i < m_size; i++) {
224 StringPtr *item = string_pool_new();
225 value_toStringPtr(&m_dataPtr->operator[](i), item);
226 size += item->size + 1;
227 string_alloc(dst, size);
228 memcpy(dst->data + dst->size, item->data, item->size * sizeof(char16_t));
229 dst->size += item->size;
230 string_pool_free(item);
231
232 if (i + 1 < m_size)
233 dst->data[dst->size++] = u' ';
234 }
235 }
236
237 dst->data[dst->size] = u'\0';
238 }
239
240 std::string toString() const;
241
242 std::shared_ptr<List> clone();
243
244 private:
245 inline void reserve(size_t size)
246 {
247 assert(size >= m_size);
248
249 while (size > m_dataPtr->size()) {
250 m_dataPtr->push_back(ValueData());
251 value_init(&m_dataPtr->back());
252 }
253
254 while (size < m_dataPtr->size()) {
255 value_free(&m_dataPtr->back());
256 m_dataPtr->erase(m_dataPtr->end());
257 }
258
259 m_rawDataPtr = m_dataPtr->data();
260 }
261
262 inline size_t getAllocSize(size_t x)
263 {
264 if (x == 0)
265 return 0;
266
267 size_t ret = 1;
268
269 while (ret < x)
270 ret *= 2;
271
272 return ret;
273 }
274
275 spimpl::unique_impl_ptr<ListPrivate> impl;
276 veque::veque<ValueData> *m_dataPtr = nullptr; // NOTE: accessing through pointer is faster! (from benchmarks)
277 ValueData *m_rawDataPtr = nullptr;
278 size_t m_size = 0;
279};
280
281} // namespace libscratchcpp
Entity(const std::string &id)
Definition entity.cpp:10
size_t * sizePtr()
Definition list.h:56
void clear()
Definition list.h:91
void setName(const std::string &name)
Definition list.cpp:32
ValueData & operator[](size_t index)
Definition list.h:149
void toStringPtr(StringPtr *dst) const
Definition list.h:156
Target * target() const
Definition list.cpp:38
void removeAt(size_t index)
Definition list.h:116
const size_t * allocatedSizePtr() const
Definition list.h:62
ValueData & appendEmpty()
Definition list.h:102
List(const List &)=delete
void setTarget(Target *target)
Definition list.cpp:44
size_t size() const
Definition list.h:65
bool contains(const Value &value) const
Definition list.h:88
void append(const ValueData &value)
Definition list.h:110
bool empty() const
Definition list.h:68
void append(const Value &value)
Definition list.h:113
List(const std::string &id, const std::string &name)
Definition list.cpp:11
void setMonitor(Monitor *monitor)
Definition list.cpp:56
void insert(size_t index, const ValueData &value)
Definition list.h:134
size_t indexOf(const Value &value) const
Definition list.h:82
ValueData * data() const
Definition list.h:44
void insert(size_t index, const Value &value)
Definition list.h:137
ValueData & insertEmpty(size_t index)
Definition list.h:124
ValueData *const * dataPtr() const
Definition list.h:50
const std::string & name()
Definition list.cpp:26
bool contains(const ValueData &value) const
Definition list.h:85
void replace(size_t index, const Value &value)
Definition list.h:147
size_t indexOf(const ValueData &value) const
Definition list.h:71
Monitor * monitor() const
Definition list.cpp:50
void replace(size_t index, const ValueData &value)
Definition list.h:140
The Monitor class represents a stage monitor.
Definition monitor.h:23
The Target class is the Stage or a Sprite.
Definition target.h:28
The Value class represents a Scratch value.
Definition value.h:22
const ValueData & data() const
Definition value.h:86
#define LIBSCRATCHCPP_EXPORT
Definition global.h:17
The main namespace of the library.
Definition asset.h:10
void value_assign_copy(ValueData *v, const ValueData *another)
Definition value_functions.cpp:94
double value_toDouble(const ValueData *v)
Definition value_functions.cpp:253
bool value_isValidNumber(const ValueData *v)
Definition value_functions.cpp:166
void value_init(ValueData *v)
Definition value_functions.cpp:30
void value_toStringPtr(const ValueData *v, StringPtr *dst)
Definition value_functions.cpp:291
LIBSCRATCHCPP_EXPORT void string_pool_free(StringPtr *str)
Definition string_pool.cpp:44
LIBSCRATCHCPP_EXPORT void string_alloc(StringPtr *str, size_t size)
Definition string_functions.cpp:19
bool value_isBool(const ValueData *v)
Definition value_functions.cpp:213
LIBSCRATCHCPP_EXPORT StringPtr * string_pool_new()
Definition string_pool.cpp:24
long value_toLong(const ValueData *v)
Definition value_functions.cpp:227
bool value_equals(const ValueData *v1, const ValueData *v2)
Definition value_functions.cpp:536
The StringPtr struct holds a string data pointer and string size.
Definition stringptr.h:14
char16_t * data
Definition stringptr.h:27
size_t size
Definition stringptr.h:28
The ValueData struct holds the data of Value. It's used in compiled Scratch code for better performan...
Definition valuedata.h:26