Skip to content

Commit 3be602b

Browse files
authored
Merge pull request #67 from bcmi-labs/getters-n-setters
Shared/Sink/Source: Provide getters/setter in addition to operator overloading.
2 parents b16f65c + 948fcd3 commit 3be602b

File tree

10 files changed

+54
-27
lines changed

10 files changed

+54
-27
lines changed

Diff for: docs/02-data-exchange.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ New values can be inserted naturally by using the assignment operator `=` as if
2020
2121
```C++
2222
/* Thread_1.inot */
23-
counter = 10; /* Store a value into the shared variable in a threadsafe manner. */
23+
counter.push(10); /* Store a value into the shared variable in a threadsafe manner. */
2424
```
2525
If the internal queue is full the oldest element is discarded and the latest element is inserted into the queue.
2626

2727
Retrieving stored data works also very naturally like it would for any POD data type:
2828
```C++
2929
/* Thread_2.inot */
30-
Serial.println(counter); /* Retrieves a value from the shared variable in a threadsafe manner. */
30+
Serial.println(counter.pop()); /* Retrieves a value from the shared variable in a threadsafe manner. */
3131
```
3232

3333
Should the internal queue be empty when trying to read the latest available value then the thread reading the shared variable will be suspended and the next available thread will be scheduled. Once a new value is stored inside the shared variable the suspended thread resumes operation and consumes the value which has been stored in the internal queue.
@@ -57,16 +57,16 @@ DataProducerThread.counter.connectTo(DataConsumerThread_2.counter);
5757
Whenever a new value is assigned to a data source, i.e.
5858
```C++
5959
/* DataProducerThread.inot */
60-
counter = 10;
60+
counter.push(10);
6161
```
6262
data is automatically copied and stored within the internal queues of all connected data sinks, from where it can be retrieved, i.e.
6363
```C++
6464
/* DataConsumerThread_1.inot */
65-
Serial.println(counter);
65+
Serial.println(counter.pop());
6666
```
6767
```C++
6868
/* DataConsumerThread_2.inot */
69-
Serial.println(counter);
69+
Serial.println(counter.pop());
7070
```
7171
If a thread tries to read from an empty `Sink` the thread is suspended and the next ready thread is scheduled. When a new value is written to a `Source` and consequently copied to a `Sink` the suspended thread is resumed and continuous execution (i.e. read the data and act upon it).
7272

Diff for: examples/Threading_Basics/Shared_Counter/Consumer.inot

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ void loop()
1212
* available, then this thread is suspended until new data
1313
* is available for reading.
1414
*/
15-
Serial.println(counter);
15+
Serial.println(counter.pop());
1616
}

Diff for: examples/Threading_Basics/Shared_Counter/Producer.inot

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ void loop()
1010
* 'counter'. Internally this is stored within a queue in a FIFO
1111
* (First-In/First-Out) manner.
1212
*/
13-
counter = i;
13+
counter.push(i);
1414
i++;
1515
delay(100);
1616
}

Diff for: examples/Threading_Basics/Source_Sink_Counter/Consumer.inot

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ void setup()
99

1010
void loop()
1111
{
12-
Serial.println(counter);
12+
Serial.println(counter.pop());
1313
}

Diff for: examples/Threading_Basics/Source_Sink_Counter/Producer.inot

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ void setup()
99
void loop()
1010
{
1111
static int i = 0;
12-
counter = i;
12+
counter.push(i);
1313
i++;
1414
}

Diff for: examples/Threading_Basics/Source_Sink_LED/Sink_Thread.inot

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ void loop()
1212
* this call will block until new data is inserted from the connected SOURCE. This means
1313
* that the pace is dictated by the SOURCE that sends data every 100 ms.
1414
*/
15-
digitalWrite(LED_BUILTIN, led);
15+
digitalWrite(LED_BUILTIN, led.pop());
1616
}

Diff for: examples/Threading_Basics/Source_Sink_LED/Source_Thread.inot

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ void setup()
88

99
void loop()
1010
{
11-
led = true;
11+
led.push(true);
1212
delay(100);
13-
led = false;
13+
led.push(false);
1414
delay(100);
1515
}

Diff for: src/threading/Shared.hpp

