Skip to content

Commit d884813

Browse files
committed
Target: Add variableData() method
1 parent be0c951 commit d884813

File tree

4 files changed

+48
-1
lines changed

4 files changed

+48
-1
lines changed

include/scratchcpp/target.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ namespace libscratchcpp
1212
{
1313

1414
class Variable;
15+
struct ValueData;
1516
class List;
1617
class Block;
1718
class Comment;
@@ -28,7 +29,7 @@ class LIBSCRATCHCPP_EXPORT Target : public Drawable
2829
public:
2930
Target();
3031
Target(const Target &) = delete;
31-
virtual ~Target() { }
32+
virtual ~Target();
3233

3334
bool isTarget() const override final;
3435

@@ -44,6 +45,8 @@ class LIBSCRATCHCPP_EXPORT Target : public Drawable
4445
int findVariable(const std::string &variableName) const;
4546
int findVariableById(const std::string &id) const;
4647

48+
ValueData **variableData();
49+
4750
const std::vector<std::shared_ptr<List>> &lists() const;
4851
int addList(std::shared_ptr<List> list);
4952
std::shared_ptr<List> listAt(int index) const;

src/scratch/target.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ Target::Target() :
2929
{
3030
}
3131

32+
/*! Destroys Target. */
33+
Target::~Target()
34+
{
35+
if (impl->variableData)
36+
free(impl->variableData);
37+
}
38+
3239
/*! Returns true. */
3340
bool Target::isTarget() const
3441
{
@@ -66,6 +73,7 @@ int Target::addVariable(std::shared_ptr<Variable> variable)
6673
return it - impl->variables.begin();
6774

6875
impl->variables.push_back(variable);
76+
impl->variableDataDirty = true;
6977
variable->setTarget(this);
7078

7179
return impl->variables.size() - 1;
@@ -102,6 +110,31 @@ int Target::findVariableById(const std::string &id) const
102110
return it - impl->variables.begin();
103111
}
104112

113+
/*! Returns an array of raw variable data pointers (for optimized variable access). */
114+
ValueData **Target::variableData()
115+
{
116+
if (impl->variableDataDirty) {
117+
const size_t len = impl->variables.size();
118+
119+
if (len == 0) {
120+
impl->variableDataDirty = false;
121+
return nullptr;
122+
}
123+
124+
if (impl->variableData)
125+
impl->variableData = (ValueData **)realloc(impl->variableData, len * sizeof(ValueData *));
126+
else
127+
impl->variableData = (ValueData **)malloc(len * sizeof(ValueData *));
128+
129+
for (size_t i = 0; i < len; i++)
130+
impl->variableData[i] = &impl->variables[i]->valuePtr()->data();
131+
132+
impl->variableDataDirty = false;
133+
}
134+
135+
return impl->variableData;
136+
}
137+
105138
/*! Returns the list of Scratch lists. */
106139
const std::vector<std::shared_ptr<List>> &Target::lists() const
107140
{

src/scratch/target_p.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ struct TargetPrivate
2828

2929
std::string name;
3030
std::vector<std::shared_ptr<Variable>> variables;
31+
bool variableDataDirty = true;
32+
ValueData **variableData = nullptr;
3133
std::vector<std::shared_ptr<List>> lists;
3234
std::vector<std::shared_ptr<Block>> blocks;
3335
std::vector<std::shared_ptr<Comment>> comments;

test/scratch_classes/target_test.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,19 @@ TEST(TargetTest, Variables)
7575
auto v3 = std::make_shared<Variable>("c", "var3");
7676

7777
Target target;
78+
ASSERT_EQ(target.variableData(), nullptr);
7879
ASSERT_EQ(target.addVariable(v1), 0);
80+
ASSERT_TRUE(target.variableData());
81+
ASSERT_EQ(target.variableData()[0], &v1->value().data());
7982
ASSERT_EQ(target.addVariable(v2), 1);
8083
ASSERT_EQ(target.addVariable(v3), 2);
84+
ASSERT_EQ(target.variableData()[0], &v1->value().data());
85+
ASSERT_EQ(target.variableData()[1], &v2->value().data());
86+
ASSERT_EQ(target.variableData()[2], &v3->value().data());
8187
ASSERT_EQ(target.addVariable(v2), 1); // add existing variable
88+
ASSERT_EQ(target.variableData()[0], &v1->value().data());
89+
ASSERT_EQ(target.variableData()[1], &v2->value().data());
90+
ASSERT_EQ(target.variableData()[2], &v3->value().data());
8291

8392
ASSERT_EQ(v1->target(), &target);
8493
ASSERT_EQ(v2->target(), &target);

0 commit comments

Comments
 (0)