Skip to content

Clarify our OOP semantics across the codebase#9586

Merged
NiLuJe merged 87 commits into
koreader:masterfrom
NiLuJe:OOPs
Oct 6, 2022
Merged

Clarify our OOP semantics across the codebase#9586
NiLuJe merged 87 commits into
koreader:masterfrom
NiLuJe:OOPs

Conversation

@NiLuJe

@NiLuJe NiLuJe commented Oct 2, 2022

Copy link
Copy Markdown
Member

Basically:

  • Use extend for class definitions
  • Use new for object instantiations

That includes some minor code cleanups along the way:

  • Updated Widget's docs to make the semantics clearer.
  • Removed should_restrict_JIT (it's been dead code since Tackle mcode_alloc issues once and for all android-luajit-launcher#283)
  • Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via open instead of new) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
  • Default to WidgetContainer instead of InputContainer for stuff that doesn't actually setup key/gesture events.
  • Ditto for explicit *Listener only classes, make sure they're based on EventListener instead of something uselessly fancier.
  • Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
    • ReaderUI: Fix one such issue with its active_widgets array, with critical implications, as it essentially pinned all of ReaderUI's modules, including their reference to the Document instance (i.e., that was a big-ass leak).
  • Terminal: Make sure the shell is killed on plugin teardown.
  • InputText: Fix Home/End/Del physical keys to behave sensibly.
  • InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
  • OverlapGroup: Compute self.dimen at init time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
  • ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being niled!
  • Kobo: Minor code cleanups.

(Lots of files touched, but mostly trivial cosmetic tweaks, most actual code changes are limited to LuaSettings & friends).

Pairs with koreader/koreader-base#1525

Sponsored by rg '^local [[:alnum:]_\-]+ = [[:alnum:]_\-]+:new' & rg "^[[:blank:]]{4}[^.[:blank:]]+[[:blank:]]*=[[:blank:]]*\{\}" ;p.


This change is Reviewable

@poire-z

poire-z commented Oct 3, 2022

Copy link
Copy Markdown
Contributor

Looks a bit scary :) v2022.10 or v2022.11 ?

We very, very, very, very rarely actually feed an existing Widget object
to extend (because that way lies inheritance madness).
In 99% of the cases, we pass it the class object of our new subclass

What is the 1% ?
There must probably be 1 or 2 odd usages that may break if blindly moved from :new to :extend. But I guess you may have found them ? :)

Thank you for having removed all these noisy assert(self ~= nil) (added by a dev who didn't trust himself very much :)

@NiLuJe

NiLuJe commented Oct 3, 2022

Copy link
Copy Markdown
Member Author

What is the 1%

I... don't think we actually do it anywhere, but it obviously still works, because a Widget is still a table, after all ;).
(This was mostly a documentation clarification).

e.g.,

local SubWidget = require("subwidget")
local SubSubWidget = SubWidget:extend(SubWidget)

Which is a terrible example because that just means SubSubWidget == SubWidget but with a different name ;p.
But it kinda proves my point that updating the doc for clarity makes sense, because this is a dumb use-case ^^.

@NiLuJe

NiLuJe commented Oct 3, 2022

Copy link
Copy Markdown
Member Author

v2022.10 or v2022.11 ?

Dealer's choice ;).

(I've been running with it applied for a couple days and nothing's blown up so far, but I perfectly understand if we want to wait a bit ;)).

@NiLuJe

NiLuJe commented Oct 3, 2022

Copy link
Copy Markdown
Member Author

There must probably be 1 or 2 odd usages that may break if blindly moved from :new to :extend. But I guess you may have found them ? :)

AFAICT, everything properly instantiates w/ new, so we're good.

(Also, in quite a few of the classes involved, new actually == extend; c.f., CacheItem for example where I made that explicit, but a number of classes had a new method that didn't do anything more than setup the inheritance chain).

There are a few oddities, LuaSettings & co instantiating w/ open, for instance (ha!); or Device being a singleton, meaning init gets called at module scope.

Comment thread frontend/ui/widget/widget.lua Outdated
@Frenzie

Frenzie commented Oct 3, 2022

Copy link
Copy Markdown
Member

Don't have internet yet, some issue with the fiber in my street, so might as well throw it in.

@NiLuJe NiLuJe added this to the 2022.10 milestone Oct 3, 2022

@NiLuJe NiLuJe left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 201 of 202 files at r1, 1 of 1 files at r2, 10 of 10 files at r3, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @Frenzie, @pazos, and @poire-z)

@NiLuJe

NiLuJe commented Oct 4, 2022

Copy link
Copy Markdown
Member Author

I sure would like to know what's got CircleCI's panties in a bunch, but it's been throwing errors 500 for a few days over here...

@NiLuJe NiLuJe left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 35 of 37 files at r4, 4 of 4 files at r5, 3 of 3 files at r6, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @Frenzie, @pazos, and @poire-z)

