2010-09-17 17 views
0

Je construis un système de visualisation de données qui visualise plus de 100 000 points de données (visites sur un site Web) sur une période donnée. La période (disons 1 semaine) est ensuite convertie en temps de simulation (1 semaine = 2 minutes en simulation), et une tâche est exécutée sur chaque élément de données au moment précis où il se produit en temps de simulation (le temps de chaque visite eu lieu pendant la semaine en temps réel). Avec moi? = pComment puis-je définir des dizaines de milliers de tâches pour chaque déclencheur à une heure définie différente?

Dans d'autres langages de programmation (par exemple, Java), je définirais simplement un temporisateur pour chaque point de données. Après chaque minuterie est terminée, il déclenche un rappel qui me permet d'afficher ce point de données dans mon application. Je suis nouveau en C++ et malheureusement, il semble que les minuteurs avec des rappels ne sont pas intégrés. Une autre méthode que j'aurais utilisée dans ActionScript, par exemple, serait d'utiliser des événements personnalisés qui sont déclenchés après une période de temps spécifique. Mais encore une fois, je ne pense pas que C++ supporte les événements personnalisés.

En un mot; disons que j'ai 1000 données qui couvrent une période de 60 secondes. Chaque élément de données a son propre temps par rapport à cette période de 60 secondes. Par exemple, il faut déclencher quelque chose à 1 seconde, un autre à 5 secondes, etc.

Est-ce que je vais dans ce sens, ou y a-t-il un moyen beaucoup plus facile de le faire?

Ps. J'utilise Mac OS X, pas Windows

Répondre

1

Réalisez vous-même un mécanisme de "minuterie", c'est le meilleur, le plus rapide et le plus flexible.

-> faire une série d'événements (liés à chaque événement objet arrive) (std :: vecteur C++/STL) -> trier le tableau à l'heure (std :: sort en C++/STL) - > alors faites une boucle sur le tableau et déclenchez l'action/la méthode de l'objet à l'intérieur d'une plage.

En gros qui donne en C++:

// action upon data + data itself 
class Object{ 
public: 
    Object(Data d) : data(d) { 

    void Action(){display(data)}; 

    Data data; 
}; 

// event time + object upon event acts 
class Event{ 
public: 
    Event(double t, Object o) time (t), object(o) {}; 

    // useful for std::sort 
    bool operator<(Event e) { return time < e.time; } 


    double time; 
    Object object; 


} 
//init 
std::vector<Event> myEvents; 

myEvents.push_back(Event(1.0, Object(data0))); 
//... 
myEvents.push_back(Event(54.0, Object(data10000))); 

// could be removed is push_back() is guaranteed to be in the correct order 
std::sort(myEvents.begin(), myEvents.end()); 

// the way you handle time... period is for some fuzziness/animation ? 
const double period = 0.5; 
const double endTime = 60; 
std::vector<Event>::iterator itLastFirstEvent = myEvents.begin(); 
for (double currtime = 0.0; currtime < endTime; currtime+=0.1) 
{ 
    for (std::vector<Event>::iterator itEvent = itLastFirstEvent ; itEvent != myEvents.end();++itEvent) 
    { 
    if (currtime - period < itEvent.time) 
     itLastFirstEvent = itEvent; // so that next loop start is optimised 
    else if (itEvent.time < currtime + period) 
     itEvent->actiontick(); // action speaks louder than words 
    else 
     break; // as it's sorted, won't be any more tick this loop 
    } 
} 

ps: A propos des événements personnalisés, vous pouvez lire/recherche sur les délégués en C++ et la fonction/pointeurs de méthode.

+0

Merci Tuan! Le code a du sens et est très simple, dans le bon sens. C'est une extension parfaite du code que j'écris actuellement, donc je vais voir comment ça se passe. – robhawkes

0

Si vous utilisez le langage C++ natif, vous devez consulter la section Minuteurs de l'API Windows sur le site Web MSDN. Ils devraient vous dire exactement ce que vous devez savoir.

+0

Merci. J'utilise OS X pour développer. Cela serait-il toujours pertinent? – robhawkes

+0

Oh. Non. Cependant, vous pourriez vous pencher sur les minuteurs POSIX - ils devraient fournir la même fonctionnalité, donner ou prendre. Mais je ne les ai jamais utilisés et n'ai aucun lien pour vous. – Puppy

4

Je n'utiliserais pas de minuteries pour faire cela. On dirait que vous avez trop d'événements et qu'ils peuvent être trop proches les uns des autres. Les performances et la précision peuvent être mauvaises avec les minuteurs.

Normalement, une simulation est effectuée comme suit: Vous effectuez des boucles (ou des itérations) de façon similaire. Et à chaque boucle, vous ajoutez un montant mesuré (en temps réel) ou constant (en temps non réel) à votre temps de simulation. Ensuite, vous vérifiez manuellement tous vos événements et les exécutez s'ils le doivent. Dans votre cas, il serait utile de les trier pour le temps d'exécution afin que vous n'ayez pas à les parcourir toutes les itérations.

La mesure de Tme peut être effectuée avec la fonction gettimer() c pour une faible précision ou il existe de meilleures fonctions pour une plus grande précision, par ex. QueryPerformanceTimer() sur Windows - ne connais pas l'équivalent pour Mac.

+0

Au lieu d'une approche de temps de ticker qui semble générique pour les simulations, dans ce cas vous pouvez également calculer le retard jusqu'au premier événement et dormir jusque là en utilisant nanosleep. – stefaanv

+0

Ou dormir dans les intervalles de vos temps d'affichage comme le font les jeux. Cela aide à ne pas consommer tout le temps du processeur. –

+0

J'ai choisi Tuan la "réponse" à ma question, mais je suis entièrement d'accord avec toi que les timers ne sont pas le meilleur choix. Je découvre cela maintenant je dois utiliser l'enregistrement basé sur l'image. Le système de minuterie ne ralentit pas en fonction d'une baisse du framerate. Je vais le convertir en un système de chronométrage basé sur le cadre comme vous le suggérez, il semble que le seul moyen. – robhawkes