Skip to content

Refactored enfuseAdvanced #179

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

Merged

Conversation

BzKevin
Copy link
Contributor

@BzKevin BzKevin commented Mar 4, 2019

I was having issue with this script periodically. The original version of this was real a hack-job of Holger Klemms original. This new version utilizes tables in a manner that I hope will make the code easier to follow and understand, but also allows for certain functions to be re-used throughout (and potentially in different scripts as well). In general:

Each program (align image stack, enfuse, exiftool) now has a table that contains information about that program, this includes a sub-table that contains argument data for the program.
There is a GUI table which contains all GUI elements. Those elements are split into sub-tables within GUI based on what aspect of the scrpt behavior they relate to (AIS, ENF, Target File, Presets, etc...)
These two structures (and the similarities between them) have allows me to create loops which populate the arguments from the GUI and vice-versa, this is all done through an intermediary preference, the "active" preference.
Whenever a change to a GUI element occurs the associated member of hte active preference is updated. then when it becomes time to build an argument string for a program command the active preference is read from and the value contained within is used. This works fine for all GUI elements that have a "changed" or "clicked" callback, as they can remain up-to-date real time. Sliders and Entry boxes do not have this, so at a certain point withing the script the GUI values are read directly for these elements and written to the associated active preference field.

As you will see about 50% of this code is simply building all the GUI elements and making sure that the initialization value for that element is valid (via the InRange() function). The actual heart of the program and it's functions really only takes up about 300 lines (starting at 180 and going through 476). That is broken down into multiple fairly concise functions. Hopefully this makes maintenance, feature enhancement, and troubleshooting much easier in the future.

I also made a few UI tweaks. This script use to create such a massive list of GUI elements that it was a nuisance when actually using it. They are now grouped into three containers for AIS options, Enfuse options, and target options. Only one of these options containers is displayed at a time. Additionally, I removed all the registered preferences I had before, so now I only register 3 options to enable user to point towards the program binaries.

I was having issue wit this script periodically. The original version of this was real a hack-job of Holger Klemms original. This new version utilizes tables in a manner that I hope will make the code easier to follow and understand, but also allows for certain functions to be re-used throughout (and potentially in different scripts as well). In general:

Each program (align image stack, enfuse, exiftool) how has a table that contains information about that program, this includes a sub-table that contains argument data for the program.
There is a GUI table which contains all gui elements. Those elements are split into sub-tables within GUI based on what aspect of the scrpt behavior they relate to (AIS, ENF, Target File, Presets, etc...)
These two structures (and the similarities between them) have allows me to create loops which populate the arguments from the GUI and vice-versa, this is all done through an intermediary preference, the "active" preference. 
Whenever a change to a GUI element occurs the associated member of hte active preference is updated. then when it becomes time to build an argument string for a program command the active preference is read from and the value contained within is used. This works fine for all GUI elements that have a "changed" or "clicked" callback, as they can remain up-to-date real time. Sliders and Entry boxes do not have this, so at a certain point withing the script the GUI values are read directly for these elements and written to the associated active preference field.

As you will see about 50% of this code is simply building all the GUI elements and making sure that the initialization value for that element is valid (via the InRange() function). The actual heart of the program and it's functions really only takes up about 300 lines (starting at 180 and going through 476). That is broken down into multiple fairly concise functions. Hopefully this makes maintenance, feature enhancement, and troubleshooting much easier in the future.

I also made a few UI tweaks. This script use to create such a massive list of GUI elements that it was a nuisance when actually using it. They are now grouped into three containers for AIS options, Enfuse options, and target options. Only one of these options containers is displayed at a time. Additionally, I removed all the registered preferences I had before, so now I only register 3 options to enable user to point towards the program binaries.
@wpferguson
Copy link
Member

Why not add a fourth container for configuration and put the executable_path_preference widgets there so the use can just configure the program on the fly and not have to restart darktable.

@BzKevin BzKevin changed the title Refactored Refactored enfuseAdvanced Mar 4, 2019
@BzKevin
Copy link
Contributor Author

BzKevin commented Mar 4, 2019

Why not add a fourth container for configuration and put the executable_path_preference widgets there so the use can just configure the program on the fly and not have to restart darktable.

True. I originally avoided doing that as it would add even more clutter to the UI. But now that I have containers it wouldn't really make any difference at all. I also made a comment of in the HDRMerge PR that applies here:
I'm not sure when I need to ask the user for a bin path and when not to. Right now I always ask. I know Windows needs it. and my understanding is that linux doesn't need that at all? Do you know if macOS needs user-defined executable preferences or not? I could only display the file choosers on systems that need them.

GUI.AIS.control_points,
GUI.AIS.control_points_remove,
GUI.AIS.correlation
}
Copy link
Member

Choose a reason for hiding this comment

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

Did you try doing table.unpack(GUI.AIS)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No. I don't know what that is. I'll have to look it up

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll look into the unpack function. However, things are working as-is, and this is already a big step forward on refactoring this, so let's not let table.unpack implementation hold up this PR. If I can get around to implementing it in the future I can do so.

@wpferguson
Copy link
Member

I'm going to download the source file and go thru it and add comments. It's really hard to get a good grip on what you've done in the diff view provided here. What I can see looks good. I think you might be able to take it a little farther and specify your gui elements in the tables and just call a routine to build them, but I need to see the script as a whole to figure it out.

@wpferguson
Copy link
Member

You might want to look at contrib/video_ffmpeg.lua. @theres had some preference read and write functions that looked pretty slick and might be useful. There's also a placeholder replacement function so that you could replace {datatype} with bool, string, int, etc.

@wpferguson
Copy link
Member

Linux can determine executable paths using which, and it works. MacOS needs to specify the location to be safe, and windows needs to specify the location. So,

if dt.configuration.running_os ~= "linux" then
-- create 4th stack for configuration
end

BzKevin added 5 commits March 5, 2019 09:11
The executable choosers have been moved to a box which is now element 4 in the GUI stack. Once the user configures these and presses update they are confirmed good or bad and the GUI changed to normal view if all works out.
Made text translatable except for line 499 which kept giving me problems
   Making L499 translatable would throw the following error   lua:499: attempt to call a nil value (upvalue '_')
   Troubleshooting steps taken and results:
        1) Changed the translation function from _() to translate() - this worked, no errors but ugly
        2) Reverted the changes from 1, then changed all "for _, var in table do" to be "for ignore, var in table do" - this did not help

Moved a chunk of code due to anomalous behavior, I suspect previous code was attempting to change the value in the stack widget before it was fully created. Adding in a print statement before trying to change the stack.active would cause things to work fine. Moving it behind the register call also helped.
@supertobi
Copy link
Contributor

Is this version better then the old one and does it run on all OS? If yes, lets merge it. It can still be improved later.

@BzKevin
Copy link
Contributor Author

BzKevin commented May 7, 2019

Is this version better then the old one and does it run on all OS? If yes, lets merge it. It can still be improved later.

This does run on all OS, though the old one did too. It is my belief this is indeed better than the old. Here's why:

  1. Made the code easier to understand, thus more maintainable by myself and others
  2. Per @wpferguson it is a good idea to minimize usage of the preferences, so while the old script relied on that heavily, this does not at all
  3. I had UX (user experience) problems with the old script as it generated one massive list of options, this has been optimized by grouping related options together and only displaying a single group at a time
  4. This is now translatable, previously was not
  5. I experienced some glitchy behavior with the old one that I have not had since refactoring.

@supertobi supertobi merged commit d3dafd4 into darktable-org:master May 7, 2019
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