Skip to content

Commit b453318

Browse files
committed
Test for FlattenObject.
WIP algorithms examples.
1 parent 942582d commit b453318

2 files changed

Lines changed: 210 additions & 66 deletions

File tree

examples/src/BasicAlgorithms.cpp

Lines changed: 139 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,18 @@ namespace example1
3737
{
3838
cout << "Example 1 - Converting events to signals" << endl;
3939

40-
auto sensor = ObjectState<Sensor>::Create(g, Sensor{ });
40+
Sensor sensor;
4141

42-
auto obs = Observer::Create(g, [] (const auto& ctx)
42+
auto obs = Observer::Create(g, [] (int v)
4343
{
44-
const Sensor& obj = ctx.GetObject();
45-
cout << ctx.Get(obj.lastSample) << endl;
46-
}, sensor);
44+
cout << v << endl;
45+
}, sensor.lastSample);
4746

48-
sensor->samples << 20 << 21 << 21 << 22; // output: 20, 21, 22
47+
sensor.samples << 20 << 21 << 21 << 22; // output: 20, 21, 22
4948

5049
g.DoTransaction([&]
5150
{
52-
sensor->samples << 30 << 31 << 31 << 32;
51+
sensor.samples << 30 << 31 << 31 << 32;
5352
}); // output: 32
5453

5554
cout << endl;
@@ -343,51 +342,15 @@ namespace example6
343342

344343
using namespace react;
345344

346-
347-
template <typename T>
348-
class MyContainer { };
349-
350-
template <typename C>
351-
struct Flattened : public C
352-
{
353-
using C::C;
354-
355-
Flattened(const C& base) :
356-
C( base )
357-
{ }
358-
359-
Flattened(const C& base, int m) :
360-
C( base ),
361-
mode( m )
362-
{ }
363-
364-
template <typename T>
365-
T* Flatten(State<T>& signal)
366-
{
367-
if (mode == 1)
368-
{
369-
memberIds_.push_back(GetInternals(signal).GetNodeId());
370-
}
371-
372-
return &GetInternals(signal).Value();
373-
}
374-
375-
public:
376-
int mode = 0;
377-
std::vector<REACT_IMPL::NodeId> memberIds_;
378-
};
379-
380345
Group g;
381346

382347
struct MyClass
383348
{
384349
StateVar<int> a = StateVar<int>::Create(g, 10);
385350
StateVar<int> b = StateVar<int>::Create(g, 20);
386351

387-
int hello = 12435;
388-
389352
bool operator==(const MyClass& other)
390-
{ return hello == other.hello; }
353+
{ return a == other.a; }
391354

392355
struct Flat;
393356
};
@@ -396,14 +359,16 @@ struct MyClass::Flat : public Flattened<MyClass>
396359
{
397360
using Flattened::Flattened;
398361

399-
int* a = this->Flatten(MyClass::a);
400-
int* b = this->Flatten(MyClass::b);
362+
Ref<int> a = this->Flatten(MyClass::a);
363+
Ref<int> b = this->Flatten(MyClass::b);
401364
};
402365

366+
using namespace react;
367+
using namespace std;
403368

404369
void test1()
405370
{
406-
using namespace react;
371+
407372

408373
/*StateVar<int> x;
409374
State<int> y;
@@ -422,38 +387,146 @@ void test1()
422387
423388
Flatten(g, sig);*/
424389

425-
StateVar<MyClass> st = StateVar<MyClass>::Create(g);
390+
auto w1 = StateVar<string>::Create(g, "Widget1");
391+
auto w2 = StateVar<string>::Create(g, "Widget2");
392+
auto w3 = StateVar<string>::Create(g, "Widget3");
426393

427-
State<Ref<MyClass>> ref = CreateRef(st);
394+
auto allWidgets = { CreateRef(w1), CreateRef(w2), CreateRef(w3) };
428395

429-
auto obs2 = Observer::Create([] (const MyClass& obj)
430-
{
431-
printf("aa %d\n", obj.hello);
432-
}, ref);
396+
auto d1 = StateVar<string>::Create(g, "Data1");
397+
auto d2 = StateVar<string>::Create(g, "Data2");
398+
auto d3 = StateVar<string>::Create(g, "Data3");
433399

434-
auto flat = FlattenObject(st);
400+
auto allData = { CreateRef(d1), CreateRef(d2), CreateRef(d3) };
435401

436-
auto flat2 = FlattenObject(ref);
402+
auto objects = StateVar<vector<StateRef<string>>>::Create(g);
437403

438-
auto obs = Observer::Create([] (const MyClass::Flat& obj)
404+
auto obs = Observer::Create([] (const auto& flatList)
405+
{
406+
cout << "Objects: ";
407+
for (const string& s : flatList)
408+
cout << s << " ";
409+
cout << endl;
410+
}, FlattenList(objects));
411+
// Objects:
412+
413+
objects.Modify([&] (auto& w)
439414
{
440-
int x = *obj.a;
441-
int y = *obj.b;
442-
printf("%d\n", x);
443-
printf("%d\n", y);
444-
}, flat2);
415+
w.push_back(CreateRef(w1));
416+
});
417+
// Objects: Widget1
418+
419+
w1.Set("Widget1 (x)");
420+
// Objects: Widget1 (x)
445421

422+
objects.Set(allWidgets);
423+
// Objects: Widget1 (x) Widget2 Widget3
446424

