How does one create an array of loaders?
The bigger picture:
I have written a mapping program in flex. I want to change my mapping program so that all I need to do is drop in a new xml file instead of going into my flex file and adding the exact number of item loaders I need. So I guess I'm looking for an array of loaders that can load the image files that are within my XML file.
xml file example:
<locations>
<location>
<name>Big Star</name>
<street>123 Some St.</street>
<city>City</city>
<state>XX</state>
<zip>555555</zip>
<lat>12.34567</lat>
<long>-67.54321</long>
<iconFile>bigStar_icon.gif</iconFile>
<imageFile>bigStar_img.swf</imageFile>
<motion>no</motion>
<featured>yes</featured>
<category>Grocery</category>
</location>
</locations>
this xml can sometimes have 2000 locations.
Yeah, that's a pretty bad question. Literally (if facetiously):
var loaders:Array = [new Loader(), new Loader()];
Trying to read into what you asked, it sounds like you are trying to load up a whole bunch of stuff and handle them all loading together somehow... and if you have to ask, you're going to struggle.
You could try using the Bulk Loader library though, which does this for you reasonably well. There are probably others.
Not a direct answer to the question since it's a bit vague + #alecmce already gave an answer (I would go for a loader queue such as BulkLoader in this situation as well).
However, since I noticed a similar question some time ago I just wanted to point out that instantiating all the loaders at once just feels a bit wrong.
Wouldn't it be a bit appropriate to just store the urls and handle process them one by one ?
Basic example :
(beware I typed it in without testing...)
// So here's the point: only Strings are stored ...
var urls:Array = new Array('image1.jpg','image2.jpg',image3.jpg);
loadNext();
function loadNext()
{
if(urls.length() == 0)
return;
load(urls.shift())
}
function load(url:String):void
{
// The loader is created lazily just before before we need it
var loader:Loader = new Loader(new URLRequest(url));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded)
loader.load(url);
}
function onLoaded(e:Event):void
{
event.target.removeEventListener(Event.COMPLETE, onLoaded);
addChild(event.target.content); // ... or whatever has to happen here.
loadNext();
}
Related
I'm working on a script that does find/replace for missing items in your project. Unfortunately I'm running into a situation detecting and then replacing layered image sources (psd, ai, etc.).
1) I see no way of detecting if a AvItem is a layer within a layered image other than parsing the item.name, which is unreliable because a user can always rename items in the project panel.
2) Once I do know that it is a part of a layered image I cannot figure out how to re-link it to the correct image without replacing the layer with the merged image. item.replace(new_path) will replace that item with the whole image, not the layer within the image. For example:
var item = app.project.item(3); //assuming this is the 'layer' we want to replace
item.replace(new_path);
So is there a secret property somewhere which will reliably tell me if an item is a part of a layered image, and if so is there a way to relink it without replacing the layer with the entire merged image?
EDIT
Here's a function to guess if a layer is part of a layered image. It's not bullet-proof but it should work as long as the user does not rename the item:
function isSourceLayered (av_item) {
// check if there is a "/"
if (av_item.name.indexOf("/") != -1) {
// check if it is in a "layers" folder
if (av_item.parentFolder.name.indexOf("Layers") != -1) {
return true;
}
}
return false;
}
I just asked the same question on the Adobe extendscript forum. Unless there's undocumented features (and I spent a bit of time looking with Extendscript Toolkit's data browser) the fileSource object doesn't seem to have any attributes or methods to do this.
There is a kind of a workaround, you can import the file using ImportOptions.importAs(ImportAsType.COMP) This will import a comp, and you can loop through the layers matching the name, get the source of that layer and use that as your new source. But as you say, it doesn't work if the source has been renamed.
I've written this into a function, it's available on github Edit: I forgot that I changed the way that function works. It doesn't re-import layer sources because of this problem, it just uses the Duplicate menu command.
The following code works to load a local, static JSON file:
var stories = require('../stories/stories.json');
Now I want to load a file based on a variable, e.g. do something like this:
var storiesPath = '../stories/stories.json';
var stories = require(storiesPath);
But this triggers an error:
Error: Cannot find module '../stories/stories.json'
at require (packages/modules-runtime.js:123:19)
at meteorInstall.server.main.js (server/main.js:7:15)
Is there any way to get this working? I assume that I could load my file via the Meteor http package instead but I'd rather not add another package if I can avoid it.
Thanks for your hints
Like I said in the comment, you can easily use a variable in a require, e.g.,
> var x = 'fs';
> require(x).readFile
[Function]
So that's not the problem you are dealing with. Are you sure your first case indeed works? It would be surprising. I think you might be running into project file layout issues, due to the use of a relative path. I would stay away from that. And fortunately you can quite easily by using an asset! You can put your json file in private/ in your project folder and then use:
const stories = JSON.parse(Assets.getText('stories.json'));
Looking for a way to add a custom timestamp(and maybe some extra info) inside a CSS/HTML file everytime you save the file. Is there an extention for brackets, sublime or dreamweaver that does this, Or perhaps some other way to do this?
Thanks
I think this post will give you a Sublime Text plugin that should do what you ask.
In Brackets, you can configure the snippets extension to insert a timestamp manually, like the answer above for Sublime. Here's how: https://stackoverflow.com/a/18844762/1172352.
Similar to the Sublime answer, it would be a bit trickier to do it automatically every time you save. There's not yet a clean hook in Brackets for pre-save processing. Several extensions get around this by listening for a post-save event and saving quickly a second time. You could probably write a timestamp-auto-inserter extension by borrowing their code for that pattern.
Anything that runs automatically would also need a little extra code to find the old timestamp and replace it -- both the snippets solution here and the Sublime solution above just insert the timestamp wherever the cursor/selection is. A regular expression should do the trick for detection.
You'd also want to screen out other file types. Bringing it all together, it would look something like this for Brackets:
function documentSavedHandler(event, doc) {
// TODO: need a little extra code here to ignore save events triggered
// by ourself, to avoid infinite loop
var langId = doc.getLanguage().getId();
if (langId === "html" || langId === "css") {
var pos = /* use regexp to find old timestamp */;
doc.replaceRange(timestampStr, posStart, posEnd);
CommandManager.execute(Commands.FILE_SAVE);
}
}
I'm working in some old code which was originally designed for handling two different kinds of files. I was recently tasked with adding a new kind of file to this code. Most of my problems were solved by filling out an extensive XML file with a new entry that handled everything from what lists were named to how the file is written in plural lower case. But this ended up being insufficient, as there were maybe 50 different places in 24 different code files where I had to update hardcoded switch-statements that only branched for the original two file types.
Unfortunately there is no consistency in this; there are methods which operate half from the XML file, and half off of hardcode. Some of the files which look like they would operate off of the XML file don't, and some that I would expect that I'd need to update the hardcode don't need it. So the only way to find the majority of these is to run through testing the whole system when only part of it is operational, finding that one step to fix (when I'm lucky that error logging actually tells me what is going on), and then running the whole thing again. This wastes time testing the parts of the code which are already confirmed to work, time better spent testing the new parts I have to add on top of it all.
It's a hassle and a half, and to my luck I can expect that I will have to add yet another new kind of file in the near future.
Are there any solutions out there which can aid in this kind of endeavour? Something which I can input some parameters of current features, document what points in a whole code project actually need to be updated, and run something nice the next time I need to add a new feature to the code. It needn't even be fully automated, something that'll help me navigate straight to the specific points in everything and maybe even record what kind of parameters need to be loaded.
Doubt it matters specifically, but the code is comprised of ASP.NET pages, some ASP.NET controls, hundreds of C# code files, and a handful of additional XML files. It's all currently in a couple big Visual Studio 2008 projects.
Not exactly what you are describing, but if you can introduce a seam into the code and lay down some interfaces you can break out and mock, a suite of unit/integration tests would go a long way to helping you modify old code you may not fully understand well.
I completely agree with the comment about using Michael Feathers' book to learn how to wedge new tests into legacy code. I'd also strongly recommend Refactoring, by Martin Fowler. What it sounds like you need to do for your code is to implement the "Replace conditionals with polymorphism" refactoring.
I imagine your code today looks somewhat like this:
if (filetype == 23)
{
type23parser.parse(file);
}
else if (filetype == 69)
{
filestore = type69reader.read(file);
File newfile = convertFSto23(filestore);
type23parser.parse(newfile);
}
What you want to do is to abstract away all the "if (type == foo)" kinds of logic into strategy patterns that are created in a factory.
class FileRules : pReader(NULL), pParser(NULL)
{
private:
FileReaderRules *pReader;
FileParserRules *pParser;
public:
void read(File* inFile) {pReader->read(inFile);};
void parse(File* inFile) {pParser->parse(inFile);};
};
class FileRulesFactory
{
FileRules* GetRules(int inputFiletype, int parserType)
{
switch (inputFiletype)
{
case 23:
pReader = new ASCIIReader;
break;
case 69:
pReader = new EBCDICReader;
break;
}
switch (parserType)
... etc...
then your main line of code looks like this:
FileRules* rules = FileRulesFactory.GetRules(filetype, parsertype);
rules.read(file);
rules.parse(file);
Pull off this refactoring, and adding a new set of file types, parsers, readers, etc., becomes as simple as writing one exclusive to your new type.
Of course, go read the book. I vastly oversimplified it here, and probably got stuff wrong, but you should get the general idea of how to approach it from this. I can also recommend another book, "Head First Design Patterns", which has a great section on the Factory patterns (if you like those "Head First" kinds of books.)
I'm using the VideoDisplay to play flv's, mov's, and mp4's and everything is working great. They are all being loaded via progressive download and are not being streamed. What I'd like to do is to grab a single specified frame (like whatever is being shown at the 10 second mark), convert it to a bitmap and use that bitmap as the preview image for the video. I'd like to do this at runtime so I don't have to create a preview image for every video that would be shown.
Any idea's on how to do this? I'd rather not fake it by playing it - seeking for that specific frame and then pausing it but I may have no other choice?
Ryan and James are correct -- the right way's probably to extract frames at upload/transcode-time. But if that's not an option, you could opt for using some sort of a default/placeholder image of your own (something generic or somehow suitable for all videos whose thumbs haven't yet been captured), and just use VideoDisplay's DisplayObject-ness to grab and then upload a frame to your server, e.g.:
<mx:Script>
<![CDATA[
var captured:Boolean;
private function creationCompleteHandler(event:Event):void
{
videoDisplay.source = "http://yourserver/yourvideo.flv";
}
private function videoDisplay_playheadUpdate(event:VideoEvent):void
{
if (!captured && videoDisplay.playheadTime >= 10)
capture();
}
private function capture():void
{
var bmpData:BitmapData = new BitmapData(videoDisplay.width, videoDisplay.height);
bmpData.draw(videoDisplay);
captured = true;
// Now just upload the byte array to your server for the next user
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
// ... etc.
}
]]>
</mx:Script>
<mx:VideoDisplay id="videoDisplay" playheadUpdate="videoDisplay_playheadUpdate(event)" />
Again, it's perhaps not the most elegant solution, but it certainly works. This way, the first user sees the generic image, but every user thereafter gets the generated thumbnail. (Which, of course, you'll have uploaded and properly associated by then.) Make sense?
I'm pretty sure this isn't possible. It may well be... but don't think so. I think the only way to load in video is to use the NetStream and NetConnection object, which as you know just kicks off the loading of the video.
If this is user generated video i think the best bet is to have some serever side script that generates the preview image. Have no idea how this is done but think this is how most clip sites work.
If all the videos are in your control it may be possible to write a script for one of the video editing programs to automate generating the image for a specific frame from a list of files. I think this is probably your best route as alternative that you could get up and running quickly.
Sorry for the vague answer... it may point you in the right direction if you need a quick solution.
I agree with James, the only way to really do this would be to do it with a server side script and pull certain frames out of the video. Even if you could do this with flex, you really would not want to put the burden to do this (which would be processor intensive I would think) on the client machine. Not to mention it will be much more efficient to create the image before hand than to have flex determine the thumbnail to show every time it is loaded.