Класс C++ Timer, также используется в QNX с импульсным сообщением

Я написал класс таймера для своего проекта. Я использовал для этого стандартные вызовы функций C++.

Я хочу создать таймер (запустить, остановить, приостановить, продолжить, сбросить), а также передать ему новые тайминги.

Если таймер срабатывает до того, как я его остановлю, я хочу получить импульсное сообщение qnx на заданном канале.

Это заголовок:

#ifndef TIMER_H_
#define TIMER_H_

#include <time.h>
#include <sys/neutrino.h>
#include "HWaccess.h"
#include "address.h"

#define MILLISECONDS_NANOSECONDS_CONV   1000000
#define SECONDS_MILLISECONDS_CONV       1000

class Timer {
public:
    /**
     * Constructor creates a new timer, attaches to the given
     * channel.
     * Does not start timer!
     *
     * @param chid
     * @param seconds
     * @param milliseconds
     * @param msg
     */
    Timer(int chid, int sec, int msec, int msg);

    /**
     * Deletes timer after detach from channel
     */
    virtual ~Timer();

    /**
     * Starts the timer
     */
    void start();

    /**
     * Stops timer and resets it to initial values
     */
    void stop();

    /**
     * Pauses the timer
     */
    void pause();

    /**
     * Continues the timer
     */
    void cont();

    /**
     * Resets the timer to initial values
     */
    void reset();

    /**
     * Changes timer values to new given values and
     * resets it
     * Does not start the timer!
     *
     * @param seconds
     * @param milliseconds
     */
    void changeTime(int sec, int msec);

private:
    /**
     * Timer ID
     */
    timer_t timerid;

    /**
     * Timerstruct for running timer
     */
    struct itimerspec timer;

    /**
     * Timerstruct for backing up the running timer
     */
    struct itimerspec backupTimer;

    /**
     * timer value: seconds
     */
    int seconds;

    /**
     * timer value: milliseconds
     */
    int miliSeconds;

    /**
     * Connection ID for timeout pulse
     */
    int coid;

    /**
     * Event structure for timer if it fires
     */
    struct sigevent event;
};

#endif /* TIMER_H_ */

... и реализация:

#include "Timer.h"

Timer::Timer(int chid, int sec, int msec, int msg) {
    if ((coid = ConnectAttach(0, 0, chid, _NTO_SIDE_CHANNEL, 0)) == -1) {
        printf("Timer: Error in ConnectAttach\n");
    }

    SIGEV_PULSE_INIT(&event, coid, SIGEV_PULSE_PRIO_INHERIT, PULSE_FROM_TIMER, msg/*Timer abgelaufen*/);

    if (timer_create(CLOCK_REALTIME, &event, &timerid) == -1) {
        printf("Timer: Error in timer_create()\n");
    }

    seconds = sec;
    miliSeconds = msec;

    reset();
}

Timer::~Timer() {
    if (ConnectDetach(coid) == -1) {
        printf("Timer: Error in ConnectDetach\n");
    }

    if (timer_delete(timerid) == -1) {
        printf("Timer: Error in timer_delete()\n");
    }
}

void Timer::start() {
    if(timer_settime(timerid, 0, &timer, NULL) == -1){
        printf("Timer: Error in timer_settime()\n");
    }
}

void Timer::stop() {
    // stop timer
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_nsec = 0;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_nsec = 0;
    if(timer_settime(timerid, 0, &timer, NULL) == -1){
        printf("Timer: Error in timer_settime()\n");
    }

    // reset it
    reset();
}

void Timer::pause() {
    timer.it_value.tv_sec = 0;
    timer.it_value.tv_nsec = 0;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_nsec = 0;

    // backup running timer values
    if(timer_gettime(timerid, &backupTimer) == -1){
        printf("Timer: Error in timer_gettime()\n");
    }
    // disarm 
    if(timer_settime(timerid, 0, &timer, NULL) == -1){
        printf("Timer: Error in timer_settime()\n");
    }
}

void Timer::cont() {
    // recover old values
    timer = backupTimer;
    // Arm timer
    if(timer_settime(timerid, 0, &timer, NULL) == -1) {
        printf("Timer: Error in timer_settime()\n");
    }
}

