@@ -162,6 +162,27 @@ struct untyped_signal_base
162
162
// Clear the signal.
163
163
virtual void
164
164
clear () const = 0 ;
165
+
166
+ // WARNING: EXPERIMENTAL VALIDATION STUFF FOLLOWS...
167
+
168
+ // Handle a validation error.
169
+ //
170
+ // This is called when there's an attempt to write to the signal and a
171
+ // validation_error is thrown. (The argument is the error.)
172
+ //
173
+ // The return value should be true iff the validation error was handled.
174
+ //
175
+ virtual bool invalidate (std::exception_ptr) const
176
+ {
177
+ return false ;
178
+ }
179
+
180
+ // Is this signal currently invalidated?
181
+ virtual bool
182
+ is_invalidated () const
183
+ {
184
+ return false ;
185
+ }
165
186
};
166
187
167
188
template <class Value >
@@ -371,6 +392,16 @@ struct signal_ref
371
392
{
372
393
ref_->write (std::move (value));
373
394
}
395
+ bool
396
+ invalidate (std::exception_ptr error) const override
397
+ {
398
+ return ref_->invalidate (error);
399
+ }
400
+ bool
401
+ is_invalidated () const override
402
+ {
403
+ return ref_->is_invalidated ();
404
+ }
374
405
375
406
private:
376
407
signal_interface<Value> const * ref_;
@@ -441,37 +472,6 @@ read_signal(Signal const& signal)
441
472
return signal.read ();
442
473
}
443
474
444
- // signal_is_clearable<Signal>::value yields a compile-time boolean indicating
445
- // whether or not the given signal type supports clearing.
446
- template <class Signal >
447
- struct signal_is_clearable : signal_capability_level_is_compatible<
448
- signal_clearable,
449
- Signal::capabilities::writing>
450
- {
451
- };
452
-
453
- // is_clearable_signal_type<T>::value yields a compile-time boolean indicating
454
- // whether or not T is an alia signal that supports clearing.
455
- template <class T >
456
- struct is_clearable_signal_type : std::conditional_t <
457
- is_signal_type<T>::value,
458
- signal_is_clearable<T>,
459
- std::false_type>
460
- {
461
- };
462
-
463
- // Clear a signal's value.
464
- // Unlike calling signal.clear() directly, this will generate a compile-time
465
- // error if the signal's type doesn't support clearing.
466
- // Note that if the signal isn't ready to write, this is a no op.
467
- template <class Signal >
468
- std::enable_if_t <signal_is_clearable<Signal>::value>
469
- clear_signal (Signal const & signal)
470
- {
471
- if (signal.ready_to_write ())
472
- signal.clear ();
473
- }
474
-
475
475
// When a value is written to a signal, the signal is allowed to throw a
476
476
// validation_error if the value isn't acceptable.
477
477
struct validation_error : exception
@@ -529,9 +529,12 @@ write_signal(Signal const& signal, Value value)
529
529
}
530
530
catch (validation_error&)
531
531
{
532
- // EXPERIMENTAL VALIDATION LOGIC
533
- if constexpr (signal_is_clearable<Signal>::value)
534
- clear_signal (signal);
532
+ // EXPERIMENTAL VALIDATION LOGIC: Try to let the signal handle the
533
+ // validation error (at some level). If it can't, rethrow the
534
+ // exception.
535
+ auto e = std::current_exception ();
536
+ if (!signal.invalidate (e))
537
+ std::rethrow_exception (e);
535
538
}
536
539
}
537
540
}
@@ -627,6 +630,37 @@ forward_signal(Signal const& signal)
627
630
return signal.read ();
628
631
}
629
632
633
+ // signal_is_clearable<Signal>::value yields a compile-time boolean indicating
634
+ // whether or not the given signal type supports clearing.
635
+ template <class Signal >
636
+ struct signal_is_clearable : signal_capability_level_is_compatible<
637
+ signal_clearable,
638
+ Signal::capabilities::writing>
639
+ {
640
+ };
641
+
642
+ // is_clearable_signal_type<T>::value yields a compile-time boolean indicating
643
+ // whether or not T is an alia signal that supports clearing.
644
+ template <class T >
645
+ struct is_clearable_signal_type : std::conditional_t <
646
+ is_signal_type<T>::value,
647
+ signal_is_clearable<T>,
648
+ std::false_type>
649
+ {
650
+ };
651
+
652
+ // Clear a signal's value.
653
+ // Unlike calling signal.clear() directly, this will generate a compile-time
654
+ // error if the signal's type doesn't support clearing.
655
+ // Note that if the signal isn't ready to write, this is a no op.
656
+ template <class Signal >
657
+ std::enable_if_t <signal_is_clearable<Signal>::value>
658
+ clear_signal (Signal const & signal)
659
+ {
660
+ if (signal.ready_to_write ())
661
+ signal.clear ();
662
+ }
663
+
630
664
} // namespace alia
631
665
632
666
#endif
0 commit comments