447-
GetInternals(st).Value().a.Set(999);
425+
objects.Set(allData);
426+
// Objects: Data1 Data2 Data3
427+
428+
w2.Set("Widget2 (x)");
429+
430+
g.DoTransaction([&]
431+
{
432+
w3.Set("Widget3 (x)");
448433

449-
MyClass a2{ };
450-
a2.hello = 3333;
434+
d1.Set("Data1 (x)");
435+
d2.Set("Data2 (x)");
451436

452-
st.Set(a2);
453-
st.Set(a2);
437+
objects.Set(allWidgets);
438+
});
439+
// Objects: Widget1 (x) Widget2 (x) Widget3 (x)
454440

441+
objects.Modify([&] (auto& w)
442+
{
443+
w.clear();
444+
w.insert(end(w), allWidgets);
445+
w.insert(end(w), allData);
446+
});
447+
// Objects: Widget1 (x) Widget2 (x) Widget3 (x) Data1 (x) Data2 (x) Data3
448+
455449
}
456450

451+
class Office;
452+
class Company;
453+
class Employee;
454+
455+
//----
456+
class Office
457+
{
458+
public:
459+
StateVar<string> location;
460+
461+
StateVar<vector<State<Employee>>> employees;
462+
463+
State<int> employeeCount = State<int>::Create(CalcEmployeeCount, FlattenList(employees));
464+
465+
struct Flat;
466+
467+
private:
468+
static int CalcEmployeeCount(const vector<Employee>& offices)
469+
{ return offices.size(); }
470+
};
471+
472+
struct Office::Flat : public Flattened<Office>
473+
{
474+
using Flattened::Flattened;
475+
476+
int employeeCount = this->Flatten(Office::employeeCount);
477+
};
478+
479+
//----
480+
class Employee
481+
{
482+
public:
483+
StateVar<string> name;
484+
485+
StateRef<Office> office;
486+
487+
struct Flat;
488+
489+
private:
490+
};
491+
492+
struct Employee::Flat : public Flattened<Employee>
493+
{
494+
using Flattened::Flattened;
495+
496+
Ref<string> name = this->Flatten(Employee::name);
497+
Ref<Office> office = this->Flatten(Employee::office);
498+
};
499+
500+
//----
501+
class Company
502+
{
503+
public:
504+
StateVar<vector<State<Office>>> offices;
505+
506+
State<int> employeeCount;
507+
508+
struct Flat;
509+
510+
private:
511+
static int CalcEmployeeCount(const vector<Office::Flat>& offices)
512+
{
513+
int count = 0;
514+
515+
for (const auto& office : offices)
516+
count += office.employeeCount;
517+
518+
return count;
519+
}
520+
};
521+
522+
struct Company::Flat : public Flattened<Company>
523+
{
524+
using Flattened::Flattened;
525+
526+
Ref<vector<State<Office>>> offices = this->Flatten(Company::offices);
527+
int employeeCount = this->Flatten(Company::employeeCount);
528+
};
529+
457530
///////////////////////////////////////////////////////////////////////////////////////////////////
458531
/// Run examples
459532
///////////////////////////////////////////////////////////////////////////////////////////////////

tests/src/algorithm_tests.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,3 +714,74 @@ TEST(AlgorithmTest, IterateByRefWithState)
714714
EXPECT_EQ(turns2, 4);
715715
}
716716
}
717+
718+
Group flattenGroup;
719+
720+
class FlattenDummy
721+
{
722+
public:
723+
StateVar<int> value1 = StateVar<int>::Create(flattenGroup, 10);
724+
StateVar<int> value2 = StateVar<int>::Create(flattenGroup, 20);
725+
726+
bool operator==(const FlattenDummy& other) const
727+
{ return value1 == other.value1 && value2 == other.value2; }
728+
729+
struct Flat;
730+
};
731+
732+
struct FlattenDummy::Flat : public Flattened<FlattenDummy>
733+
{
734+
using Flattened::Flattened;
735+
736+
Ref<int> value1 = this->Flatten(FlattenDummy::value1);
737+
Ref<int> value2 = this->Flatten(FlattenDummy::value2);
738+
};
739+
740+
TEST(AlgorithmTest, FlattenObject1)
741+
{
742+
Group g;
743+
744+
FlattenDummy o1;
745+
FlattenDummy o2;
746+
747+
auto outer = StateVar<FlattenDummy>::Create(flattenGroup, o1);
748+
auto flat = FlattenObject(outer);
749+
750+
int turns = 0;
751+
int output1 = 0;
752+
int output2 = 0;
753+
754+
auto obs = Observer::Create([&] (const FlattenDummy::Flat& v)
755+
{
756+
++turns;
757+
output1 = v.value1;
758+
output2 = v.value2;
759+
}, flat);
760+
761+
EXPECT_EQ(turns, 1);
762+
EXPECT_EQ(output1, 10);
763+
EXPECT_EQ(output2, 20);
764+
765+
o1.value1.Set(30);
766+
o1.value2.Set(40);
767+
768+
EXPECT_EQ(turns, 3);
769+
EXPECT_EQ(output1, 30);
770+
EXPECT_EQ(output2, 40);
771+
772+
outer.Set(o2);
773+
774+
EXPECT_EQ(turns, 4);
775+
EXPECT_EQ(output1, 10);
776+
EXPECT_EQ(output2, 20);
777+
778+
o1.value1.Set(300);
779+
o1.value2.Set(400);
780+
781+
o2.value1.Set(500);
782+
o2.value2.Set(600);
783+
784+
EXPECT_EQ(turns, 6);
785+
EXPECT_EQ(output1, 500);
786+
EXPECT_EQ(output2, 600);
787+
}

0 commit comments

Comments
 (0)