Skip to content
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

Clarify our OOP semantics across the codebase #9586

Merged
merged 87 commits into from Oct 6, 2022
Merged

Conversation

NiLuJe
Copy link
Member

@NiLuJe NiLuJe commented Oct 2, 2022

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
Copy link
Contributor

poire-z commented Oct 3, 2022

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
Copy link
Member Author

NiLuJe commented Oct 3, 2022

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
Copy link
Member Author

NiLuJe commented Oct 3, 2022

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
Copy link
Member Author

NiLuJe commented Oct 3, 2022

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.

@Frenzie
Copy link
Member

Frenzie commented Oct 3, 2022

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
Copy link
Member Author

@NiLuJe NiLuJe left a comment

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
Copy link
Member Author

NiLuJe commented Oct 4, 2022

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...

Copy link
Member Author

@NiLuJe NiLuJe left a comment

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)

@poire-z
Copy link
Contributor

poire-z commented Oct 5, 2022

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
Copy link
Contributor

poire-z commented Oct 5, 2022

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
Copy link
Member Author

NiLuJe commented Oct 5, 2022

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.

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?
But only build the default mapping list once.
There was a desync of the charpos or something, which caused del/ret to
delete stuff at the old position.

Del is still wonky in that it behaves like return when at the end of the
line.
e.g., Del doesn't do weird stuff anymore, and Home/End move across the
*current* line.
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.
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.
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.
Copy link
Member Author

@NiLuJe NiLuJe left a comment

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
Copy link
Member Author

@NiLuJe NiLuJe left a comment

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
Copy link
Contributor

poire-z commented Oct 8, 2022

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
Copy link
Member Author

NiLuJe commented Oct 8, 2022

@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
Copy link
Member Author

NiLuJe commented Oct 8, 2022

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
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.

None yet

4 participants