Skip to content

Making Preferences standalone #1104

Open
@Stefterv

Description

@Stefterv
Collaborator

For the migration of the internal Gradle runner, I'm running into trouble with the Preferences class.

Problem description

Currently Preferences is tightly coupled with the PDE through the use of the Base, Messages, Toolkit and Language classes. These classes do not operate outside of the PDE, thus not allowing reuse of the Preferences class in other modules within Processing (e.g. Gradle plugins, Processing CLI, Processing pre-processor, etc.)

Proposed solution

Migrate the Preferences class to a standalone version.

  • Completing the migration of Preferences to be standalone from :app by moving it to a :app:utils module.
  • Move functionality dependent on :app into a AppPreferences class or into other relevant areas of the PDE
  • Adding callback events/listeners when a preference changes
  • Tests that will declare and test the functionality of Preferences, a few of the top of my head would be:
    • Test if the defaults are loaded and saved without creating changes
    • Test if \ work
    • Test if the preferences file is created if it does not yet exist
    • Any other tests to make sure we have backwards compatibility
  • A Github Action that will run the Tests on all supported platforms
  • Bonus: Removing the dependency on core

Steps taken so far

  • In IntelliJ IDEA create a new module utils in the app folder with the following settings (see image below)
  • Add package processing.utils to the newly created module
  • Refactoring the class by right clicking the Prefrences class and Refactor -> Move Class... and moving it to the newly created processing.utils package
Image

Activity

Stefterv

Stefterv commented on May 16, 2025

@Stefterv
CollaboratorAuthor

@AhmedMagedC is this something you would be interested in working on?

AhmedMagedC

AhmedMagedC commented on May 16, 2025

@AhmedMagedC

@Stefterv Thanks for suggesting me to implement this, and yes i'm interested into working on it

unfortunately though im currently busy with college having practical exams this week, i can start working on it once i finish

AhmedMagedC

AhmedMagedC commented on May 21, 2025

@AhmedMagedC

Hi @Stefterv , I would like to show my approach to make sure I'm moving in the right direction.

I will move Preferences class into :app:util module inside processing.utils package, while keeping AppPreferences class inside :app module which will extend Preferences main functionalities like load(), get(), set() and then provide functionalities that depend on :app like setFont(), getFont()

but for the Preferneces class, getting the preferences.txt file is platform-dependent so i thought of creating processing.utils.platform package to override getSettingFolder() for each platform (which is already implemented in processing.app.platform package i will just copy it)

and for things like getting the default.txt file or ,setting.txt (for portable versions), I can use built-in JAR Resources System instead of the deprecated Platform.getContentFile() which will make it independent of app.Base and app.Platform classes

so what do you think?

Stefterv

Stefterv commented on May 21, 2025

@Stefterv
CollaboratorAuthor

Hi @AhmedMagedC, Thank you for writing down the approach.

I will move Preferences class into :app:util module inside processing.utils package, while keeping AppPreferences class inside :app module which will extend Preferences main functionalities like load(), get(), set() and then provide functionalities that depend on :app like setFont(), getFont()

and for things like getting the default.txt file or ,setting.txt (for portable versions), I can use built-in JAR Resources System instead of the deprecated Platform.getContentFile() which will make it independent of app.Base and app.Platform classes

Perfect 👍

but for the Preferneces class, getting the preferences.txt file is platform-dependent so i thought of creating processing.utils.platform package to override getSettingFolder() for each platform (which is already implemented in processing.app.platform package i will just copy it)

Let's use the existing Platform for now, I'd rather avoid duplicating code where we can. Then we create a new issue for the Platform class similar to this one after creating the new Preferences is finished.

Thank you for catching the dependency on Platform early on!

AhmedMagedC

AhmedMagedC commented on May 31, 2025

@AhmedMagedC

Hi @Stefterv , so i managed to migrate the preference class to utils module and it properly compiles and runs

i took a different approach than using the Platform class because that made cyclic dependency problem (utils depend on app, app depends on utils)

i wanna make a PR so you and other devs can review the work done and prompts changes if needed

also note that i didnt yet work on the rest of requirements, i will once the migration alone makes sense

Stefterv

Stefterv commented on Jun 1, 2025

@Stefterv
CollaboratorAuthor

Hi @AhmedMagedC, thanks so much for the update and the work you’ve done so far! Please go ahead and open a draft PR. We can take a look and continue the discussion there.

Stefterv

Stefterv commented on Jun 20, 2025

@Stefterv
CollaboratorAuthor

Hi @AhmedMagedC Thank you so much for this initial work and thank you for checking in to see if this approach is correct. I learned the following:

By renaming the class to AppPreferences we have to update all the references as well which makes the PR hard to check. I would suggest that we instead create a new class Preferences in utils and extend the existing class from there. That way we can slowly migrate over functionality whilst keeping the references the same. Also some functionality could be extended more easily by overriding methods in the app version of the class.

Looking at the utils.Preferences I would like the system proxy stuff to be in the app.Preferences instead. I would suggest that keeping all side-effects out of the utils class

I'm happy for the Location classes that you have now to be a single class/file.

In any case, this has been super helpful and I hope you are also still excited to implement these changes! Again sorry that I assigned this to you and then did not have the time to review your work sooner.

AhmedMagedC

AhmedMagedC commented on Jun 20, 2025

@AhmedMagedC

Hi @Stefterv , Thanks for the suggestions and I'm still interested in implementing these changes and finishing the todo tasks

for the first point, I have already made the Preferences class in utils which is extended by AppPreferences , i will just rename AppPreferences Back to It's original name Preferences which would resolve these many changes of references.

for the second point, I don't fully understand what do you mean by side-effects can you please elaborate more?

Stefterv

Stefterv commented on Jun 20, 2025

@Stefterv
CollaboratorAuthor

Sure! Side effects are in this case configuration changes that are not explicitely requested. The Preferences class seems like it should only handle saving and loading preferences, but here it also changes the proxy settings while the program is running. I think a utility class should focus on just one thing.

AhmedMagedC

AhmedMagedC commented on Jun 22, 2025

@AhmedMagedC

@Stefterv , I made the changes I hope that's what you had in mind

i renamed the AppPreferences and AppMessages back to the original name Preferences and Messages respectively

and i moved extra configurations to app.preferences which is unrelated to the utils.preferences class like

  • explicitly set bgcolor
  • set sketchbook path
  • proxies configuration
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    Participants

    @Stefterv@AhmedMagedC

    Issue actions

      Making `Preferences` standalone · Issue #1104 · processing/processing4