B4J Question Resumable Sub - Load image from drive

ThRuST

Well-Known Member
Licensed User
Longtime User
I've been looking at resumable sub posts and I did not find one that I need.

I want to load an image from the harddrive, and have the sub wait until it is successfully loaded.
After that it may continue.

How to do that?
Thanks

I want to use it with this code
B4X:
Sub InitCustomSkinImage
    
    If File.Exists(TmpFolder, "Design.png") = True Then
        Main.ivPaneManagerInfo.SetImage(fx.LoadImage(TmpFolder, "Design.png"))
        
        FadeInImage
    End If
    
End Sub
 

stevel05

Expert
Licensed User
Longtime User
I think that the sub will already wait for the image to load, you just need to control the Alpha of the image view:

B4X:
    ImageView1.SetAlphaAnimated(0,0)
    ImageView1.SetImage(fx.LoadImage(File.DirAssets,"Aviary Stock Photo 3.png"))
    ImageView1.SetAlphaAnimated(400,1)
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Hi Steve. Sorry I should have posted my FadeInImage code as well. I used a Sleep(500) below in the Init sub but was looking for another way since the resumable sub icon is not showing at the end of the sub name I doubt it is active. Only with sleep and wait for it should be 'active' as far as I have understood.

FadeInImage code

B4X:
Sub FadeInImage
    
    Main.ivPaneManagerInfo.Alpha = 0
    Main.ivPaneManagerInfo.SetAlphaAnimated(2000, 1)

End Sub

ivPaneManagerInfo is an imageview. I use it with modules that is extracted in a tmp folder, and the image should be loaded once the process is completed.
If the file is large, I am afraid it might skip the loading of the image. That's why a resumable sub seems better.
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
It's a mystery how the fadeinimage code can work when the resumable sub icon is not showing. @stevel05 are you sure the sub is waiting for image to load? how can this be when neither Sleep or Wait For is used? That's what I want to understand.
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
I was going for a solution like this but that did never load the image

B4X:
Sub InitDatabaseImage
    
    If File.Exists(File.DirData("Athena"), "Database.png") = True Then
        Main.ivPaneManagerInfo.SetImage(fx.LoadImage(ApplicationPath, "Database.png"))
        Wait For InitDatabaseImage complete
        FadeInImage
    End If
    
End Sub
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
I was going for a solution like this but that did never load the image
You are using two different paths!?
Checking file exists in path A, try loading from path B
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
@DonManfred This may indeed look confusing. It's because my project can create module files which simply is an archive with files that can be loaded in my application. A database file together with an image and a textfile that stores the info about the module. So when a module filename is clicked in the listview, its content is extracted to a tmp folder. Then the image is loaded to display in my application together with the information who created the module. There's four types of modules. One for the main database, one for the contextmenu, one for application sound and one for graphics (CSS) and images. So that's why a 'waiting sub' is so important. It has to be prepared for the archrive contents to be extracted before showing the image (which is in the module archieve). I guess this will make it easier to understand what it's used for.
If I use Sleep (2000) before checking if the image exist, it gives the system 2 seconds to extract the archive before loading the image. I am looking for a more convenient way instead of using Sleep because if someone creates a module with a database that is a couple of megabytes, then 2 seconds wait will not be enough. One wait should be to check the size of the file and adjust the sleep according to that, but I assume that's bad practice. Wait For is what I want to use so please help me :)
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
The following modules are supported

Athena Database Module (.ADM)
Athena Contextmenu Module (.ACM)
Athena Sound Module (.AZM)
Athena Design Module (.AGM)

Here's a screenshot of Athena v0.80

athena.JPG
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Installed modules must be treated differently to those that are read temporary. That's why noninstalled modules are extracted in the tmp folder.
If the user choses to install a module it is copied to the application directory. Simply really but it easily grows in complexity :) A resumable sub might save the day
(and the whole project) ;)
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Main.ivPaneManagerInfo.SetImage(fx.LoadImage(TmpFolder, "Design.png"))
I want to load an image from the harddrive, and have the sub wait until it is successfully loaded.
fx.LoadImage will not return unless it 1) has loaded the file or 2) error's out. It is not an asynchronous method. Neither is SetImage. Therefore, these statements are executed serially.
If I use Sleep (2000) before checking if the image exist, it gives the system 2 seconds to extract the archive before loading the image.
Again, this is only true if the archive method is an actual asynchronous method, which I cannot determine from the information given. If the archiving function is not asynchronous, then all that Sleep(2000) does is add another 2 seconds to the process. If the archiving function is asynchronous, then hopefully it has a callback and you can use Wait For with the callback without requiring Sleep(). But again, not enough information is provided and I'm just throwing some ideas up in the air.
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Hi @OliverA and thanks, you sure had a good point. I use Arc.AsyncZipFiles to create the archives and Arc.AsyncUnZip. What do you suggest for the Resumable sub? I posted another question about how to check filesize with numberformat since I cannot get that to work properly. As a secondary solution I plan to check the size of the archive and adjust the sleep to match the filesize. Not the nicest solution, but should work. Math usually does anyway :)
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Arc.AsyncZipFiles
So you have something like
B4X:
Arc.AsyncZipFile(ton of parameters, "CallbackFunction")
Sleep(2000)
Do something else
You just need to do
B4X:
Arc.AsyncZipFile(ton of parameters, "CallbackFunction")
Wait for CallbackFunction_ZipDone(CompletedWithOutError As Boolean,NbOffiles As Int)
If CompletedWithOutError = True Then
      'Load your images
Else
      'Do something else
End If
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
Actually it looks like this :)

B4X:
Dim FilesToZip() As String
    
    ' Create Athena Database
    If TabPaneManager.SelectedItem.Text == "Databases" Then
        FilesToZip = Array As String ("Athena_db.sqlite", "Database.dat", "Database.png", "UNLICENSE.txt")
        Arc.AsyncZipFiles(Inititialization.ApplicationPath, FilesToZip, Inititialization.DatabasesFolder, tfFilename.Text & ".ADM", "ZipDatabase")
        ListDatabaseFiles
    End If

and for the unzip method

B4X:
Sub UnZipDatabase
    
    Try
    
        ' Unzip file
        Arc.AsyncUnZip(Inititialization.DatabasesFolder, lvDatabases.SelectedItem, Inititialization.TmpFolder, "UnZipDatabase")
        
    Catch
        fx.Msgbox(MainForm, LastException.Message, "")
    End Try
    

End Sub

When unzipped done...
B4X:
Sub UnZipDatabase_UnZipDone (Success As Boolean, FilesInZip As Int)
   'Log("Unzipped all files status : " & Success)
   'Log(File.ListFiles(File.DirTemp))
  
   If Success = True Then
   Load module info...
End Sub
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
B4X:
Sub UnZipDatabase
    Try
        ' Unzip file
        Arc.AsyncUnZip(Inititialization.DatabasesFolder, lvDatabases.SelectedItem, Inititialization.TmpFolder, "UnZipDatabase")
        Wait For UnZipDatabase_UnZipDone (Success As Boolean, FilesInZip As Int)
        If Success = True Then
          'Load module info...
          'Load picture, since package has been unzipped. No other Sleep() statements required.
        Else
          '
        End If     
    Catch
        fx.Msgbox(MainForm, LastException.Message, "")
    End Try
End Sub
Note: This makes UnZipDatabase resumable and you may need to wait for it. May need to turn it into a returnable sub with result. More code needed on how it is called and what happens after it.
 
Upvote 0

ThRuST

Well-Known Member
Licensed User
Longtime User
@OliverA Thanks, you're awesome. Just had a pizza Salami with Sprite, I'm falling back upon the traditional programmers diet haha :D
My eyes stays fixed on that Wait For UnzipDatabase_UnzipDone... that's where the magic happens so to speak :)
I will try this it seems just what I need to improve my code. I must add your name among the credits list, it's getting longer every month.
I am learning the Resumable sub since it's extremely useful, so your solution is a great addition to the examples found across the forum.
I guess the filesize check with adjustable sleep value is not needed now, with professionals like the mighty @OliverA
WHAT ALL OF YOU GONNA DO, WHEN OLIVER-MANIA RUNS WILD,ON YOOOOUU (strike a pose Oliver haha) and Thank you master :)
 
Upvote 0
Top