-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Add Print::availableForWrite #5789
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@matthijskooijman: Shall i rebase this so you can merge? |
dc141a9
to
e0fb9fd
Compare
The real question is that isn't clear is if the "default" method should return IIRC an old discussion on the developers list, the consensus was that it should return |
Thankfully whatever it returns, it won't break existing code. I think you're right, 0 would make more sense. |
I would like to suggest the default should be either 1 or a large number, but not zero. The most common use case looks something like this:
All availableForWrite() implementations should only return zero when they will later return non-zero. Returning zero will cause the user's code to avoid Serial.write(). Users will expect zero means they should not send their data now, because a better time will become available in the future. Returning zero doesn't mean "don't know". Zero means "will block, avoid writing if you can't wait". Please make the default either 1 or a large number, but not zero. |
The The point is that in the example above we relies on the If availableForWrite returns always So we have to decide if we should let fail the "stream" or the "timing sensitive task":
|
(well, looking again at the example, there is no explicit while loop, but you've got the idea) |
Does this default really matter at all? We could just as easily put Let me recap why we need this at all. Consider the following code:
Now we can either:
If the user now edits their code to call |
Indeed any use of the default rather than a real implementation will be something less than ideal. This is a matter of choosing the "least bad" outcome. Returning 0 pretty much guarantees data will not flow for sketches and libraries which check availableForWrite(). Returning 1 allows data to flow, but with disruption to the timing sensitive tasks. Both do still get to function, though the timing sensitive task is likely to suffer delays. While this isn't good, I'd like to suggest having all parts working but some ir all not performing well is much easier on end users than some parts performing well with other parts not working at all. This default is likely to be forever used for SoftwareSerial, Soft I2C and other no buffering cases. In the short term, it's also likely to be used for most Print objects which don't yet implement availableForWrite(). |
Which objects are these? I was under the impression that all these objects derive from |
Ah nevermind, I'm wrong about that - I forgot that this is being moved from |
Perhaps |
However, I believe any of these default values is a better decision than "choosing" indecision which leaves this important contribution languishing. Please just pick one. |
But not -1. Either 0, 1 or INT_MAX. Any of those defaults is better than another release where library authors can't access this function from the base class, and are forced to design libraries which aren't compatible with a wider range of communication objects. |
I don't follow your argument against -1 - can you elaborate with a code example? |
I think that the only sane default is
|
Ok, 0 it is. Really, this is your call Cristian. My position is any of these 3 choices is far better than not merging only because of this default value choice. |
@eric-wieser could you update the PR? |
If available() is in the base Stream class, then availableForWrite() should be in the base Print class
e0fb9fd
to
36b121a
Compare
Updated, including a comment explaining the choice, and when overriding is necessary |
#2387 is very similar to this PR, so would be good to get that in too, while we're thinking about |
Great, thanks! |
@@ -22,6 +22,7 @@ | |||
|
|||
#include <inttypes.h> | |||
#include <stdio.h> // for size_t | |||
#include <limits.h> // for INT_MAX |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, this wasn't needed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! fixed here: d4a9452
This was added in arduino/Arduino#5789 Not implemented yet for USB serial, as that is harder
This was added in arduino/Arduino#5789 Not implemented yet for USB serial, as that is harder
If
available()
is in the baseStream
class, thenavailableForWrite()
should be in the base Print classFor backwards compatibility, this can't be pure virtual. So we return INT_MAX, indicating no limit.
Ideally, we'd use
size_t
andSIZE_MAX
, but that's probably not a backwards-compatible change