Skip to content

Commit 3aae4a8

Browse files
committed
Do not store default values in gshow files
1 parent 71492ea commit 3aae4a8

File tree

6 files changed

+127
-65
lines changed

6 files changed

+127
-65
lines changed

system/jsonreader.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ inline unsigned OptionalUInt(const Object &parent, const char *name,
125125
return iter == parent.end() ? default_value : ToNum(*iter).AsUInt();
126126
}
127127

128+
inline int OptionalInt(const Object &parent, const char *name,
129+
int default_value) {
130+
const Object::const_iterator iter = parent.find(name);
131+
return iter == parent.end() ? default_value : ToNum(*iter).AsInt();
132+
}
133+
128134
inline double OptionalDouble(const Object &parent, const char *name,
129135
double default_value) {
130136
const Object::const_iterator iter = parent.find(name);

system/jsonwriter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ class JsonWriter {
5757
Number(number);
5858
}
5959

60+
template <typename T>
61+
void OptionalNumber(const char* name, T number, T default_value = T(0)) {
62+
if (number != default_value) {
63+
Name(name);
64+
Number(number);
65+
}
66+
}
67+
6068
void Number(double number) { NumberGeneric(number); }
6169

6270
void Number(int number) { IntegerNumber(number); }

system/reader.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ void ParseFixtureTypes(const json::Array &node, Management &management) {
198198

199199
DmxChannel ParseDmxChannel(const Object &node) {
200200
DmxChannel channel;
201-
channel.SetUniverse(ToNum(node["universe"]).AsInt());
202-
channel.SetChannel(ToNum(node["channel"]).AsInt());
201+
channel.SetUniverse(OptionalUInt(node, "universe", 0));
202+
channel.SetChannel(ToNum(node["channel"]).AsUInt());
203203
return channel;
204204
}
205205

@@ -305,9 +305,9 @@ void ParsePresetCollection(const Object &node, Management &management) {
305305
const Array &values = ToArr(node["values"]);
306306
for (const Node &value : values) {
307307
const Object &v = ToObj(value);
308-
Folder &folder = *management.Folders()[ToNum(v["folder"]).AsSize()];
308+
Folder &folder = *management.Folders()[OptionalSize(v, "folder", 0)];
309309
FolderObject &obj = folder.GetChild(ToStr(v["controllable-ref"]));
310-
const size_t inputIndex = ToNum(v["input-index"]).AsSize();
310+
const size_t inputIndex = OptionalSize(v, "input-index", 0);
311311
Controllable *controllable = dynamic_cast<Controllable *>(&obj);
312312
if (controllable == nullptr)
313313
throw std::runtime_error(
@@ -325,8 +325,8 @@ void ParseSequence(const Object &node, Sequence &sequence,
325325
const Array &inputs = ToArr(node["inputs"]);
326326
for (Node &item_node : inputs) {
327327
const Object &item = ToObj(item_node);
328-
size_t input = ToNum(item["input-index"]).AsSize();
329-
size_t folderId = ToNum(item["folder"]).AsSize();
328+
size_t input = OptionalSize(item, "input-index", 0);
329+
size_t folderId = OptionalSize(item, "folder", 0);
330330
Controllable &c = dynamic_cast<Controllable &>(
331331
management.Folders()[folderId]->GetChild(ToStr(item["name"])));
332332
sequence.Add(c, input);
@@ -419,8 +419,8 @@ void ParseEffect(const Object &node, Management &management) {
419419
for (const Node &item : connections) {
420420
const Object &c_node = ToObj(item);
421421
const std::string &cName = ToStr(c_node["name"]);
422-
const size_t cInputIndex = ToNum(c_node["input-index"]).AsSize();
423-
const size_t folderId = ToNum(c_node["folder"]).AsSize();
422+
const size_t cInputIndex = OptionalSize(c_node, "input-index", 0);
423+
const size_t folderId = OptionalSize(c_node, "folder", 0);
424424
Folder *folder = management.Folders()[folderId].Get();
425425
effect.AddConnection(dynamic_cast<Controllable &>(folder->GetChild(cName)),
426426
cInputIndex);
@@ -435,7 +435,7 @@ KeySceneItem &ParseKeySceneItem(const Object &node, Scene &scene) {
435435

436436
ControlSceneItem &ParseControlSceneItem(const Object &node, Scene &scene,
437437
Management &management) {
438-
const size_t folderId = ToNum(node["folder"]).AsSize();
438+
const size_t folderId = OptionalSize(node, "folder", 0);
439439
Folder *folder = management.Folders()[folderId].Get();
440440
Controllable &controllable = static_cast<Controllable &>(
441441
folder->GetChild(ToStr(node["controllable-ref"])));
@@ -500,21 +500,21 @@ void ParseControls(const Array &node, Management &management) {
500500

501501
SingleSourceValue ParseSingleSourceValue(const Object &object) {
502502
SingleSourceValue result;
503-
result.SetValue(ControlValue(ToNum(object["value"]).AsUInt()));
504-
result.SetTargetValue(ToNum(object["target-value"]).AsUInt());
505-
result.SetFadeSpeed(ToNum(object["fade-speed"]).AsDouble());
503+
result.SetValue(ControlValue(OptionalUInt(object, "value", 0)));
504+
result.SetTargetValue(OptionalUInt(object, "target-value", 0));
505+
result.SetFadeSpeed(OptionalUInt(object, "fade-speed", 0.0));
506506
return result;
507507
}
508508

509509
void ParseSourceValues(const Array &node, Management &management) {
510510
for (const Node &element : node) {
511511
const Object &object = ToObj(element);
512-
size_t folderId = ToNum(object["folder"]).AsSize();
512+
size_t folderId = OptionalSize(object, "folder", 0);
513513
const std::string name = ToStr(object["controllable-ref"]);
514514
Folder *folder = management.Folders()[folderId].Get();
515515
Controllable &controllable =
516516
dynamic_cast<Controllable &>(folder->GetChild(name));
517-
const size_t inputIndex = ToNum(object["input-index"]).AsSize();
517+
const size_t inputIndex = OptionalSize(object, "input-index", 0);
518518
SourceValue &value = management.AddSourceValue(controllable, inputIndex);
519519
value.A() = ParseSingleSourceValue(ToObj(object["a"]));
520520
value.B() = ParseSingleSourceValue(ToObj(object["b"]));
@@ -525,8 +525,8 @@ void ParseGuiPresetRef(const Object &node, gui::FaderSetState &fader,
525525
Management &management) {
526526
if (node.contains("name")) {
527527
// Old way of storing inputs ; support to be removed at a later time
528-
const size_t input = ToNum(node["input-index"]).AsSize();
529-
const size_t folder_id = ToNum(node["folder"]).AsSize();
528+
const size_t input = OptionalSize(node, "input-index", 0);
529+
const size_t folder_id = OptionalSize(node, "folder", 0);
530530
const std::string name = ToStr(node["name"]);
531531
Folder *folder = management.Folders()[folder_id].Get();
532532
Controllable &controllable =
@@ -540,8 +540,8 @@ void ParseGuiPresetRef(const Object &node, gui::FaderSetState &fader,
540540
for (const Node &source_value_item : source_value_node) {
541541
const Object &object = ToObj(source_value_item);
542542
if (object.contains("name")) {
543-
const size_t input = ToNum(object["input-index"]).AsSize();
544-
const size_t folder_id = ToNum(object["folder"]).AsSize();
543+
const size_t input = OptionalSize(object, "input-index", 0);
544+
const size_t folder_id = OptionalSize(object, "folder", 0);
545545
const std::string name = ToStr(object["name"]);
546546
Folder *folder = management.Folders()[folder_id].Get();
547547
Controllable &controllable =

system/writer.cpp

Lines changed: 60 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ void writeFolderAttributes(WriteState &state, const FolderObject &obj) {
9494
void writeDmxChannel(WriteState &state, const DmxChannel &dmxChannel,
9595
const char *name) {
9696
state.writer.StartObject(name);
97-
state.writer.Number("universe", dmxChannel.Universe());
97+
if (dmxChannel.Universe() != 0)
98+
state.writer.Number("universe", dmxChannel.Universe());
9899
state.writer.Number("channel", dmxChannel.Channel());
99100
state.writer.EndObject();
100101
}
@@ -248,19 +249,23 @@ void writeFixtureType(WriteState &state, const FixtureType &fixture_type) {
248249

249250
void writeSingleSourceValue(WriteState &state,
250251
const SingleSourceValue &singleSourceValue) {
251-
state.writer.Number("value", singleSourceValue.Value().UInt());
252-
state.writer.Number("target-value", singleSourceValue.TargetValue());
253-
state.writer.Number("fade-speed", singleSourceValue.FadeSpeed());
252+
if (singleSourceValue.Value())
253+
state.writer.Number("value", singleSourceValue.Value().UInt());
254+
if (singleSourceValue.TargetValue())
255+
state.writer.Number("target-value", singleSourceValue.TargetValue());
256+
if (singleSourceValue.FadeSpeed() != 0.0)
257+
state.writer.Number("fade-speed", singleSourceValue.FadeSpeed());
254258
}
255259

256260
void writeSourceValue(WriteState &state, const SourceValue &sourceValue) {
257261
writeControllable(state, sourceValue.GetControllable());
258262

259263
state.writer.StartObject();
260264
state.writer.String("controllable-ref", sourceValue.GetControllable().Name());
261-
state.writer.Number("input-index", sourceValue.InputIndex());
262-
state.writer.Number("folder",
263-
state.folderIds[&sourceValue.GetControllable().Parent()]);
265+
if (sourceValue.InputIndex())
266+
state.writer.Number("input-index", sourceValue.InputIndex());
267+
state.writer.OptionalNumber(
268+
"folder", state.folderIds[&sourceValue.GetControllable().Parent()]);
264269
state.writer.StartObject("a");
265270
writeSingleSourceValue(state, sourceValue.A());
266271
state.writer.EndObject();
@@ -275,9 +280,10 @@ void writePresetValue(WriteState &state, const PresetValue &presetValue) {
275280

276281
state.writer.StartObject();
277282
state.writer.String("controllable-ref", presetValue.GetControllable().Name());
278-
state.writer.Number("input-index", presetValue.InputIndex());
279-
state.writer.Number("folder",
280-
state.folderIds[&presetValue.GetControllable().Parent()]);
283+
if (presetValue.InputIndex())
284+
state.writer.Number("input-index", presetValue.InputIndex());
285+
state.writer.OptionalNumber(
286+
"folder", state.folderIds[&presetValue.GetControllable().Parent()]);
281287
state.writer.Number("value", presetValue.Value().UInt());
282288
state.writer.EndObject();
283289
}
@@ -338,9 +344,10 @@ void writeSequence(WriteState &state, const Sequence &sequence) {
338344
state.writer.StartArray("inputs");
339345
for (const Input &input : sequence.List()) {
340346
state.writer.StartObject();
341-
state.writer.Number("input-index", input.InputIndex());
342-
state.writer.Number("folder",
343-
state.folderIds[&input.GetControllable()->Parent()]);
347+
if (input.InputIndex())
348+
state.writer.Number("input-index", input.InputIndex());
349+
state.writer.OptionalNumber(
350+
"folder", state.folderIds[&input.GetControllable()->Parent()]);
344351
state.writer.String("name", input.GetControllable()->Name());
345352
state.writer.EndObject();
346353
}
@@ -396,44 +403,51 @@ void writeEffect(WriteState &state, const Effect &effect) {
396403
state.writer.String("effect_type", EffectTypeToName(effect.GetType()));
397404
std::unique_ptr<PropertySet> ps = PropertySet::Make(effect);
398405

406+
std::unique_ptr<Effect> default_effect = Effect::Make(effect.GetType());
407+
399408
// the number and name of the effect controls are implied from the
400409
// effect type, so do not require to be stored.
401410

402411
state.writer.StartArray("properties");
403412
for (const Property &p : *ps) {
404-
state.writer.StartObject();
405-
state.writer.String("name", p.Name());
406-
switch (p.GetType()) {
407-
case PropertyType::Choice:
408-
state.writer.String("value", ps->GetChoice(p));
409-
break;
410-
case PropertyType::ControlValue:
411-
state.writer.Number("value", ps->GetControlValue(p));
412-
break;
413-
case PropertyType::Duration:
414-
state.writer.Number("value", ps->GetDuration(p));
415-
break;
416-
case PropertyType::Boolean:
417-
state.writer.Boolean("value", ps->GetBool(p));
418-
break;
419-
case PropertyType::Integer:
420-
state.writer.Number("value", ps->GetInteger(p));
421-
break;
422-
case PropertyType::TimePattern:
423-
state.writer.String("value", ToString(ps->GetTimePattern(p)));
424-
break;
425-
case PropertyType::Transition:
426-
writeTransition(state, ps->GetTransition(p), "value");
427-
break;
413+
const bool has_default_value =
414+
ps->EqualPropertyValues(p, *default_effect);
415+
if (!has_default_value) {
416+
state.writer.StartObject();
417+
state.writer.String("name", p.Name());
418+
switch (p.GetType()) {
419+
case PropertyType::Choice:
420+
state.writer.String("value", ps->GetChoice(p));
421+
break;
422+
case PropertyType::ControlValue:
423+
state.writer.Number("value", ps->GetControlValue(p));
424+
break;
425+
case PropertyType::Duration:
426+
state.writer.Number("value", ps->GetDuration(p));
427+
break;
428+
case PropertyType::Boolean:
429+
state.writer.Boolean("value", ps->GetBool(p));
430+
break;
431+
case PropertyType::Integer:
432+
state.writer.Number("value", ps->GetInteger(p));
433+
break;
434+
case PropertyType::TimePattern:
435+
state.writer.String("value", ToString(ps->GetTimePattern(p)));
436+
break;
437+
case PropertyType::Transition:
438+
writeTransition(state, ps->GetTransition(p), "value");
439+
break;
440+
}
441+
state.writer.EndObject();
428442
}
429-
state.writer.EndObject();
430443
}
431444
state.writer.EndArray(); // properties
432445
state.writer.StartArray("connections");
433446
for (const std::pair<Controllable *, size_t> &c : effect.Connections()) {
434447
state.writer.StartObject();
435-
state.writer.Number("input-index", c.second);
436-
state.writer.Number("folder", state.folderIds[&c.first->Parent()]);
448+
if (c.second) state.writer.Number("input-index", c.second);
449+
state.writer.OptionalNumber("folder",
450+
state.folderIds[&c.first->Parent()]);
437451
state.writer.String("name", c.first->Name());
438452
state.writer.EndObject();
439453
}
@@ -453,8 +467,8 @@ void writeControlSceneItem(WriteState &state, const ControlSceneItem &item) {
453467
state.writer.Number("start-value", item.StartValue().UInt());
454468
state.writer.Number("end-value", item.EndValue().UInt());
455469
state.writer.String("controllable-ref", item.GetControllable().Name());
456-
state.writer.Number("folder",
457-
state.folderIds[&item.GetControllable().Parent()]);
470+
state.writer.OptionalNumber(
471+
"folder", state.folderIds[&item.GetControllable().Parent()]);
458472
}
459473

460474
void writeBlackoutSceneItem(WriteState &state, const BlackoutSceneItem &item) {
@@ -552,10 +566,11 @@ void writeFaderState(WriteState &state, const gui::FaderState &fader) {
552566
for (SourceValue *source : sources) {
553567
state.writer.StartObject();
554568
if (source != nullptr) {
555-
state.writer.Number("folder",
556-
state.folderIds[&source->GetControllable().Parent()]);
569+
state.writer.OptionalNumber(
570+
"folder", state.folderIds[&source->GetControllable().Parent()]);
557571
state.writer.String("name", source->GetControllable().Name());
558-
state.writer.Number("input-index", source->InputIndex());
572+
if (source->InputIndex())
573+
state.writer.Number("input-index", source->InputIndex());
559574
}
560575
state.writer.EndObject();
561576
}

theatre/properties/propertyset.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "propertyset.h"
22

3+
#include <cassert>
4+
35
#include "audioleveleffectps.h"
46
#include "colorcontroleffectps.h"
57
#include "colortemperatureeffectps.h"
@@ -69,8 +71,7 @@ std::unique_ptr<PropertySet> PropertySet::Make(FolderObject &object) {
6971

7072
void PropertySet::AssignProperty(const Property &to, const Property &from,
7173
const PropertySet &fromSet) {
72-
if (from.type_ != to.type_)
73-
throw std::runtime_error("Copying different types");
74+
assert(from.type_ == to.type_);
7475
switch (from.type_) {
7576
case PropertyType::Boolean:
7677
SetBool(to, fromSet.GetBool(from));
@@ -96,4 +97,30 @@ void PropertySet::AssignProperty(const Property &to, const Property &from,
9697
}
9798
}
9899

100+
bool PropertySet::EqualPropertyValues(const Property &property,
101+
const Effect &rhs) {
102+
assert(dynamic_cast<Effect *>(_object));
103+
const Effect &effect = static_cast<const Effect &>(*_object);
104+
assert(effect.GetType() == rhs.GetType());
105+
switch (property.type_) {
106+
case PropertyType::Boolean:
107+
return GetBool(property) == getBool(rhs, property.set_index_);
108+
case PropertyType::Choice:
109+
return GetChoice(property) == getChoice(rhs, property.set_index_);
110+
case PropertyType::ControlValue:
111+
return GetControlValue(property) ==
112+
getControlValue(rhs, property.set_index_);
113+
case PropertyType::Duration:
114+
return GetDuration(property) == getDuration(rhs, property.set_index_);
115+
case PropertyType::Integer:
116+
return GetInteger(property) == getInteger(rhs, property.set_index_);
117+
case PropertyType::TimePattern:
118+
return GetTimePattern(property) ==
119+
getTimePattern(rhs, property.set_index_);
120+
case PropertyType::Transition:
121+
return GetTransition(property) == getTransition(rhs, property.set_index_);
122+
}
123+
return false;
124+
}
125+
99126
} // namespace glight::theatre

theatre/properties/propertyset.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ class TimePattern;
1717

1818
namespace glight::theatre {
1919

20+
/**
21+
* A property set describes the properties of an object, and knows how to
22+
* get and set the values. It also keeps a pointer to the object itself.
23+
*/
2024
class PropertySet {
2125
public:
2226
using iterator = std::vector<Property>::iterator;
@@ -111,6 +115,8 @@ class PropertySet {
111115
void AssignProperty(const Property &to, const Property &from,
112116
const PropertySet &fromSet);
113117

118+
bool EqualPropertyValues(const Property &property, const Effect &rhs);
119+
114120
protected:
115121
/**
116122
* Set the property

0 commit comments

Comments
 (0)