Skip to content

Commit b971fb3

Browse files
committed
Allow write() to return new value ID
1 parent 906c686 commit b971fb3

File tree

13 files changed

+75
-49
lines changed

13 files changed

+75
-49
lines changed

src/alia/flow/actions.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,11 +604,11 @@ struct write_action_signal : signal_wrapper<
604604
{
605605
return this->wrapped_.ready_to_write() && on_write_.is_ready();
606606
}
607-
void
607+
id_interface const&
608608
write(typename Wrapped::value_type value) const
609609
{
610610
perform_action(on_write_, value);
611-
this->wrapped_.write(std::move(value));
611+
return this->wrapped_.write(std::move(value));
612612
}
613613

614614
private:

src/alia/flow/for_each.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,10 +354,11 @@ struct list_item_signal : signal<
354354
{
355355
return list_signal_.ready_to_write();
356356
}
357-
void
357+
id_interface const&
358358
write(Item value) const
359359
{
360360
*item_ = std::move(value);
361+
return null_id;
361362
}
362363

363364
private:

src/alia/signals/adaptors.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,9 @@ struct writability_faker : signal_wrapper<
9595
}
9696
// Since this is only faking writability, write() should never be called.
9797
// LCOV_EXCL_START
98-
void write(typename Wrapped::value_type) const override
98+
id_interface const& write(typename Wrapped::value_type) const override
9999
{
100+
return null_id;
100101
}
101102
// LCOV_EXCL_STOP
102103
};
@@ -140,7 +141,7 @@ struct casting_signal : casting_signal_wrapper<
140141
value_ = this->move_out();
141142
return value_;
142143
}
143-
void
144+
id_interface const&
144145
write(To value) const override
145146
{
146147
return this->wrapped_.write(
@@ -591,10 +592,10 @@ struct unwrapper_signal : casting_signal_wrapper<
591592
else
592593
return null_id;
593594
}
594-
void
595+
id_interface const&
595596
write(typename Wrapped::value_type::value_type value) const override
596597
{
597-
this->wrapped_.write(std::move(value));
598+
return this->wrapped_.write(std::move(value));
598599
}
599600
void
600601
clear() const override

src/alia/signals/application.hpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ struct lazy_duplex_apply_signal
145145
{
146146
return arg_.ready_to_write();
147147
}
148-
void
148+
id_interface const&
149149
write(Result value) const
150150
{
151-
arg_.write(reverse_(std::move(value)));
151+
return arg_.write(reverse_(std::move(value)));
152152
}
153153

154154
private:
@@ -429,24 +429,29 @@ struct duplex_apply_signal : signal<
429429
{
430430
return input_.ready_to_write();
431431
}
432-
void
432+
id_interface const&
433433
write(Value value) const
434434
{
435-
input_.write(reverse_(value));
436-
// This is sort of hackish, but the idea here is that if we do nothing
437-
// right now, on the next refresh, we're going to detect that the input
438-
// signal has changed, and then apply the forward mapping to convert
439-
// that value back to the one we're writing right now, which is
440-
// obviously wasted effort.
441-
// To attempt to avoid this, we capture the value ID of the input after
442-
// writing to it in the hopes that it has already changed. (That is the
443-
// case for some signal types, but not all.)
444-
// To do this properly, we should probably allow signal write()
445-
// functions to return a new value ID.
446-
data_->input_id.capture(input_.value_id());
447-
++data_->result.version;
448-
data_->result.value = std::move(value);
449-
data_->result.status = apply_status::READY;
435+
id_interface const& new_value_id = input_.write(reverse_(value));
436+
// If we stop here, then on the next refresh, we're going to detect
437+
// that the input signal has changed (to what we just set it to), and
438+
// then apply the forward mapping to convert that value back to the one
439+
// we just received, which is obviously wasted effort. To avoid this,
440+
// we need to just record the new value as our ouput and record the
441+
// input's new value ID to go along with it. (This is only possible
442+
// though if the input signal actually supplies its new value ID.)
443+
if (new_value_id != null_id)
444+
{
445+
data_->input_id.capture(new_value_id);
446+
++data_->result.version;
447+
data_->result.value = std::move(value);
448+
data_->result.status = apply_status::READY;
449+
return this->value_id();
450+
}
451+
else
452+
{
453+
return null_id;
454+
}
450455
}
451456

452457
private:

src/alia/signals/basic.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ struct empty_signal
5858
}
5959
// Since this is never ready to write, none of this should ever be called.
6060
// LCOV_EXCL_START
61-
void write(Value) const override
61+
id_interface const& write(Value) const override
6262
{
63+
return null_id;
6364
}
6465
void
6566
clear() const override
@@ -236,10 +237,11 @@ struct direct_signal
236237
{
237238
return true;
238239
}
239-
void
240+
id_interface const&
240241
write(Value value) const override
241242
{
242243
*v_ = std::move(value);
244+
return this->value_id();
243245
}
244246

245247
private:

src/alia/signals/core.hpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,10 @@ struct signal_interface : untyped_signal_base
207207
destructive_ref() const = 0;
208208

209209
// Write the signal's value.
210-
virtual void
210+
// The signal can *optionally* return the new value ID of the signal (after
211+
// taking on the value that was written in by this call). If this is
212+
// impractical, it can just return null_id instead.
213+
virtual id_interface const&
211214
write(Value value) const = 0;
212215
};
213216

@@ -243,8 +246,9 @@ struct signal : signal_base<Derived, Value, Capabilities>
243246
{ \
244247
return false; \
245248
} \
246-
void write(Value) const override \
249+
id_interface const& write(Value) const override \
247250
{ \
251+
return null_id; \
248252
}
249253

250254
#define ALIA_DEFINE_UNUSED_SIGNAL_MOVE_INTERFACE(Value) \
@@ -387,10 +391,10 @@ struct signal_ref
387391
{
388392
return ref_->ready_to_write();
389393
}
390-
void
394+
id_interface const&
391395
write(Value value) const override
392396
{
393-
ref_->write(std::move(value));
397+
return ref_->write(std::move(value));
394398
}
395399
bool
396400
invalidate(std::exception_ptr error) const override
@@ -518,14 +522,14 @@ signal_ready_to_write(Signal const& signal)
518522
// error if the signal's type doesn't support writing.
519523
// Note that if the signal isn't ready to write, this is a no op.
520524
template<class Signal, class Value>
521-
std::enable_if_t<signal_is_writable<Signal>::value>
525+
std::enable_if_t<signal_is_writable<Signal>::value, id_interface const&>
522526
write_signal(Signal const& signal, Value value)
523527
{
524528
if (signal.ready_to_write())
525529
{
526530
try
527531
{
528-
signal.write(std::move(value));
532+
return signal.write(std::move(value));
529533
}
530534
catch (validation_error&)
531535
{
@@ -537,6 +541,7 @@ write_signal(Signal const& signal, Value value)
537541
std::rethrow_exception(e);
538542
}
539543
}
544+
return null_id;
540545
}
541546

542547
// signal_is_duplex<Signal>::value yields a compile-time boolean indicating

src/alia/signals/lambdas.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,10 +274,11 @@ struct lambda_duplex_signal
274274
{
275275
return ready_to_write_();
276276
}
277-
void
277+
id_interface const&
278278
write(Value value) const override
279279
{
280280
write_(std::move(value));
281+
return null_id;
281282
}
282283

283284
private:
@@ -369,10 +370,11 @@ struct lambda_duplex_signal_with_id : signal<
369370
{
370371
return ready_to_write_();
371372
}
372-
void
373+
id_interface const&
373374
write(Value value) const override
374375
{
375376
write_(std::move(value));
377+
return null_id;
376378
}
377379

378380
private:

src/alia/signals/numeric.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ struct scaled_signal
4848
{
4949
return this->wrapped_.ready_to_write() && scale_factor_.has_value();
5050
}
51-
void
51+
id_interface const&
5252
write(typename N::value_type value) const override
5353
{
5454
this->wrapped_.write(value / forward_signal(scale_factor_));
55+
return null_id;
5556
}
5657

5758
private:
@@ -108,10 +109,11 @@ struct offset_signal
108109
{
109110
return this->wrapped_.ready_to_write() && offset_.has_value();
110111
}
111-
void
112+
id_interface const&
112113
write(typename N::value_type value) const override
113114
{
114115
this->wrapped_.write(value - forward_signal(offset_));
116+
return null_id;
115117
}
116118

117119
private:
@@ -147,12 +149,13 @@ struct rounding_signal_wrapper
147149
{
148150
return this->wrapped_.ready_to_write() && step_.has_value();
149151
}
150-
void
152+
id_interface const&
151153
write(typename N::value_type value) const override
152154
{
153155
typename N::value_type step = step_.read();
154156
this->wrapped_.write(
155157
std::floor(value / step + typename N::value_type(0.5)) * step);
158+
return null_id;
156159
}
157160

158161
private:

src/alia/signals/operators.hpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -383,13 +383,14 @@ struct signal_mux : signal<
383383
&& (condition_.read() ? t_.ready_to_write()
384384
: f_.ready_to_write());
385385
}
386-
void
386+
id_interface const&
387387
write(typename T::value_type value) const override
388388
{
389389
if (condition_.read())
390390
t_.write(value);
391391
else
392392
f_.write(value);
393+
return null_id;
393394
}
394395
void
395396
clear() const override
@@ -493,12 +494,13 @@ struct field_signal : preferred_id_signal<
493494
{
494495
return structure_.has_value() && structure_.ready_to_write();
495496
}
496-
void
497+
id_interface const&
497498
write(Field x) const override
498499
{
499500
structure_type s = forward_signal(alia::move(structure_));
500501
s.*field_ = std::move(x);
501502
structure_.write(std::move(s));
503+
return null_id;
502504
}
503505

504506
private:
@@ -773,10 +775,11 @@ struct subscript_signal
773775
return container_.has_value() && index_.has_value()
774776
&& container_.ready_to_write();
775777
}
776-
void
778+
id_interface const&
777779
write(typename subscript_signal::value_type x) const override
778780
{
779781
write_subscript(container_, index_, std::move(x));
782+
return null_id;
780783
}
781784

782785
private:

src/alia/signals/state.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,11 @@ struct state_signal
186186
{
187187
return true;
188188
}
189-
void
189+
id_interface const&
190190
write(Value value) const override
191191
{
192192
data_->set(std::move(value));
193+
return this->value_id();
193194
}
194195
void
195196
clear() const override

0 commit comments

Comments
 (0)