FlipView with variable controls - winrt-xaml

I want to present images (given as a collection of StorageFiles) in a FlipView.
Images are in a custom format and decoded by:
async Task<WritableBitmap> MyDecodeImage(StorageFile sf) { ... }
The WritableBitmap can be assigned to image.Source.
There can be hundreds of files so they should be decoded on demand rather than all at once.
How to declare my FlipView? It should normally show Images, but for files that have decoding errors it should show an error message.

Use lots of code behind and the ContainerContentChanging event to start/cancel loading the images. Use a prioritized list to make sure you first load an image for the currently visible item rather than something that's virtualized to show something soon. Use StorageFile.GetThumbnail() rather than loading the entire image until you zoom in on the image to use less memory and speed up loading time, especially after the system has already cached the thumbnail.
Once the decoding task is complete - you can write code to specify what should show up in a FlipViewItem.

Related

Loading JSON file not reflecting changes

I have a JSON file I use to store dialogue for a game. However, the changes I make to this JSON file are sometimes not reflected in my game even after hard reloads (I've been doing ctrl+shift+r or shift+F5 for this). I have made sure the changes to the JSON file are saved.
I have this.load.json('dialogue', 'assets/dialogue.json'); in preload(), and this.dialogue = this.cache.json.get('dialogue'); in create().
When I try copy+pasting the contents to a new different file (e.g. dialogue-2.json), and update my this.load.json() to reflect the new file name, the changes do get loaded.
The problem is that phaser doesn't automatic start the loading files, except in the preload function.
If you want to load files in other functions you need to call the start method of the LoadPlugin. Here the link to the official documentation.
The code should look something like this:
function create(){
// some code here ...
this.load.json(/* key and file...*/);
// start the loading of the enqueued files
this.load.start();
// some code here...
}
..., than the files should get loaded.
Update (copied form comments):
to check (and as a tempoary quickfix) if your problem, is a caching issue from the Webserver or browser or ..., you can load the file with a "dynamic" Url.
Just a load the file with a questionmark and random number added to the url, so that each call to the json uses aunique Url.
For Example like this:
this.load.json('dialogue', 'assets/dialogue.json?' + Math.random());
If this solves the problem, there is a caching problem. It could be in the browser, or simply caused by serviceworker or on the webserver.

Heroku cannot store files temporarily

I am writing a nodejs app which works with fonts. One action it performs is that it downloads a .ttf font from the web, converts it to a base64 string, deletes the .ttf and uses that string in other stuff. I need the .ttf file stored somewhere, so I convert it. This process takes like 1-2 seconds. I know heroku has an ephemeral file system but I need to store stuff for such a short time. Is there any way I can store my files? Using fs.writeFile currently returns this error:
Error: EROFS: read-only file system, open '/app\test.txt']
I had idea how about you make an action, That would get font, convert it and store it on a global variable before used by another task.
When you want to use it again, make sure you check that global variable already filled or not with that font buffer.
Reference
Singleton
I didn't know that you could store stuff in /tmp directory. It is working for the moment but according to the dyno/ephemeral system, it gets cleaned frequently so I don't know if it may cause other problems in the long run.

HTML5 Audio long buffering before playing

I'm currently making an electron app that needs to play some 40Mbyte audio file from the file system, maybe it's wrong to do this but I found that the only way to play from anywhere in the file system is to convert the file to a dataurl in the background script and then transfer it using icp, after that I simply do
this.sound = new Audio(dataurl);
this.sound.preload = "metadata"
this.sound.play()
(part of a VueJS component hence the this)
I did a profling inside electron and this is what came out:
Note that actually transferring the 40Mbytes audio file doesn't take that long (around 80ms) what is extremely annoying is the "Second Task" which is probably buffering (I have no idea) which last around 950ms, this is way too long and ideally would need it under <220ms
I've already tried changing the preload option to all available options and while I'm using the native html5 audio right now I've also tried howlerjs with similar results (seemed a bit faster tho).
I would guess that loading the file directly might be faster but even after disabling security measures put by electron to block the file:/// it isn't recognized as a valid URI by XHR
Is there a faster way to load the dataurl since all the data is there it just needs to be converted to a buffer or something like that ?
Note: I can not "pre-buffer" every file in advance since there is about 200 of them it just wouldn't make sense in my opinion.
Update:
I found this post Electron - throws Not allowed to load local resource when using showOpenDialog
don't know how I missed it, so I followed step 1 and I now can load files inside electron with the custom protocol, however, nor Audio nor howlerjs is faster, it's actually slower at around 6secs from click to first sound, is it that it needs to buffer the whole file before playing ?
Update 2:
It appears that the 6sec loading time is only effective on the first instance of audio that is created. I do not know why tho. After that the use of two instances (one playing and one pre-buffering) work just fine, however even loading a file that isn't loaded is instantaneous. Seems weird that it only is the firs one.

scons: How to deal with dynamic targets?

