Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Autres questions


Index du Forum » Autres questions » keydown() never true in timer function
Simnon Hors ligne Membre Points: 79 Défis: 0 Message

keydown() never true in timer function

Posté le 27/10/2025 12:05

when i call the function through the timer it doesnt detect the keydown (works when i call the function directly)
static int Timer;

int TimerFunc(){
    int b = 0;
    while(1){
        clearevents();

        b++;
        dclear(C_WHITE);
        dprint(0,0,C_BLACK,"%d", b);
        dupdate();
        if(keydown(KEY_EXIT)){
            return TIMER_STOP;
        }
    }
}

int main(void)
{
    Timer = timer_configure(TIMER_ANY, 50000, GINT_CALL(TimerFunc));
    
    while(1){
        clearevents();
        
        dclear(C_WHITE);
        drect(0,0,20,20,C_BLACK);
        dupdate();
        if(keydown(KEY_MENU)){
            return 1;
        }
        if(keydown(KEY_EXE)){
            timer_start(Timer);
        }
    }
}



Lephenixnoir En ligne Administrateur Points: 25437 Défis: 174 Message

Citer : Posté le 27/10/2025 15:28 | #


This is because the timer callback runs from an interrupt handler. While TimerFunc is running, any interrupts of priority equal to or lower than the selected timer is disabled. This includes the keyboard driver's polling, which runs on the lowest-priority timer in the system. As a result, the keyboard is not polled and therefore no key state changes are recorded.

This programming style is somewhat dubious, as holding an interrupt for an arbitrary amount of time always blocks other processing. I haven't yet formed a definitive opinion on whether I should allow it and make user timers the lowest-priority elements in the system, or whether it's bad enough of a style to discount it entirely. (For reference, signal handlers in Linux are the most direct comparison, and you can barely do anything in them.)

If you can explain what brought you to this approach instead of having a single core loop which takes input from the handler through a flag, that'll help me decide how to proceed in the future.
Mon graphe (27 Juin): (MQ || Rogue Life) ; serial gint ; passe gint 3 ; Azur ; ...) || (shoutbox v5 ; v5)
Simnon Hors ligne Membre Points: 79 Défis: 0 Message

Citer : Posté le 27/10/2025 18:52 | #


what brought me to this approach is i use the loop at the end of a game (match), where you do completely different things than in the main loop, so i thought i would have no benefit from putting these things in the main loop which would just get more complicated.

I suppose that is the best way to handle this though?
Maybe i can have those gameplay actions and new match actions in 2 functions which i just call from the loop
Fcalva En ligne Membre Points: 632 Défis: 10 Message

Citer : Posté le 27/10/2025 18:54 | #


You could write a second "main" loop instead. It would be a lot cleaner, and actually work
Apréciateur de Noctua moyen
Caltos : G35+EII, G90+E (briquée )
Simnon Hors ligne Membre Points: 79 Défis: 0 Message

Citer : Posté le 27/10/2025 18:59 | #


what do you mean by second main loop
Fcalva En ligne Membre Points: 632 Défis: 10 Message

Citer : Posté le 27/10/2025 19:01 | #


Well have a "main" loop for the first part of gameplay, then a second "main" loop for the second part of the gameplay.
Apréciateur de Noctua moyen
Caltos : G35+EII, G90+E (briquée )
Lephenixnoir En ligne Administrateur Points: 25437 Défis: 174 Message

Citer : Posté le 27/10/2025 19:30 | #


I suppose that is the best way to handle this though?

How about this?

static int Timer;

int OtherLoop(){
    int b = 0;
    while(1){
        clearevents();

        b++;
        dclear(C_WHITE);
        dprint(0,0,C_BLACK,"%d", b);
        dupdate();
        if(keydown(KEY_EXIT)){
            return;
        }
    }
}

int main(void)
{
    volatile int timer_flagged = 0;
    Timer = timer_configure(TIMER_ANY, 50000, GINT_CALL_SET_STOP(&timer_flagged));
    
    while(1){
        clearevents();
        
        dclear(C_WHITE);
        drect(0,0,20,20,C_BLACK);
        dupdate();
        if(keydown(KEY_MENU)){
            return 1;
        }
        if(keydown(KEY_EXE)){
            timer_start(Timer);
        }
        if(timer_flagged)
            OtherLoop();
    }
}

Mon graphe (27 Juin): (MQ || Rogue Life) ; serial gint ; passe gint 3 ; Azur ; ...) || (shoutbox v5 ; v5)
Simnon Hors ligne Membre Points: 79 Défis: 0 Message

Citer : Posté le 27/10/2025 19:45 | #


thanks this seems nice but why is timer_flagged volatile and what is GINT_CALL_SET_STOP()?
Lephenixnoir En ligne Administrateur Points: 25437 Défis: 174 Message

Citer : Posté le 27/10/2025 19:48 | #


GINT_CALL_SET_STOP() is a predefined callback that sets the given variable to true and then stops the timer. It's an alarm, more or less.

The variable is volatile to tell the compiler that it gets modified asynchronously. Otherwise the compiler could optimize away the if(timer_flagged) by claiming that the variable is never set to true after entering the loop, by assuming "normal variable behavior".
Mon graphe (27 Juin): (MQ || Rogue Life) ; serial gint ; passe gint 3 ; Azur ; ...) || (shoutbox v5 ; v5)
Simnon Hors ligne Membre Points: 79 Défis: 0 Message

Citer : Posté le 27/10/2025 19:54 | #


oh ok thanks

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2025 | Il y a 89 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd