I have directly tried to convert C++ example of mathGL Into C code here:
#include <mgl2/mgl_cf.h>
#include <mgl2/wnd_cf.h>
#include <mgl2/fltk.h>
#include <pthread.h>
#include <synchapi.h>
//mglFLTK *gr=NULL; // pointer to window
HMGL gr = NULL;//HMGL mgl_create_graph_fltk
void *calc(void *) // function with calculations
{
// mglPoint pnt; // some data for plot
// HMDT dat;
// dat= mgl_create_data () ;
for(long i=0;;i++) // do calculation
{
// long_calculations(); // which can be very long
// Sleep(200);
for(uint64_t i=0;i<200000;i++);
// pnt.Set(2*mgl_rnd()-1,2*mgl_rnd()-1);
if(gr)
{
// gr->Clf(); // make new drawing
mgl_clf ( gr) ;
// draw something
// gr->Line(mglPoint(),pnt,"Ar2");
mgl_line(gr,0,0,0,2*mgl_rnd()-1,2*mgl_rnd()-1,0,"Ar2",2);
char str[16]; snprintf(str,15,"i=%ld",i);
// gr->Puts(mglPoint(),str);
mgl_puts(gr,0,0,0,str,":C",-.7);
// don’t forgot to update window
// gr->Update();
mgl_wnd_update(gr);
}
}
}
But it doesn't work. I've added printf before mgl_wnd_update to printing i in console and it only prints one time: i=0. I'm using windows 10 and installed minGW GCC and mathgl by MSYS2 through eclipse IDE. Though I've created the not threaded one here:
int main(int argc,char **argv)
{
gr = mgl_create_graph_fltk(NULL, "First C graph", NULL, NULL);
mgl_fltk_thr ();
while(1)
{
Sleep(100);
mgl_clf ( gr) ;
// draw something
// gr->Line(mglPoint(),pnt,"Ar2");
mgl_line(gr,0,0,0,2*mgl_rnd()-1,2*mgl_rnd()-1,0,"Ar2",-.5);
char str1[16]; snprintf(str1,15,"i=%ld",1);
// gr->Puts(mglPoint(),str);
mgl_puts(gr,0,0,0,str1,":C",-.5);
// don’t forgot to update window
// gr->Update();
mgl_wnd_update(gr);
}
return 0;
}
And this is works. What is wrong with that pthreaded code? It seems that the thread loop only works once. But this loops works well on none-threade program!!
Related
I'm making a whack-a-mole program, and currently I have the setup for the mole to appear and disappear at random; however, while this is all going on I'll need to accept user input in order to "whack" the mole. Is there any way to do this without pausing the loop to wait for the user to input something, and rather have the loop run WHILE scanning for input? my code is below.
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <stdbool.h>
int main(){
// sets the mole to be initially under_ground
bool above_ground = false;
char mole_presence[1] = {0};
// keeps the mole running as long as the game is in play
while(1){
// while the mole is not above ground, wait until he randomly is
while(above_ground == false){
int r = rand() % 6;
if (r == 5){
printf("a mole has appeared, he's dancing around!\n");
mole_presence[0] = 1;
above_ground = true;
}
else{
printf("%d\n", mole_presence[0]);
sleep(1);
}
}
// while the mole is above ground, he dances until he randomly escapes
while(above_ground == true){
bool escaped = false;
// while he hasn't escaped, continue this loop
while (escaped == false){
int x = rand() % 10;
// if he randomly escapes, break out and show he is no longer above ground
if (x == 5){
printf("he disappeared!\n");
mole_presence[0] = 0;
escaped = true;
}
else{
printf("%d\n", mole_presence[0]);
sleep(1);
}
}
above_ground = false;
}
}
}
I faced the same problem while writing a snake-xenia kind of game. In Windows there is function called _kbhit which can be used to check whether the key is pressed or not. It's prototype is
int _kbhit(void)
Itreturns a nonzero value if a key has been pressed. Otherwise, it returns 0. Read more here : https://msdn.microsoft.com/en-us/library/58w7c94c.aspx
It's not available on linux as there is no conio.h in linux So for linux this answer can help Using kbhit() and getch() on Linux
My LAME (v3.99.5) outputs progress in console by moving up x lines in the console and overwriting the previous lines. It's pretty cool.
I've read in a different post that such behavior for a single line can be achieved with a mere "\r" instead of "\n" - although the post was for Ruby, it seems to be the same for C on my system at least:
#include <stdio.h>
#include <time.h>
int main() {
time_t t;
time_t t2;
time(&t);
t2 = t;
printf("%u\r", (unsigned int)t);
fflush(stdout);
while (1) {
if (t2 - t > 0) {
time(&t);
printf("%u\r", (unsigned int)t);
fflush(stdout);
}
time(&t2);
}
return 0;
}
The post further suggests a curses library can be used to make the same behavior multi-line.
What would be a boilerplate example of such code in C?
According to http://falsinsoft.blogspot.com/2014/05/set-console-cursor-position-in-windows.html
Windows:
void SetCursorPos(int XPos, int YPos)
{
COORD Coord;
Coord.X = XPos;
Coord.Y = YPos;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Coord);
}
Linux:
void SetCursorPos(int XPos, int YPos)
{
printf("\033[%d;%dH", YPos+1, XPos+1);
}
You can use something like this:
/!\ Warning: If you stop your curses program without call endwin() before, the terminal used to launch the program will have a very strange behavior.
include <curses.h>
int main(int argc, char *argv[])
{
// init curses
Xinitscr(argc, argv);
// init time
time_t t = 0, t2;
time(&t2);
// main loop
while (1) {
if (t2 - t > 0)
{
time(&t);
clear();
mvprintw(1,1, "%u", (unsigned int)t);
refresh();
}
time(&t2);
}
// end curses mode
// warning: if you do not call this at the end of your program,
// your terminal won't be usable.
endwin();
return 0;
}
The example shown by #purplepsycho has some issues, addressed in this revision (works with "any" X/Open Curses implementation):
#include <curses.h>
int main(int argc, char *argv[])
{
filter();
initscr();
// init time
time_t t = 0, t2;
time(&t2);
// main loop
while (1) {
if (t2 - t > 0)
{
time(&t);
erase();
mvprintw(1,1, "%u", (unsigned int)t);
refresh();
}
time(&t2);
}
endwin();
return 0;
}
That is:
use initscr for initializing curses (PDCurses provides a non-standard function Xinitscr which is not what OP had in mind: it certainly is not often used).
use erase rather than clear (to avoid screen-flicker):
The clear and wclear routines are like erase and werase,
but they also call clearok, so that the screen is cleared
completely on the next call to wrefresh for that window
and repainted from scratch.
use filter to keep the output on a single line. If your terminal switches to the alternate screen, the screen will appear to be cleared. There is a workaround available with ncurses (see filter.c in ncurses-examples).
Better than erase() would be wclrtoeol(), called after the mvprintw.
I have a C program, where I just wanted to test if I could reproduce a console spinner used in npm install while it installs a module. This particular spinner simply spins in this order:
|
/
-
\
on the same space, so I use the following program:
#include <stdio.h>
int main() {
char sequence[4] = "|/-\\";
while(1) {
for(int i = 0; i < 4; i++) {
// \b is to make the character print to the same space
printf("\b%c", sequence[i]);
// now I want to delay here ~0.25s
}
}
}
So I found a way to make it rest for that long from <time.h> documentation and made this program:
#include <stdio.h>
#include <time.h>
void sleep(double seconds) {
clock_t then;
then = clock();
while(((double)(clock() - then) / CLOCKS_PER_SEC) < seconds); //do nothing
}
int main() {
char sequence[4] = "|/-\\";
while(1) {
for(int i = 0; i < 4; i++) {
printf("\b%c", sequence[i]);
sleep(0.25);
}
}
}
But now nothing prints to the console. Does anyone know how I can go about producing the behavior I want?
EDIT According to what appears to be popular opinion, I've updated my code above to be the following:
#include <stdio.h>
#include <unistd.h>
int main() {
char sequence[4] = "|/-\\";
while(1) {
for(int i = 0; i < 4; i++) {
printf("\b%c", sequence[i]);
/* fflush(stdout); */
// commented out to show same behavior as program above
usleep(250000); // 250000 microseconds = 0.25 seconds
}
}
}
You will need to flush after you wrote to the console. Otherwise, the program will buffer your output:
fflush(stdout);
Things do get printed to console, it's just does not get flushed. Add fflush(stdout) to see the results, or set the console in an unbuffered mode by calling setbuf:
setbuf(stdout, NULL);
A bigger problem with your code is that your sleep method runs a busy loop, which burns CPU cycles for no good reason. A better alternative would be to call usleep, which takes the number of microseconds:
usleep(25000);
The sleep function isn't really your problem. The issue is that the output is buffered. The simplest thing to do will be to research ncurses.
For now:
fflush(stdout);
I'm writing a small school project. It's a game of falling words - the word is moving from the top to the bottom. I had an idea to make two windows (one with interface and second with moving object). Words are randomized as you can see in the code. The problem is the input. I'm using mvwsacanw to write the word. Is there any way to write anything in second window while the word is moving in different window? For now the word is falling and when it reaches the bottom, the second window opens and I can type the word.
Hope somebody will help me.
#include <stdio.h>
#include <ncurses.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
void moving(WINDOW *move)
{
int j,random;
char *cmp=(char*)malloc(10*sizeof(char));
char word[6];
wclear(move);
box(move, 0, 0);
mvwprintw(move, 1, 1, "PIS");
wrefresh(move);
srand (time (NULL));
random=2+rand()%7;
for(j=0; j< random ; j++) //random word
{
word[j]= rand()%26+'a';
}
int poz = 2+rand()%24; //random position of moving word
for(int i=1; i<18; i++)
{
wclear(move);
box(move,0,0);
mvwprintw(move,i, poz, word);
wrefresh(move);
usleep(300000);
}
}
void interface(WINDOW *ui)
{
wclear(ui);
char *cmp=(char*)malloc(10*sizeof(char));
box(ui, 0, 0);
mvwprintw(ui,1,1,"wpisz wyraz: ");
mvwscanw(ui,2,1, "%s",cmp);
mvwprintw(ui, 3, 1, "->%s",cmp);
wrefresh(ui);
}
int main(int argc, char *argv[])//int argc, const char * argv[])
{
int x,y;
int sc = 3;
initscr();
noecho();
curs_set(FALSE);
getmaxyx(stdscr, y,x);
WINDOW *move = newwin(y-5, x-1, 0, 0);
WINDOW *ui = newwin(sc+2, x, y-5, 0);
while(1)
{
moving(move);
interface(ui);
wclear(move);
wclear(ui);
}
delwin(move);
delwin(ui);
endwin();
return 0;
}
You can't do that with your current code structure. You are keeping the word fall phase and the input phase in separate functions, so the only way to make them work at the same time is some kind of multithreading.
Assuming this is not what you want to do, you could try to merge the two features in a single function. In pseudocode:
pick random word
pick random position
set i = 0
set input = {} //empty array
do
> print word at (i, pos)
> set stoptime = time() + DELAY
> do
>> set c = getch()
>> append c to input
>> print interface
> while (time() < stoptime)
> i++
while (i < 18)
This, with timeout() set to an opportune delay, will give the impression that everything is happening simultaneously.
This is absolutely not the most efficient solution, but is simple and straightforward, and considering you are working on a school project, it should be just fine
Try to use the following code :
nodelay(your_window, TRUE);
which will make your input nonblocking for the given window !
I am training to use thread on face,nose,eyes detection. Because, when I did not, the camera is working very slowly. I wrote this code. I can not find mistake in code. But when I compiled it is giving exception on taskCollection tab pChore->m_pFunction(pChore); error.
#include <iostream>
#include "cv.h"
#include "highgui.h"
#include <pthread.h>
#include <stdio.h>
struct parameter_t{
IplImage* capturedImg;
CvHaarClassifierCascade* pCascade_face;
CvMemStorage* storage;
};
void* threadface_func(void* parameter){
CvSeq * detectRect_face;
parameter_t *p =(parameter_t*)parameter;
detectRect_face=cvHaarDetectObjects(p->capturedImg,p->pCascade_face,p->storage,1.15, 3, 0,cvSize(50,50));
for(int i=0;i<(detectRect_face ? detectRect_face->total:0); i++ )
{
CvRect* r = (CvRect*)cvGetSeqElem(detectRect_face, i);
CvPoint pt1 = { r->x, r->y };
CvPoint pt2 = { r->x + r->width, r->y + r->height };
cvRectangle(p->capturedImg, pt1, pt2, CV_RGB(255,0,0), 1,8, 0);
}
return 0;
}
int main ()
{
CvCapture* capture = cvCaptureFromCAM(0);
IplImage* capturedImg;
int resCount = 1;
int flags = CV_HAAR_FIND_BIGGEST_OBJECT | CV_HAAR_DO_ROUGH_SEARCH;
CvHaarClassifierCascade * pCascade_face;
pthread_t threadface;
pCascade_face = (CvHaarClassifierCascade *)cvLoad("C:/Users/Furkan/Desktop/Computer Vision/Programlar/opencv/data/haarcascades/haarcascade_frontalface_alt.xml");
cvNamedWindow("FaceDetection");
while (true)
{
CvMemStorage * storage = 0;
capturedImg = cvQueryFrame(capture);
storage = cvCreateMemStorage(0);
parameter_t my_parameters;
my_parameters.capturedImg=capturedImg;
my_parameters.storage=storage;
my_parameters.pCascade_face=pCascade_face;
int k=pthread_create(&threadface,0,threadface_func,(void*)&my_parameters);
if(k!=0)
{
printf("Create thread failed! error");
return 1;
}
cvShowImage("FaceDetection", capturedImg);
}
cvDestroyWindow("FaceDetection");
cvReleaseCapture(&capture);
pthread_exit(NULL);
return 0;
}
Please Help.
the IplImages you get from the capture are pointing to videodriver-memory. to use them in another thread, youve got to clone() them. (i see, that you're even trying to draw into that).
you're generating new threads at an absurd high rate there, without ever waiting for one to finish
i can't see any lock/mutex in your code
please reconsider using multiple threads at all. at least, it won't work like this
(seems, that your opencv version & your api use could need an upgrade, too .. )