I'm trying to automate my work of converting PDF to png file with scons. The tool used for my conversion is convert from ImageMagick.
Here's the raw command line:
convert input.pdf temp/temp.png
convert temp/*.png -append output.png
The first command will generate one PNG file for each page in PDF file, so the target of the first command is a dynamic file list.
Here's the SConstruct file I'm working on:
convert = Builder(action=[
Delete("${TARGET.dir}"),
Mkdir("${TARGET.dir}"),
"convert $SOURCE $TARGET"])
combine = Builder(action="convert $SOURCE -append $TARGET")
env = Environment(BUILDERS={"Convert": convert, "Combine": combine})
pdf = env.PDF("input.tex")
pngs = env.Convert("temp/temp.png", pdf) # I don't know how to specify target in this line
png = env.Combine('output.png', pngs)
Default(png)
The code pngs = env.Convert("temp/temp.png", pdf) actually is wrong since the target is multiple files that I don't know how many before env.Convert is executed, so the final output.png only contains the first page of the PDF file.
Any hint is appreciated.
UPDATE:
I just found that I can use command convert input.pdf -append output.png to avoid the two-step conversion.
Still I'm curious how to handle the scenario when the intermediate temporary file list is unknown beforehand and requires a dynamic target list.
If you want to know how to do the original (convert and combine) situation you proposed, I would suggest creating a builder with a SCons Emitter. The emitter allows you to modify the list of source and target files. This works nicely for generated files that dont exist with a clean build.
As you mentioned, the convert step will generate multiple targets, the trick is you need to be able to "calculate" those targets in the emitter based on the source. For example, recently I created a wsdl2java builder and was able to do some simple wsdl parsing in the emitter to calculate all of the target java files to be generated (the source being the wsdl).
Here is a general idea of what the build scripts should look like:
def convert_emitter(source, target, env):
# both and source and target will be a list of nodes
# in this case, the target will be empty, and you need
# to calculate all of the generated targets based on the
# source pdf file. You will need to open the source file
# with standard python code. All of the targets will be
# removed when cleaned (scons -c)
target = [] # fill in accordingly
return (target, source)
# Optionally, you could supply a function for the action
# which would have the same signature as the emitter
convert = env.Builder(emitter=convert_emitter,
action=[
Delete("temp"),
Mkdir("temp"),
"convert $SOURCE $TARGET"])
env.Append(BUILDERS={'Convert' : convert})
combine = env.Builder(action=convert_action, emitter=combine_emitter)
env.Append(BUILDERS={'Combine' : combine})
pdf = env.PDF('input.tex')
# You can omit the target in this call, as it will be filled-in by the emitter
pngs = env.Convert(source=pdf)
png = env.Combine(target='output.png', source=pngs)
Depending on what qualifies as "dynamic" for you, I believe the correct answer is: not possible.
As long as the source on which you would like to "dynamically" compute a target set is present when SCons is run, #Brady's solution should work fine. However, if the source in question itself is the target of some other command, it will not work. This is a fundamental limitation of SCons, as it makes the assumption that the set of build targets can be statically determined from the base set of input (non-intermediate) sources. It runs through and computes a build/target/dependency graph in one sweep, then executes it in the next. It has no ability to run through some known portion of the build graph, stop to introspect some intermediate targets to dynamically compute the rest of the build graph, and then continue. I'd frankly love for this ability in the work that I do with SCons, but I'm afraid this is just a fundamental limitation.
The best you can do is set the build up so that on the first run, it stops at the construction of the PDF (if no PDF target exists when the build script is executed). Once the PDF has been built, you can rerun the build and set things up so the rest of the build steps execute based on the PDF built from the last run. This more or less works decently... except for one problem. If the PDF ends up changing (and producing some new pages for instance), you'll actually have to rerun the build twice in order to capture the changes to the PDF, since any page counts (etc) will be based on the old version of the PDF.
I'd love for someone to prove me wrong here, but such is the way of things.
Looking at this, there's no requirement for the individual temp/*png to be kept - if there was, you shouldn't be putting them in a temp directory, and in any case you'd have to do quite a bit of work if you wanted to work out which pages to generate.
So it looks more sensible to do this as one step, this So you'd have something like this
png = env.Convert('output.png', 'input.pdf')
where the action function for convert was something like this:
Delete('temp'),
Mkdir('temp'),
'convert $SOURCE temp/$TARGET',
'for i in temp/*png; do convert $TARGET temp/$i',
Delete('temp')
Though frankly you might do better with writing that whole thing as a single callable script to make sure you got the page sorting correct.

Matlab GUIDE GUI Handles change in values after using Load() function?

Inside a GUI that I have made using GUIDE in Matlab. I run into a problem where upon using the Load() function to load a .MAT file all my handles change values. This means that if I had a button that I wanted to use on my GUI. My program will believe its handle is for example
handles.button1 =190.082
when in reality the only way I can access that button any more is through a different handle that is unknown. So if its unknown lets see what its new handle must be.
findobj('Tag','button1') = 227.0093
As you can see these numbers are completely different. Why the handles values get changed is beyond me. Since the handles change I can no longer use the set() function as I have written in previous sections of code. For example I have to change
set(handles.button1, 'Enable', 'off');
to
set(findobj('Tag','button1'),'Enable','off');
Does anyone have an explanation as to why this problem occurs when using Load()?
Is there a feasible solution instead of having to find the handle for an object every time you want to use it?
The .MAT file conveniently also had a handles variable in it which overwrote my current handles.

Resources