void Timer::reset(){
    timer.it_value.tv_sec = seconds;
    timer.it_value.tv_nsec = miliSeconds * MILLISECONDS_NANOSECONDS_CONV;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_nsec = 0;
}

void Timer::changeTime(int sec, int msec){
    seconds = sec;
    miliSeconds = msec;
    reset();
}

1) Могу ли я установить значения структуры таймера на ноль (чтобы остановить таймер) и сделать резервную копию значений в другой обратной структуре так, как я это делаю? Или рабочий таймер уменьшается в структуре таймера?

2) Могу ли я легко восстановить старые значения таймера с помощью простого timer = backupTimer?

3) И, наконец, если я создаю и запускаю таймер в функции, то примерно так:

void coolClass::interestingFunction() {
    //do other time consuming stuff here...
    Timer timer(chid, 10, 0);
    timer.start();
}

... затем таймер создается в стеке, и когда я выхожу из этой функции (и ее переменных и т. д.), они становятся недействительными. Будет ли таймер по-прежнему отсчитывать мой пульс? Или мне придется использовать классификатор в моем заголовочном файле для этого таймера?


person user1276012    schedule 04.12.2012    source источник
comment
Я отредактировал ваш вопрос. Нет такого языка, как C/C++, и точно нет классов в C. Это вопрос по C++.   -  person netcoder    schedule 04.12.2012
comment
хорошо, но вызовы таймера также используются в c .... это то, что я имел в виду :) спасибо   -  person user1276012    schedule 04.12.2012
comment
По определению C++ имеет доступ ко всему, что есть у C. Поэтому достаточно сказать, что просто C++.   -  person Agent_L    schedule 04.12.2012


Ответы (1)


Хорошо, я исправил все свои проблемы;> если кому-то интересно, вот модифицированный код:

#include "Timer.h"

Timer::Timer(int chid, int sec, int msec, int msg) {
    if ((coid = ConnectAttach(0, 0, chid, _NTO_SIDE_CHANNEL, 0)) == -1) {
        printf("Timer: Error in ConnectAttach\n");
    }

    SIGEV_PULSE_INIT(&event, coid, SIGEV_PULSE_PRIO_INHERIT, PULSE_FROM_TIMER, msg/*Timer abgelaufen*/);

    if (timer_create(CLOCK_REALTIME, &event, &timerid) == -1) {
        printf("Timer: Error in timer_create()\n");
    }

    seconds = sec;
    miliSeconds = msec;

    reset();
}

Timer::~Timer() {
    if (ConnectDetach(coid) == -1) {
        printf("Timer: Error in ConnectDetach\n");
    }

    if (timer_delete(timerid) == -1) {
        printf("Timer: Error in timer_delete()\n");
    }
}

void Timer::start() {
    //TODO running flag, wg doppelt pause / continue
    if(timer_settime(timerid, 0, &timer, NULL) == -1){
        printf("Timer: Error in timer_settime()\n");
    }
}

void Timer::stop() {
    // Stoppe den Timer
    if(timer_settime(timerid, 0, NULL, NULL) == -1){
        printf("Timer: Error in timer_settime()\n");
    }

    // Zuruecksetzen
    reset();
}

void Timer::pause() {
    // disarm (da erster Wert NULL)
    if(timer_settime(timerid, 0, NULL, &backupTimer) == -1){
        printf("Timer: Error in timer_settime()\n");
    }
}

void Timer::cont() {
    // Arm, da Werte im struct wieder != 0
    if(timer_settime(timerid, 0, &backupTimer, NULL) == -1) {
        printf("Timer: Error in timer_settime()\n");
    }
}

void Timer::reset(){
    timer.it_value.tv_sec = seconds;
    timer.it_value.tv_nsec = miliSeconds * MILLISECONDS_NANOSECONDS_CONV;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_nsec = 0;
}

void Timer::changeTime(int sec, int msec){
    seconds = sec;
    miliSeconds = msec;
    reset();
}
person user1276012    schedule 05.12.2012