+20-6
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@ class Shared
4040
{
4141
public:
4242

43-
operator T();
44-
void operator = (T const & other);
43+
T pop();
44+
void push(T const & val);
4545
inline T peek() const { return _val; }
4646

47+
operator T() [[deprecated("Use 'pop()' instead.")]];
48+
void operator = (T const & val) [[deprecated("Use 'push()' instead.")]];
4749

4850
private:
4951

@@ -57,7 +59,7 @@ class Shared
5759
**************************************************************************************/
5860

5961
template<class T, size_t QUEUE_SIZE>
60-
Shared<T,QUEUE_SIZE>::operator T()
62+
T Shared<T,QUEUE_SIZE>::pop()
6163
{
6264
T * val_ptr = _mailbox.try_get_for(rtos::Kernel::wait_for_u32_forever);
6365
if (val_ptr)
@@ -70,7 +72,7 @@ Shared<T,QUEUE_SIZE>::operator T()
7072
}
7173

7274
template<class T, size_t QUEUE_SIZE>
73-
void Shared<T,QUEUE_SIZE>::operator = (T const & other)
75+
void Shared<T,QUEUE_SIZE>::push(T const & val)
7476
{
7577
/* If the mailbox is full we are discarding the
7678
* oldest element and then push the new one into
@@ -82,14 +84,26 @@ void Shared<T,QUEUE_SIZE>::operator = (T const & other)
8284
_mailbox.free(val_ptr);
8385
}
8486

85-
_val = other;
87+
_val = val;
8688

8789
T * val_ptr = _mailbox.try_alloc();
8890
if (val_ptr)
8991
{
90-
*val_ptr = other;
92+
*val_ptr = val;
9193
_mailbox.put(val_ptr);
9294
}
9395
}
9496

97+
template<class T, size_t QUEUE_SIZE>
98+
Shared<T,QUEUE_SIZE>::operator T()
99+
{
100+
return pop();
101+
}
102+
103+
template<class T, size_t QUEUE_SIZE>
104+
void Shared<T,QUEUE_SIZE>::operator = (T const & val)
105+
{
106+
push(val);
107+
}
108+
95109
#endif /* ARDUINO_THREADS_SHARED_HPP_ */

Diff for: src/threading/Sink.hpp

+10-5
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,13 @@ class SinkBase
3838

3939
virtual ~SinkBase() { }
4040

41-
virtual operator T() = 0;
41+
virtual T pop() = 0;
4242
virtual void inject(T const & value) = 0;
43+
44+
inline operator T() [[deprecated("Use 'pop()' instead.")]]
45+
{
46+
return pop();
47+
}
4348
};
4449

4550
template<typename T>
@@ -50,7 +55,7 @@ class SinkNonBlocking : public SinkBase<T>
5055
SinkNonBlocking() { }
5156
virtual ~SinkNonBlocking() { }
5257

53-
virtual operator T() override;
58+
virtual T pop() override;
5459
virtual void inject(T const & value) override;
5560

5661

@@ -69,7 +74,7 @@ class SinkBlocking : public SinkBase<T>
6974
SinkBlocking(size_t const size);
7075
virtual ~SinkBlocking() { }
7176

72-
virtual operator T() override;
77+
virtual T pop() override;
7378
virtual void inject(T const & value) override;
7479

7580

@@ -87,7 +92,7 @@ class SinkBlocking : public SinkBase<T>
8792
**************************************************************************************/
8893

8994
template<typename T>
90-
SinkNonBlocking<T>::operator T()
95+
T SinkNonBlocking<T>::pop()
9196
{
9297
_mutex.lock();
9398
return _data;
@@ -114,7 +119,7 @@ SinkBlocking<T>::SinkBlocking(size_t const size)
114119
{ }
115120

116121
template<typename T>
117-
SinkBlocking<T>::operator T()
122+
T SinkBlocking<T>::pop()
118123
{
119124
_mutex.lock();
120125
while (_data.isEmpty())

Diff for: src/threading/Source.hpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ class Source
4343
public:
4444

4545
void connectTo(SinkBase<T> & sink);
46-
void operator = (T const & other);
46+
void push(T const & val);
47+
48+
void operator = (T const & val) [[deprecated("Use 'push()' instead.")]];
4749

4850
private:
4951
std::list<SinkBase<T> *> _sink_list;
@@ -60,14 +62,20 @@ void Source<T>::connectTo(SinkBase<T> & sink)
6062
}
6163

6264
template<typename T>
63-
void Source<T>::operator = (T const & value)
65+
void Source<T>::push(T const & val)
6466
{
6567
std::for_each(std::begin(_sink_list),
6668
std::end (_sink_list),
67-
[value](SinkBase<T> * sink)
69+
[val](SinkBase<T> * sink)
6870
{
69-
sink->inject(value);
71+
sink->inject(val);
7072
});
7173
}
7274

75+
template<typename T>
76+
void Source<T>::operator = (T const & val)
77+
{
78+
push(val);
79+
}
80+
7381
#endif /* ARDUINO_THREADS_SOURCE_HPP_ */

0 commit comments

Comments
 (0)