@@ -94,7 +94,8 @@ void writeFolderAttributes(WriteState &state, const FolderObject &obj) {
9494void 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
249250void 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
256260void 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
460474void 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 }
0 commit comments