playing PDE files in a loop? - processing

I'm still relatively new to Processing. We are thinking of showing our Processing work in a loop for a small exhibition. Is there a way to play multiple PDEs in a loop? I know I can export as frames and then assemble them as a longer loop-able Quicktime file, but I'm wondering if there's any way to play and loop the files themselves?
Also, for interactive PDEs, what's the best way to present them? We are thinking of having a couple of computers with PDEs running in Processing but it would be nice to have a file run for 20 minutes and then open another file for 20 minutes.
Thanks in advance!

You should be able to put together a shell/batch script that uses the processing-java command line executable.
You should be able to set that up via the Tools > Install "processing-java"
If you're not confortable with bash/batch scripting you could even write a Processing sketch that launches Processing sketches
Here's a very rough take on it using selectFolder() and exec():
final int SKETCH_RUN_TIME = 10000;//10 seconds for each sketch, feel free to change
ArrayList<File> sketches = new ArrayList<File>();
int sketchIndex = 0;
void setup(){
selectFolder("Select a folder containing Processing sketches:", "folderSelected");
}
void draw(){
}
void nextSketch(){
//run sketch
String sketchPath = sketches.get(sketchIndex).getAbsolutePath();
println("launching",sketchPath);
Process sketch = exec("/usr/local/bin/processing-java",
"--sketch="+sketchPath,
"--present");
//increment sketch index for next time around (checking the index is still valid, otherwise go back to 0)
sketchIndex++;
if(sketchIndex >= sketches.size()){
sketchIndex = 0;
}
//delay is deprecated so you shouldn't use this a lot, but as a proof concept this will do
delay(SKETCH_RUN_TIME);
nextSketch();
}
void folderSelected(File selection) {
if (selection == null) {
println("No folder ? Ok, maybe another time. Bye! :)");
exit();
} else {
File[] files = selection.listFiles();
//filter just Processing sketches
for(int i = 0; i < files.length; i++){
if(files[i].isDirectory()){
String folderName = files[i].getName();
File[] sketchFiles = files[i].listFiles();
boolean isValidSketch = false;
//search for a .pde file with the same folder name to check if it's a valid sketch
for(File f : sketchFiles){
if(f.getName().equals(folderName+".pde")){
isValidSketch = true;
break;
}
}
if(isValidSketch) {
sketches.add(files[i]);
}else{
System.out.println(files[i]+" is not a valid Processing sketch");
}
}
}
println("sketches found:",sketches);
nextSketch();
}
}
The code is commented so hopefully it should be easy to read and follow.
You will be prompted to select a folder containing sketches to run.
Note 1: I've used the processing-java path on my machine (/usr/local/bin/processing-java). If you're on Windows this may be different and you need to change this.
Note 2: The processing-java command launches another Process which makes it tricky to close the previous sketch before running the next one. As a workaround for you you could call exit() on each sketch after the amount of time you need.
Note 3: The code will not recursively traverse the selected folder containing sketches, so only the first level sketches will be executed, anything deeper should be ignored.

Related

How can I randomize a video to play after another by pressing a key on Processing?

