f3d icon indicating copy to clipboard operation
f3d copied to clipboard

supported files stop being `--watch`ed if they fail to load

Open snoyer opened this issue 7 months ago • 1 comments

Describe the bug When a file of a supported type opened with the --watch option is overridden with erroneous data, overriding it again with a correct model does not trigger a reload automatically (but pressing the up key does).

To Reproduce Steps to reproduce the behavior:

  1. run following python script to create and periodically override watched.off in your temp directory
from time import sleep
from pathlib import Path
from tempfile import gettempdir

fn = Path(gettempdir()) / "watched.off"
delay = 3

while True:
    for name, off in {
        "a tetrahedron": "OFF\n4 4 0\n1 1 1\n1 -1 -1\n-1 1 -1\n-1 -1 1\n3 1 2 0\n3 0 2 3\n3 3 2 1\n3 1 0 3",
        "a cube": "OFF\n8 6 0\n-1 -1 -1\n-1 -1 1\n-1 1 -1\n-1 1 1\n1 -1 -1\n1 -1 1\n1 1 -1\n1 1 1\n4 0 1 3 2\n4 6 7 5 4\n4 5 7 3 1\n4 0 2 6 4\n4 4 5 1 0\n4 3 7 6 2",
        "broken": "OFF\n4 1 0\n1 1 1\n1 -1 -1\n-1 1 -1\n-1 -1 1\n0",
    }.items():
        fn.write_text(off)
        print(f"{fn} is now {name}")
        sleep(delay)
  1. open the file with f3d --watch /tmp/watched.off
  2. observe the file does reload when changing from a tetrahedron to a cube to a broken file
  3. observe the file does not reload as a tetrahedron after being broken, press up to reload manually

Expected behavior The file should reload every time even after it failed to load

System Information: N/A

F3D Information 3.0, 3.1

Additional context The bug is due to supported files that fail to load being treated as unsupported.

The following diff could be the base of a quick and dirty fix as it does allow the broken file to reload automatically:

diff --git a/application/F3DStarter.cxx b/application/F3DStarter.cxx
index 9b76ea17..37facf28 100644
--- a/application/F3DStarter.cxx
+++ b/application/F3DStarter.cxx
@@ -1456,10 +1456,6 @@ void F3DStarter::LoadFileGroup(
             "Loading animation time: ", this->Internals->AppOptions.AnimationTime.value());
           scene.loadAnimationTime(this->Internals->AppOptions.AnimationTime.value());
         }
-
-        // Update loaded files
-        std::copy(
-          localPaths.begin(), localPaths.end(), std::back_inserter(this->Internals->LoadedFiles));
       }
     }
   }
@@ -1473,6 +1469,9 @@ void F3DStarter::LoadFileGroup(
     unsupported = true;
   }
 
+  // Update loaded files
+  std::copy(localPaths.begin(), localPaths.end(), std::back_inserter(this->Internals->LoadedFiles));
+
   std::string filenameInfo;
   if (this->Internals->LoadedFiles.size() > 0)
   {
@@ -1549,7 +1548,7 @@ void F3DStarter::LoadFileGroup(
   // but there is no way to detect if an option has been set
   // by the user or not.
   f3d::options& options = this->Internals->Engine->getOptions();
-  options.ui.dropzone = this->Internals->LoadedFiles.empty();
+  options.ui.dropzone = unsupported;
   options.ui.filename_info = filenameInfo;
 }

However a proper solution would involve distinguishing between actually unsupported files and supported files that failed to load to be able to act accordingly (logging, UI, ...).

snoyer avatar May 07 '25 16:05 snoyer

Indeed this usecase was not considered at all. good catch!

mwestphal avatar May 07 '25 16:05 mwestphal