FLTK neka pitanja

Evo pokusavao sam napraviti gui za x/o (tic tac toe) u fltk. Ideja: stavio sam 9 obicnih Fl_Button -s
koji treba da predstavljaju polja. Klikom na to dugme callback mijenja label tog dugmeta u x ili o. To je sve proslo ok. Unos se upisuje u 2d niz inicijaliziran na 0 da bi znali da li vec postoji unos. Sada me zanima kako da znam koje je dugme kliknuto npr.

±-+ ±-+ ±-+
| 1 | | 2 | | 3 |
±-+ ±-+ ±-+

.
.
. itd.

recimo klikom na dugme 1 treba da upise x ili oks (1,2) u niz[0][0]. Ja sam razmisljao da kao userdata
u callback svakog dugmeta stavim neki pokazivac ili referencu koji bi promjenio neku varijablu u main-u ili da citav niz pozovem kao argument. Buni me onaj (void*) u argumentu userdata. Na koji nacin se moze staviti pokazivac ili referenca na to mjesto. Ima li neko bolju ideju ili drugi pristup problemu ? Nadam se da je pitanje bilo razumljivo :slight_smile:

ljudi… ovo se shiri… izgleda da je zarazno :smiley:

izvinjavam se zbog [spam]-a :smiley:

Ovakvim postavljanjem pitanja mozes ocekivati samo odgovor od FLTK profesionalca sa kristalnom kuglom …

Ako odgovoris na sljedeca pitanja: Koji void* ? koji userdata ? u argumentu cega? I kopiras nam problematicni kod odgovor mozes ocekivati od svih ljudi koji rade sa c++om ili cak c-om :slight_smile:

evo da pokusam malo jasnije napisati sta sam htio pitati :slight_smile:

nrp:
jedna callback funkcija koja kao drugi arg prima void* userdata.

void but_cb( Fl_Widget* o, void* userdata ) { . . cout<<int(userdata); }
poziv callback funkcije

gdje ovaj drugi argument 12345 predstavlja userdata. Klikom na dugme u konzoli ce biti ispisano 12345.

Moje pitanje je bilo, da li se moze kao userdata staviti pokazivac ili referenca ? Buni me to sto callback funkcija kao drugi argument prima (void*).

Evo moje pitanje predstavljeno na jednom jednostavnom primjeru :

Imam napravljena tri Fl_Buttons. U mainu postoji varijabla int a=0. Klikom na dugme 1 varijabla a treba da poprimi vrijednost 1. Klikom na dugme 2, varijabla a poprima vrijednost 2. … dugme 3 varijabla a poprima vrijednost 3. Nadam se da sam sada bio bar malo jasniji.

Hvala

[code]#include

using namespace std;

void smanji_za_jedan(void *);

int main(void)
{
int rezultat = 12345;
cout<<"Prije: "<<rezultat<<endl;
smanji_za_jedan(&rezultat);
cout<<"Poslije: "<<rezultat<<endl;

return 0;

}

void smanji_za_jedan(void *userdata)
{
int *rez = static_cast<int *>(userdata);
*rez -= 1;
}[/code]
Evo primjer koji sadrzi rjesenje tvog problema - pa ti skontaj … :slight_smile:

Callback funkcija može primati i long kao parametar a ne samo void*. Void* je pointer na bilo šta (što ti olakšava prosljeđivanje najrazličitijih vrsta argumenata npr. možeš proslijediti pointer na neki Fl_Input koji je vezan za to dugme, samo ne zaboravi odraditi odgovarajući cast).

@testni_hamo2: tvoji odgovori su bili izuzetno helpful u ovom slučaju :slight_smile:

ok, sad mi je puno jasnije sta callback prima kao argument.

Možel samo jedno (dobronamjerno) pitanje, zar se to ne može ljepše odraditi u C++? Prosljeđivanje parametara kao void* koristi se u C-u, ali se time gubi type safety.

Moglo bi se to rijesiti uz pomoc templatea ?

Ljepše - da, jednostavnije…? FLTK = Fast Light Toolkit :slight_smile: Generalno FLTK zastupa pristup programiranju “C+objekti” koji se meni inače sviđa.

Ja bi preporucio da kreiras neki svoj StateButton, izveden iz Fl_Button koji mijenja interno stanje (i label()) prilikom callback-a. Time ces izbjeci potrebu za 2d nizom.

Možel samo jedno (dobronamjerno) pitanje, zar se to ne može ljepše odraditi u C++?
Moglo bi se to rijesiti uz pomoc templatea ?
Naravno, http://sanel.linux.org.ba/fltk/

Prosljeđivanje parametara kao void* koristi se u C-u, ali se time gubi type safety.
Ah, suplja prica. gcc ionako u compile time-u “void” resolvira u odgovarajuci tip.

[quote=Sanel]> Prosljeđivanje parametara kao void* koristi se u C-u, ali se time gubi type safety.
Ah, suplja prica. gcc ionako u compile time-u “void” resolvira u odgovarajuci tip.[/quote]
Svejedno, gadno je :stuck_out_tongue:

Ne resolvira GCC ništa, ako se slučajno za***eš i proslijediš pogrešan pointer, ode program u …

Upravo tako. void smanji_za_jedan(void *userdata) { int *rez = static_cast<int *>(userdata); *rez -= 1; }
Npr. ova funkcija prima ‘pointer na bilo sta’ tj. ‘void *’, nemoguce je da compiler pri compile time-u resolva tip; nebitno kako se pozove funkcija smanji_za_jedan, compajler nece praviti probleme sve dok je sintaksa korektna.

Npr. sljedeci dio koda je za vrijeme compiletime-a sasvim legalan

std::string a("abc"); smanji_za_jedan(&a); std::cout << a << endl;
al ce se zato program srusiti pri runtime-u.

Onda koristi PyFltk, Rubyfltk ili Perl::Fltk. C++ nije za ljude slabog srca :slight_smile:

Ne resolvira GCC ništa
Ok, da malo pojasnim. Nacin resolviranja nije identican kao kod template-a zbog toga sto u ovom slucaju (void*) vrijedi samo nad pokazivacima (aka. pointer aliasing). U C99 je detaljno pojasnjeno sta moze biti alias za sta, mada od samih pocetaka void* je bio alias za pokazivac bilo kakvog tipa.

Ponekad se znalo desiti u 3.x seriji da za prototip “void foo(void*)” pri nekoj gresci javi “in void foo(int*) bla bla” ako se funkcija poziva samo sa int* tokom citavog koda.

ova funkcija prima ‘pointer na bilo sta’ tj. ‘void *’, nemoguce je da compiler pri compile time-u resolva tip
Gore pojasnjeno. Btw. kompajler uvijek moze da resolvira tip (izuzev slucajeva kad se jave viseznacni izrazi).

al ce se zato program srusiti pri runtime-u.
Ne vidim kakve veze ima tvoj primjer sa distinkcijom tipova.

Ne mora imati veze sa distinckijom tipova. Prica je krenula kada je Adis pomenuo type safety probleme, a oni su ilustrirani navedenim primjerom.

Pogotovo kad se autor koda potrudi da odrzi takvu reputaciju C+±a :wink:

Nije problem u reputaciji C+±a nego u tvom neshvatanju koji programski jezik služi za šta.

Prica je krenula kada je Adis pomenuo type safety probleme, a oni su ilustrirani navedenim primjerom.
A zar nije prica krenula u pravcu resolviranja tipova ? :stuck_out_tongue:

Pogotovo kad se autor koda potrudi da odrzi takvu reputaciju C+±a :wink:
Kao sto je neko rekao u kontekstu C+±a: “there is no safe shotgun” :slight_smile:

Nisam imao osjecas da uopste postoji problem. Ukoliko si ti procijenio nivo mog (ne)shvatanja svrhe programskih jezika na osnovu dva one-linera, nemam zelju da te razuvjerim.

Za kraj mali zakljucak. Svrha jezika moze posluziti kao praktican izgovor za njegovu sustinsku neelegantnost.