Comment thread frontend/device/kobo/device.lua
@poire-z

poire-z commented Oct 5, 2022

Copy link
Copy Markdown
Contributor
InputText: Fix Home/End/Del to behave like a real keyboard
e.g., Del doesn't do weird stuff anymore, and Home/End move across the *current* line.

You had me worried - but that's indeed just the Home and End physical keyboard keys.
The virtual keyboard's image are actually Top and Bottom keys, and use the unchanged scrollToTop/Bottom methods.
So, fine by me :)

@poire-z

poire-z commented Oct 5, 2022

Copy link
Copy Markdown
Contributor

InputContainer: That... wasn't a deep copy, like, at all.
So, don't do it, because I don't think we need a deep copy at all her,e
seeing as this is already an instance member, not a class one.

Looked, and I agree (in case you need confirmation :)
Just curious: you go at all that trusting your (good) sense ? Or do you look at git history/blame, to see who did the change when, if there was a reason or not, if the person who did the change feel like it had experience or was a newcommer ?
There's many things I've seen in some early/base widgets that looked odd (some stuff I remembed related to align= stuff), that I didn't dare changing because "if it works don't fix it" :)

@NiLuJe

NiLuJe commented Oct 5, 2022

Copy link
Copy Markdown
Member Author

Just curious: you go at all that trusting your (good) sense ? Or do you look at git history/blame, to see who did the change when, if there was a reason or not, if the person who did the change feel like it had experience or was a newcommer ?
There's many things I've seen in some early/base widgets that looked odd (some stuff I remembed related to align= stuff), that I didn't dare changing because "if it works don't fix it" :)

All of the above? ;o)

(And I'm trying to keep to stuff mostly related to this PR. e.g., parts of the dimen stuff was an old, old workaround... because of base classes being registered via new, which meant init doing funky stuff to base classes ;)).

Let's say I'm cautiously optimistic it won't break too many things ;p.

NiLuJe added 10 commits October 5, 2022 23:19
They're implementations, not instantiated objects.

Part I: frontend/ui (i.e., Widgets).
We very, very, very, very rarely actually feed an existing Widget object
to extend (because that way lies inheritance madness).
In 99% of the cases, we pass it the class object of our new subclass,
which is just a table with its dedicated or overloaded static fields.
Instances are created via open
i.e., with inheritance magic.

Also, simplify the LuaData API, that extra random table just to pass a
single field name was weird?
NiLuJe added 2 commits October 5, 2022 23:19
InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time, like
most of our widgets

OverlapGroup: Compute self.dimen at *init* time, because for some reason
it needs to do that, but do it directly in OverlapGroup instead of going
through a weird WidgetContainer method that it was the sole user of.
NiLuJe added 2 commits October 5, 2022 23:51
Doesn't appear to be any rhyme or reason re: init vs. paintTo, wheee!

Anyway, fill the Geom tables we create to make sure we won't need to
grow it later while I'm there.

@NiLuJe NiLuJe left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 7 files at r7, 3 of 4 files at r8, 3 of 3 files at r9, 5 of 8 files at r10, 27 of 27 files at r11, all commit messages.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @Frenzie, @pazos, @poire-z, and @zwim)

NiLuJe added a commit to koreader/koreader-base that referenced this pull request Oct 5, 2022
* Minor cosmetic tweaks to ffi/pic to follow our usual class semantics

@NiLuJe NiLuJe left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 3 of 3 files at r12, all commit messages.
Reviewable status: all files reviewed, 2 unresolved discussions (waiting on @Frenzie, @pazos, @poire-z, and @zwim)

@poire-z

poire-z commented Oct 8, 2022

Copy link
Copy Markdown
Contributor

Crash when Wikipedia lookup:

10/08/22-16:24:44 WARN  error in wrapped function: frontend/apps/reader/modules/readerdictionary.lua:970: attempt to get length of field 'dict_window_list' (a nil value)
stack traceback:
 frontend/apps/reader/modules/readerdictionary.lua:970: in function 'showDict'
 frontend/apps/reader/modules/readerwikipedia.lua:536: in function 'lookupWikipedia'
 frontend/apps/reader/modules/readerwikipedia.lua:392: in function <frontend/apps/reader/modules/readerwikipedia.lua:391>
 [C]: in function 'xpcall'

Dunno how you'll want to fix that : :new ? re-set all the ReaderDict fields in ReaderWikipedia ? Call super/ReaderDict:init() ?

@NiLuJe

NiLuJe commented Oct 8, 2022

Copy link
Copy Markdown
Member Author

@poire-z: I was a bit unclear on what exactly the dict_window_list array's raison d'être was, so it will kind of depend on that?

@NiLuJe

NiLuJe commented Oct 8, 2022

Copy link
Copy Markdown
Member Author