I'm quite new to Processing.
I'm trying to make Processing randomly play a video after I clear the screen by mouseclick, so I create an array that contain 3 videos and play one at a time.
Holding 'Spacebar' will play a video and release it will stop the video. Mouseclick will clear the screen to an image. The question is how can it randomize to another video if I press spacebar again after clear the screen.
I've been searching all over the internet but couldn't find any solution for my coding or if my logic is wrong, please help me.
Here's my code.
int value = 0;
PImage photo;
import processing.video.*;
int n = 3; //number of videos
float vidN = random(0, n+1);
int x = int (vidN);
Movie[] video = new Movie[3];
//int rand = 0;
int index = 0;
void setup() {
size(800, 500);
frameRate(30);
video = new Movie[3];
video[0] = new Movie (this, "01.mp4");
video[1] = new Movie (this, "02.mp4");
video[2] = new Movie (this, "03.mp4");
photo = loadImage("1.jpg");
}
void draw() {
}
void movieEvent(Movie video) {
video.read();
}
void keyPressed() {
if (key == ' ') {
image(video[x], 0, 0);
video[x].play();
}
}
void mouseClicked() {
if (value == 0) {
video[x].jump(0);
video[x].stop();
background(0);
image(photo, 0, 0);
}
}
You have this bit of logic in your code which picks a random integer:
float vidN = random(0, n+1);
int x = int (vidN);
In theory, if you want to randomise to another video when the spacebar is pressed again you can re-use this bit of logic:
void keyPressed() {
if (key == ' ') {
x = int(random(n+1));
image(video[x], 0, 0);
video[x].play();
}
}
(Above I've used shorthand of the two lines declaring vidN and x, but the logic is the same. If the logic is harder to follow since two operations on the same line (picking a random float between 0,n+1 and rounding down to an integer value), feel free to expand back to two lines: readability is more important).
As side notes, these bit of logic look a bit off:
the if (value == 0) condition will always be true since value never changes, making both value and the condition redundant. (Perhaps you plan to use for something else later ? If so, you could save separate sketches, but start with the simplest version and exclude anything you don't need, otherwise, in general, remove any bit of code you don't need. It will be easier to read, follow and change.)
Currently your logic says that whenever you click current video resets to the start and stops playing and when you hit the spacebar. Once you add the logic to randomise the video that the most recent frame of the current video (just randomised) will display (image(video[x], 0, 0);), then that video will play. Unless you click to stop the current video, previously started videos (via play()) will play in the background (e.g. if they have audio you'll hear them in the background even if you only see one static frame from the last time space was pressed).
Maybe this is the behaviour you want ? You've explained a localised section of what you want to achieve, but not overall what the whole of the program you posted should do. That would help others provide suggestions regarding logic.
In general, try to break the problem down to simple steps that you can test in isolation. Once you've found a solid solution for each part, you can add each part into a main sketch one at a time, testing each time you add something. (This way if something goes wrong it's easy to isolate/fix).
Kevin Workman's How To Program is a great article on this.
As a mental excercise it will help to read through the code line by line and imagine what it might do. Then run it and see if the code behaves as you predicted/intended. Slowly and surely this will get better and better. Have fun learning!

Code is getting slower with every run (PowerPoint VSTO)

I'm writting a PowerPoint AddIn (VSTO) which makes the following (very roughly):
1. Loop through all slides
2. Loop through all tags for each slide and write the tag information to a List-Object
3. Do some calucations on the List-Object and update some columns in the list-Object
4. Loop through the List-Object and write the tags back to the sorresponding slides / tags
I recognized that this code runs for every run slower and slowwer - the 10th run is 3-4 times slower than the first one.
I also see the memory usage goes up for every run.
What are my tools to check where the bottle neck is?
How can I find the problem which makes my code slower for every run?
Is there a way to clear the memory etc. the AddOn uses after each run?
I'm sorry to ask such general question, but please let me know if you need more details
My PowerPoint has 32 Slides - for each slide i want to write tags (in this example 49 Tags). Because of updates etc. the code is executed several times by the user. I simulate this by doing it 11 times automatically. I recognize here the same behavior as by user interaction: the writing of the tags for the 32 Slides is getting slower with every execute.
I reduced my code to the minimum which has the same behavior. I tried also to first delete the tags on every slide but without success.
private void btn_DoIt10Times_Click(object sender, EventArgs e)
{
Stopwatch watch = new Stopwatch();
watch.Start();
SlideTags_Write();
watch.Stop();
//MessageBox.Show("Time spend: " + watch.Elapsed);
for (int i = 1; i <= 10; i++)
{
SlideTags_Write();
}
Stopwatch watch2 = new Stopwatch();
watch2.Start();
SlideTags_Write();
watch2.Stop();
MessageBox.Show("Time 1st run: " + watch.Elapsed + "\n Time 11th run: " + watch2.Elapsed);
}
public void SlideTags_Write()
{
PowerPoint.Presentation oPresentation = Globals.ThisAddIn.Application.ActivePresentation;
foreach (PowerPoint.Slide oSlide in oPresentation.Slides)
{
//for (int iTag = 1; iTag <= oSlide.Tags.Count; iTag++)
//{
// oSlide.Tags.Delete(oSlide.Tags.Name(iTag));
//}
for (int iTag = 1; iTag < 50; iTag++)
{
oSlide.Tags.Add("Tag_" + iTag.ToString(), "Tag Value " + iTag.ToString());
}
}
}

How to display Images in a wxListCtrl (multicolumn report style)

I already managed to create wxListCtrls with either icons or multicolumn text like this
Picture of two wxListCtrls
Now I'd like to add an icon to each line of the text list on the left. I thought this should be possible as typical wxWidgets applications like code::blocks and wxSmith often diplay icons in list/tree views (resource browser window) and even in tabs of notebooks (compiler log window).
So how can I create something like this? (Everybody knows Windows Explorer)
Picture of Explorer Window with icons
I tried this...
SetImageList (ToolImages, wxIMAGE_LIST_NORMAL);
InsertColumn (0, "Icon");
SetColumnWidth (0, 40);
...
for (int i=0; i<5; i++)
{
InsertItem (i, i);
SetItemColumnImage (i, 0, i);
SetItem (i, 1, IntToStr (i+1));
...
But as you can see, only the text gets displayd, the image column is blank. Is it possible at all to mix text and images in report mode? If not, what other wxControl class can I use to get the desired result?
Many Thanks in advance.
Yes, it is possible, and the listctrl sample shows how to do it, in particular see MyFrame::InitWithReportItems() function. The only difference with your code seems to be that you use a different InsertItem() overload, so perhaps you should use InsertItem(i, "") instead.
Also check that your image list does have the 5 icons in it.
More generally, trying to reduce the differences between your code and the (working) sample will almost always quickly find the problem.
Thanks, VZ, but I found out that it's not the InsertItem() but the SetImageList(). My image list was correct, but the "which" parameter wasn't. Replacing wxIMAGE_LIST_NORMAL by wxIMAGE_LIST_SMALL fixes the problem! I thought "SMALL" was only meant for the SMALL_ICON mode and that "NORMAL" should be the default. But yes, that makes sense, normal icons are big and don't fit in the text display. Would be nice if the documentation had told us that before long trial and error...
This is a simple example for SMALL ICONIC VIEW USING WXLISTCTRL .Please place this code inside the class declaration.I did it in Frame based Windows Application using CODE BLOCKS.It will be useful to you.
wxImageList *il=new wxImageList(32,32,false,0);
wxImageList *i2=new wxImageList(32,32,false,0);
wxDir dir(wxGetCwd());
wxDir dir1(wxGetCwd());
if ( !dir.IsOpened() )
{
// deal with the error here - wxDir would already log an error message
// explaining the exact reason of the failure
return;
}
if ( !dir1.IsOpened() )
{
// deal with the error here - wxDir would already log an error message
// explaining the exact reason of the failure
return;
}
puts("Enumerating object files in current directory:");
wxString path, filename, dirstring,filename1, dirstring1, img,imgPath,path1,img1,imgPath1;
int i=0;
path=wxT("C:\\testing\\splitterwindow\\set\\devices");
path1=wxT("C:\\testing\\splitterwindow\\set\\actions");
img=wxT("C:\\testing\\splitterwindow\\set\\devices\\");
img1=wxT("C:\\testing\\splitterwindow\\set\\actions\\");
bool cont=dir.Open(path);
bool cont1=dir1.Open(path1);
cont = dir.GetFirst(&filename, wxEmptyString, wxDIR_DEFAULT);
dirstring.Append(filename.c_str());
cont1 = dir1.GetFirst(&filename1, wxEmptyString, wxDIR_DEFAULT);
dirstring1.Append(filename1.c_str());
while ( cont )
{
imgPath.clear();
cont = dir.GetNext(&filename);
dirstring.Append(filename.c_str());
// Consturct the imagepath
imgPath.Append(img.c_str());
imgPath.Append(filename.c_str());
//Now, add the images to the imagelist
il->Add(wxBitmap(wxImage(imgPath.c_str())));
i++;
}
while ( cont1 )
{
imgPath1.clear();
cont1 = dir1.GetNext(&filename1);
dirstring1.Append(filename1.c_str());
// Consturct the imagepath
imgPath1.Append(img1.c_str());
imgPath1.Append(filename1.c_str());
//Now, add the images to the imagelist
i2->Add(wxBitmap(wxImage(imgPath1.c_str())));
i++;
}
//assigning the imagelist to listctrl
ListCtrl1->AssignImageList(il, wxIMAGE_LIST_SMALL);
ListCtrl3->AssignImageList(i2, wxIMAGE_LIST_SMALL);
for(int j=0;j < il->GetImageCount()-1;j++)
{
wxListItem itemCol;
itemCol.SetId(j);
itemCol.SetImage(j);
itemCol.SetAlign(wxLIST_FORMAT_LEFT);
ListCtrl1->InsertItem(itemCol);
}
for(int k=0;k < i2->GetImageCount()-1;k++)
{
wxListItem itemCol1;
itemCol1.SetId(k);
itemCol1.SetImage(k);
itemCol1.SetAlign(wxLIST_FORMAT_LEFT);
ListCtrl3->InsertItem(itemCol1);
}
`

reset game in processing

I am making a Tron game in Processing. I have the game all worked out but I do not know how to add a reset option to start a new game after the player loses.
Anyone have some suggestions?
Well usually you should make a method that will reset/recreate/delete what is needed to restart your game. Like(pseudo):
void reset(){
score = 0;
ballsList.removeAll();
playerPositionX = 0;
playerPositionY = 0;
}
And then call it when needed.
Avoid using "init" as name of the method or you will override a built in method.
Wouldn't a simple switch case work fine ?
Switch (levels):
Case one:
Case last level:
If (this == that){
levels = one;
break
}
What I would say is wrap your whole gamecode in a function like void inGame(){gamecodeing} and when something happens like if (player.state == "dead"){inGame();} and the ingame at the starting as well. Like so:
void setup() {
size(500,500);
}
void draw() {
inGame();
if (playerHasLost) {inGame();}
}
void inGame() {gameStuff}
and every time inGame() is called it kind of does it all over again.
I'd reccomend running the setup() again.
And then store your variables in there like x = 0;, score = 0;.

GTK+ - How to listen to an event from within a method?

I'm writing an application that runs an algorithm, but allows you to 'step through' the algorithm by pressing a button - displaying what's happening at each step.
How do I listen for events while within a method?
eg, look at the code I've got.
static int proceed;
button1Event(GtkWidget *widget)
{
proceed = 0;
int i = 0;
for (i=0; i<15; i++) //this is our example 'algorithm'
{
while (proceed ==0) continue;
printf("the nunmber is %d\n", i);
proceed = 0;
}
}
button2Event(GtkWidget *widget)
{
proceed = 1;
}
This doesn't work because it's required to exit out of the button1 method before it can listen for button2 (or any other events).
I'm thinking something like in that while loop.
while(proceed == 0)
{
listen_for_button_click();
}
What method is that?
The "real" answer here (the one any experienced GTK+ programmer will give you) isn't one you will like perhaps: don't do this, your code is structured the wrong way.
The options include:
recommended: restructure the app to be event-driven instead; probably you need to keep track of your state (either a state machine or just a boolean flag) and ignore whichever button is not currently applicable.
you can run a recursive main loop, as in the other answer with gtk_main_iteration(); however this is quite dangerous because any UI event can happen in that loop, such as windows closing or other totally unrelated stuff. Not workable in most real apps of any size.
move the blocking logic to another thread and communicate via a GAsyncQueue or something along those lines (caution, this is hard-ish to get right and likely to be overkill).
I think you are going wrong here:
while(proceed == 0)
{
listen_for_button_click();
}
You don't want while loops like this; you just want the GTK+ main loop doing your blocking. When you get the button click, in the callback for it, then write whatever the code after this while loop would have been.
You could check for pending events & handle the events in while loop in the clicked callback. Something on these lines:
button1Event(GtkWidget *widget)
{
proceed = 0;
int i = 0;
for (i=0; i<15; i++) //this is our example 'algorithm'
{
while (proceed ==0)
{
/* Check for all pending events */
while(gtk_events_pending())
{
gtk_main_iteration(); /* Handle the events */
}
continue;
}
printf("the nunmber is %d\n", i);
proceed = 0;
}
}
This way when the events related click on the second button is added to the event queue to be handled, the check will see the events as pending and handle them & then proceed. This way your global value changes can be reflected & stepping should be possible.
Hope this helps!
If you want to do it like this, the only way that comes to my mind is to create a separate thread for your algorithm and use some synchronization methods to notify that thread from within button click handlers.
GTK+ (glib, to be more specific) has its own API for threads and synchronization. As far as I know Condition variables are a standard way to implement wait-notify logic.

Resources