Use a table & table.concat instead of individual concats.
And then use that same table for every hash-related operation.
(Nothing else uses the configurable hash function, otherwise I'd have
limited the table shenanigans to the function itself).
* Allow doing away with CacheItem
Now that we have working FFI finalizers on BBs, it's mostly useless overhead.
We only keep it for DocCache, because it's slightly larger, and memory pressure might put us in a do or die situation where waiting for the GC might mean an OOM kill.
* Expose's LRU slot-only mode
And use it for CatalogCache, which doesn't care about storage space
* Make GlyphCache slots only (storage space is insignificant here, it was
always going to be evicted by running out of slots).
* More informative warning when we chop the cache in half
Ought to be faster than our naive array-based approach.
Especially for the glyph cache, which has a solid amount of elements,
and is mostly cache hits.
(There are few things worse for performance in Lua than
table.remove @ !tail and table.insert @ !tail, which this was full of :/).
DocCache: New module that's now an actual Cache instance instead of a
weird hack. Replaces "Cache" (the instance) as used across Document &
co.
Only Cache instance with on-disk persistence.
ImageCache: Update to new Cache.
GlyphCache: Update to new Cache.
Also, actually free glyph bbs on eviction.
* Minor updates to the min & max cache sizes (16 & 64MB). Mostly to satisfy my power-of-two OCD.
* Purge broken on-disk cache files
* Optimize free RAM computations
* Start dropping LRU items when running low on memory before pre-rendring (hinting) pages in non-reflowable documents.
* Make serialize dump the most recently *displayed* page, as the actual MRU item is the most recently *hinted* page, not the current one.
* Use more accurate item size estimations across the whole codebase.
TileCacheItem:
* Drop lua-serialize in favor of Persist.
KoptInterface:
* Drop lua-serialize in favor of Persist.
* Make KOPTContext caching actually work by ensuring its hash is stable.
* Ensure that going from one to the other tears down the former and
its plugins before instantiating the latter and its plugins.
UIManager: Unify Event sending & broadcasting
* Make the two behave the same way (walk the widget stack from top to
bottom), and properly handle the window stack shrinking shrinking
*and* growing.
Previously, broadcasting happened bottom-to-top and didn't really
handle the list shrinking/growing, while sending only handled the list
shrinking by a single element, and hopefully that element being the one
the event was just sent to.
These two items combined allowed us to optimize suboptimal
refresh behavior with Menu and other Menu classes when
opening/closing a document.
e.g., the "opening document" Notification is now properly regional,
and the "open last doc" option no longer flashes like a crazy person
anymore.
Plugins: Allow optimizing Menu refresh with custom menus, too.
Requires moving Menu's close_callback *after* onMenuSelect, which, eh,
probably makes sense, and is probably harmless in the grand scheme of
things.
Includes:
- MathML: a few minor fixes
- (Upstream) lvtext: fix possible index out of range
- Fonts: RegisterExternalFont() should take a documentId
- Fonts: fix: letter-spacing should not be applied on diacritic
- (Upstream) Fonts: more granular synthetic weights
- Fonts: synthesized weights: tweak some comments
- Fonts: keep hinting with synthetic weight
- Fonts: fix synthesized weight inconsitencies
- Fonts: fix getFontFileNameAndFaceIndex()
- Fonts: adds LVFontMan::RegularizeRegisteredFontsWeights()
- Fonts: handle synth_weight tweaks in glyph/glyphinfo slots
- (Upstream) Fonts: fix some compiler warnings
- Fix hyphenation on Armenian and Georgian text
Update the bottom menu widget "Font Weight" to allow more
granular weights than the previous "regular | bold".
Also bump thirdparty/luasec to v1.0.1.
successful authentication.
Fully tearing down Wi-Fi was a bit optimistic, as the AP list can
technically still be up, so the user might want to try again and/or
connect to another AP.
Fix#5912, regression since #4616.
The reasoning behind #4616 doesn't really apply anymore anyway, as the
Wi-Fi prompt now handles this inconsistent state properly.
The whole codepath should be *extremely* rare anyway (and/or require
super-broken network conditions).
* Support cancelling individual moves.
Coopt the cancel button to actually do just that, cancel, instead of close.
* Don't close when hitting the accept button, allowing to chain multiple moves.
Changes are still propagated to the caller on each individual move, though.
* Update the new icons to match our usual stroke width.
* ReaderToc: Tweak padding around items to be a tad more balanced for multi-level ToCs, and perfectly balanced for flat ToCs. (Re #7548)
* ReaderToc: Make the onHold popup's width match said padding. (Re #7548)
* InfoMessage: Allow passing the alignment flag to TextBoxWidget
* ReaderToc: Center text inside the InfoMessage onHold popup
The object was never re-assigned, so closing a smaller menu (e.g.,
Calibre metadata search) made the underlying one (e.g., CoverBrowser's
ListMenu) inherit the smaller dimensions...
Instead of creating the object in the Class constructor, create it in the
instance constructor (i.e., :init).
Similar cleanups in other Menu* related classes.
* Input: Don't create a new TimeVal object for input frame timestamps, just promote our existing table by assigning it the `TimeVal` metatable.
* TimeVal: Export (const) `zero` & `huge` TimeVal objects, because they're common enough in our codebase. (NOTE: not actually const, that's a Lua 5.4 feature ;p).
* GestureDetector: Explain the behavior of the `last_tevs` & `first_tevs` tables, and why one needs a new object and not the other.
* Speaking of, simplify the copy method for `first_tevs`, because it doesn't need to create a new TimeVal object, we can just reference the original, it's unique and re-assigned for each frame.
* Wireless: Optimize memory usage in StreamMessageQueue (use an array of string ropes, that we only concatenate once). Allowed to relax the throttling, making transfers that much faster.
* Persist: Add a "zstd" codec, that uses the "luajit" codec, but compressed via zstd. Since both of those are very fast, it pretty much trounces everything in terms of speed and size ;).
* Persist: Implemented a "writes_to_file" framework, much like the existing "reads_from_file" one. And use it in the zstd codec to avoid useless temporary string interning.
* Metadata: Switch to the zstd codec.
There have been a couple of these this month, and keeping stuff that should only ever run once piling up in their respective module was getting ugly, especially when it's usually simple stuff (settings, files).
So, move everything to a dedicated module, run by reader.lua on startup, and that will actually only do things once, when necessary.
* TimeVal: Log the results of the COARSE probes in debug logs
* GestureDetector: Print details of failed clock probes in debug logs
* GestureDetector: Skip the BOOTTIME probe when CLOCK_BOOTTIME is unsupported.
* Input: Decode ABS_DISTANCE events in debug logs
* Get rid of duplicated <linux/input.h> constants, use the FFI module everywhere (re #7536)
* Kobo: Get rid of the `touch_alyssum_protocol` quirk. Replace it by setting `main_finger_slot` to `1`, like on the H2O.
* CalibreMetadata: Get rid of the now useless NULL-hunt: here, this was basically looking for `rapidjson.null` to replace them with... `rapidjson.null` :?. IIRC, that's a remnant of a quirk of the previous JSON parser (possibly even the previous, *previous* JSON parser ^^).
* CalibreSearch: Update the actually relevant NULL-hunt to make it explicit: replace JSON NULLs with Lua nils, instead of relying on an implementation detail of Lua-RapidJSON, because that detail just changed data type ;).
* UIManager: Make sure tasks scheduled during the final ZMQ callback are honored. e.g., the Calibre "Disconnect" handler. This happened to mostly work purely by chance before the event loop rework.
* Calibre: Restore a proper receiveCallback handler after receiving a book, in order not to break the "Disconnect" handler's state (and, well, get a working Disconnect handler, period ^^).
* Calibre: Unbreak metadata cache when it's initialized by a search (regression since #7159).
* Calibre: Handle UTC <-> local time conversions when checking the cache's timestamp against the Calibre metadata timestamp.
* Bump base (Unbreak CRe on Android, update RapidJSON)
By which I mean, explicitly initialize default settings, making everything seven hundred billion percent less weird.
Also, split the background option between image and (solo) message, because the defaults for those are different, and trying to twist the one into the other was leading to pure madness.
Requires https://github.com/koreader/koreader-base/pull/1344 & https://github.com/koreader/koreader-base/pull/1346 (fix#7485)
Assorted input fixes:
* Actually handle errors in the "there's a callback timer" input polling loop.
* Don't break timerfd when the clock probe was inconclusive.
Not directly related, but noticed because of duplicate onInputEvent handlers:
* HookContainer: Fix deregistration to actually deregister properly. "Regression" extant since its inception in #2933 (!).
* Made sure the three plugins (basically the trio of AutoThingies ;p) that were using HookContainer actually unschedule their task on teardown.
68a5fcdb moved them a bit to near the top than before,
and it can overlap with CRE rendering progress bar.
Also makes it nicer when multiple notications are stacked.
Generic feature added to TouchMenu: an optional callback
'open_on_menu_item_id_func()' set on an items table can
tell which menu item should be shown when opening a menu.
TouchMenu: allows jumping to first or last page with
long-press on the chevrons.
* Change 'Find a file' to 'File search' for consistency
There is 'File search' in the Gesture manager already.
There is 'Fulltext search' in the readermenu.
Some help text added.
It appears the fancy split settings from #6885 were not being honored at all.
Also:
* Made sure "pagewidth" is actually the default zoom mode again, "full" had sneaked in as the default state of the zoom type toggle).
* Display human-readable values in the "Make as default" popup, instead of the raw, meaningless numerical setting.
* Disable zoom options when reflow is enabled, and restore 'em properly when it's disabled.
Fix#7461, #7228, #7192
* ReaderDictionary: Port delay computations to TimeVal
* ReaderHighlight: Port delay computations to TimeVal
* ReaderView: Port delay computations to TimeVal
* Android: Reset gesture detection state on APP_CMD_TERM_WINDOW.
This prevents potentially being stuck in bogus gesture states when switching apps.
* GestureDetector:
* Port delay computations to TimeVal
* Fixed delay computations to handle time warps (large and negative deltas).
* Simplified timed callback handling to invalidate timers much earlier, preventing accumulating useless timers that no longer have any chance of ever detecting a gesture.
* Fixed state clearing to handle the actual effective slots, instead of hard-coding slot 0 & slot 1.
* Simplified timed callback handling in general, and added support for a timerfd backend for better performance and accuracy.
* The improved timed callback handling allows us to detect and honor (as much as possible) the three possible clock sources usable by Linux evdev events.
The only case where synthetic timestamps are used (and that only to handle timed callbacks) is limited to non-timerfd platforms where input events use
a clock source that is *NOT* MONOTONIC.
AFAICT, that's pretty much... PocketBook, and that's it?
* Input:
* Use the <linux/input.h> FFI module instead of re-declaring every constant
* Fixed (verbose) debug logging of input events to actually translate said constants properly.
* Completely reset gesture detection state on suspend. This should prevent bogus gesture detection on resume.
* Refactored the waitEvent loop to make it easier to comprehend (hopefully) and much more efficient.
Of specific note, it no longer does a crazy select spam every 100µs, instead computing and relying on sane timeouts,
as afforded by switching the UI event/input loop to the MONOTONIC time base, and the refactored timed callbacks in GestureDetector.
* reMarkable: Stopped enforcing synthetic timestamps on input events, as it should no longer be necessary.
* TimeVal:
* Refactored and simplified, especially as far as metamethods are concerned (based on <bsd/sys/time.h>).
* Added a host of new methods to query the various POSIX clock sources, and made :now default to MONOTONIC.
* Removed the debug guard in __sub, as time going backwards can be a perfectly normal occurrence.
* New methods:
* Clock sources: :realtime, :monotonic, :monotonic_coarse, :realtime_coarse, :boottime
* Utility: :tonumber, :tousecs, :tomsecs, :fromnumber, :isPositive, :isZero
* UIManager:
* Ported event loop & scheduling to TimeVal, and switched to the MONOTONIC time base.
This ensures reliable and consistent scheduling, as time is ensured never to go backwards.
* Added a :getTime() method, that returns a cached TimeVal:now(), updated at the top of every UI frame.
It's used throughout the codebase to cadge a syscall in circumstances where we are guaranteed that a syscall would return a mostly identical value,
because very few time has passed.
The only code left that does live syscalls does it because it's actually necessary for accuracy,
and the only code left that does that in a REALTIME time base is code that *actually* deals with calendar time (e.g., Statistics).
* DictQuickLookup: Port delay computations to TimeVal
* FootNoteWidget: Port delay computations to TimeVal
* HTMLBoxWidget: Port delay computations to TimeVal
* Notification: Port delay computations to TimeVal
* TextBoxWidget: Port delay computations to TimeVal
* AutoSuspend: Port to TimeVal
* AutoTurn:
* Fix it so that settings are actually honored.
* Port to TimeVal
* BackgroundRunner: Port to TimeVal
* Calibre: Port benchmarking code to TimeVal
* BookInfoManager: Removed unnecessary yield in the metadata extraction subprocess now that subprocesses get scheduled properly.
* All in all, these changes reduced the CPU cost of a single tap by a factor of ten (!), and got rid of an insane amount of weird poll/wakeup cycles that must have been hell on CPU schedulers and batteries..
Followup to #7306.
As discussed there, the only way to make everybody happy is to make 'em context-aware. At which point, trying to make the fact that it's a *device* rotation and not a *content* one come across in the icon design loses its interest, and would actually only further muddy the issue.
So, these are similar is spirit to the traditional rotation icons in pretty much anything that can rotate text content, with a special inspiration from the Kindle 4 & PocketBook UI.
Fix#7429