Okay, yeah, looking at DictQuickLookup, it needs to be a static class member (if only for the "close all open windows on hold" feature), I'll fix that ;).

NiLuJe added a commit to NiLuJe/koreader that referenced this pull request Oct 8, 2022
Also, make references are actually dropped no matter how the widget is
closed by relying on onCloseWidget ;).

Enable the "long-press-on-close" on the actual Close button, too,
instead of only on the title bar's cross.

Fix: koreader#9586 (comment)
@NiLuJe NiLuJe mentioned this pull request Oct 8, 2022
NiLuJe added a commit to NiLuJe/koreader that referenced this pull request Oct 8, 2022
Also, make sure references are actually dropped,
no matter how the widget is closed, by relying on onCloseWidget ;).

Enable the "long-press-on-close" trick on the actual Close button,
too, instead of only on the title bar's cross.

Fix: koreader#9586 (comment)
NiLuJe added a commit that referenced this pull request Oct 9, 2022
Also, make sure references are actually dropped,
no matter how the widget is closed, by relying on onCloseWidget ;).

Enable the "long-press-on-close" trick on the actual Close button,
too, instead of only on the title bar's cross.

Fix: #9586 (comment)
NiLuJe added a commit to NiLuJe/koreader that referenced this pull request Oct 24, 2022
NiLuJe added a commit that referenced this pull request Oct 24, 2022
@poire-z

poire-z commented Aug 25, 2024

Copy link
Copy Markdown
Contributor

InputText: Fix Home/End/Del physical keys to behave sensibly.

Works when a scrollable has not yet scrolled. Once you scroll and the first line is not the top line, all go messy :) Home moves some lines up, End too.
I guess it's because your added:
current_line_num = 1, -- index of the currently edited line (i.e., where our cursor is)
is actually the index of the currently edited line among the visible lines, and not related to the top (undisplayed) line.
So, your recent fix moves it to not the right place:

function TextBoxWidget:moveCursorHome()
    self:moveCursorToCharPos(self.vertical_string_list[self.current_line_num] and self.vertical_string_list[self.current_line_num].offset or #self.charlist)
end

Looking at fixing that.
edit: just a matter of:

-    self.current_line_num = screen_line_num
+    self.current_line_num = screen_line_num + self.virtual_line_num - 1

@poire-z

poire-z commented Aug 25, 2024

Copy link
Copy Markdown
Contributor

^ will PR that fix, there are a few minor other related cleanups needed.

0xstillb pushed a commit to 0xstillb/koreader-thai that referenced this pull request May 9, 2026
Basically:

* Use `extend` for class definitions
* Use `new` for object instantiations

That includes some minor code cleanups along the way:

* Updated `Widget`'s docs to make the semantics clearer.
* Removed `should_restrict_JIT` (it's been dead code since koreader/android-luajit-launcher#283)
* Minor refactoring of LuaSettings/LuaData/LuaDefaults/DocSettings to behave (mostly, they are instantiated via `open` instead of `new`) like everything else and handle inheritance properly (i.e., DocSettings is now a proper LuaSettings subclass).
* Default to `WidgetContainer` instead of `InputContainer` for stuff that doesn't actually setup key/gesture events.
* Ditto for explicit `*Listener` only classes, make sure they're based on `EventListener` instead of something uselessly fancier.
* Unless absolutely necessary, do not store references in class objects, ever; only values. Instead, always store references in instances, to avoid both sneaky inheritance issues, and sneaky GC pinning of stale references.
  * ReaderUI: Fix one such issue with its `active_widgets` array, with critical implications, as it essentially pinned *all* of ReaderUI's modules, including their reference to the `Document` instance (i.e., that was a big-ass leak).
* Terminal: Make sure the shell is killed on plugin teardown.
* InputText: Fix Home/End/Del physical keys to behave sensibly.
* InputContainer/WidgetContainer: If necessary, compute self.dimen at paintTo time (previously, only InputContainers did, which might have had something to do with random widgets unconcerned about input using it as a baseclass instead of WidgetContainer...).
* OverlapGroup: Compute self.dimen at *init* time, because for some reason it needs to do that, but do it directly in OverlapGroup instead of going through a weird WidgetContainer method that it was the sole user of.
* ReaderCropping: Under no circumstances should a Document instance member (here, self.bbox) risk being `nil`ed!
* Kobo: Minor code cleanups.
0xstillb pushed a commit to 0xstillb/koreader-thai that referenced this pull request May 9, 2026
Also, make sure references are actually dropped,
no matter how the widget is closed, by relying on onCloseWidget ;).

Enable the "long-press-on-close" trick on the actual Close button,
too, instead of only on the title bar's cross.

Fix: koreader#9586 (comment)
0xstillb pushed a commit to 0xstillb/koreader-thai that referenced this pull request May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants