This commit adds explicit selection knobs for all possible
types of characters and symbols.
A side effect is there is also now an error loop to handle the
case that none of the knobs are selected. The user cannot
proceed with generation until at least one type is selected.
When no alphabetic characters are selected, "exclude similar" is
now false, which allows all of the numbers to be picked from.
Normally, 1, 0, etc. are avoided to make it easier for humans
to read/copy the passwords without ambiguity. This does reduce
the total entropy slightly, but ideally you are using the
password generator with a long setting (20 or so characters)
so you're well beyond the worry of losing entropy due to dropping
the few similar characters.
- rapid redraws are normally aborted by this routine. offer a forced
redraw in the case that a "final state" has to be rendered without
fail.
- fix a misdirected message (sending it to app instead of to ui by
accident)
this simplifies the problem of tracking concurrency if multiple threads
are requesting a busy-state to be presented. In this case, when the
final thread leaves its busy state, the idle-state will be shown.
- remove modal pop-up for wifi connection, and replace with
busy animation
- specify units of delay in the constants (_MS to indicate milliseconds;
this is a convention I'm trying to adhere to)
- partial progress on debugging why the animation isn't running
(value of animation variable is not being passed back at the GAM layer).
Also a general note on coding styles that probably is going to cause
confusion now that more people are contributing to the code base.
Generally, when a lot of "generic" library functions fail, we've been
passing an error message up the stack. However, these functions are
actually meant to be infalliable, and when you kick the error up the
stack you just end up with a panic at an unhelpful location (because
you finally catch the error only at the main loop or something and
by that point there's nothing you can really do about it but panic,
since it's supposed to be an infalliable operation).
As a result I have been trying to tamp down on needless error propagations
and having them fail with a unwrap or expect at the point where the
abstraction should be infalliable. This helps in debugging the actual
failure root cause because you're closer to the line of code that
actually broke, instead of just some line at a generic error handler.
Of course if you build with stack unwinding the top-level unwraps are more
useful because you can peer down into the call chain, but even then,
with the limited screen real estate I think deeply nested failures
would probably overflow any panic display. So even with panic unwinding
I think we stil want to keep the root cause within a few stack frames,
instead of errors being passed up sixteen levels of abstraction before
finally dying.
This only applies to things that are meant to be truly infalliable,
like syscalls that should not fail, or like unpacking a buffer or
memory message that has already been allocated. In this case the errors
are more like asserts, and are helpful if they fail at the line where
they break instead of being passed up the call stack (which was the
original architecture).
Probably I should add a note about this to the Xous Book.
- status bar text is just status bar text now
- idle animation runs/stops based on an explicit run/stop message
Note that at the moment if one starts the busy bar and a modal pops
up, you might overflow the queue of the ui drawing thread with animation
requests, because the thread blocks when the modal is summoned.
Modals "take the screen" anyways, so maybe the solution to this is
to add an additional interlock around any modal calls within the UI
main thread. Need to think about it a bit more.
XOR op should not be usable to create fake security boxes
but it also looks really ugly to have it defaced.
This small tweak makes the XOR function look decent for the initial
purpose of the function (chat status bar wait indicator).
Eventually, this will be a controversial decision, but I'll kick
that down the road.
Busy-wait animaitions are handled by a helper server that is normally
blocked. A single shared `bool` indicates whether the animation should
run or not.
When woken up, the busy-wait animator will check if the shared `bool`
is set, and if so, send a message to the main loop to update
the animation, then send wait an appropriate timeout and send itself
a message to re-check the animation status.
This particular format of server is fairly compact but can be vulnerable
to a "message storm" if busy state updates happen in rapid
succession without allowing the server to unblock and handle messages.
Thus, all messages to this server use a `try_send` method, with a silent
failure if the message can't be sent. In other words, if the animator
is already super busy and its queue is full, don't send it more messages,
just drop the existing updates so we can fail without a panic or deadlock.
The typical consequence of this is some UX inconsistency, which is
not a critical error.
- status bar gets some initial text on boot
- previous status message is saved when entering a busy state,
and restored on exit
- add routines for hopefully making the redraw a bit more efficient
if the only thing happening is a busy-wait update.