RadioSvegliaGBE
StopWatch.h
Go to the documentation of this file.
1 #pragma once
2 
3 // Macro per sovvertire alla presenza dell'enumerazione 'WorkingState' nella classe CORE "StopWatchData", alla quale l'utente non
4 // deve avere accesso
5 /*
6 L'utente deve poter utilizzare l'enumerazione degli stati 'WorkingState' come se fosse definita all'interno del WRAPPER "StopWatch".
7 Questo è più complicato dato dal fatto che l'enumerazione, per la logica sulla quale si basa il progetto, si trova nel CORE "StopWatchData"
8 [classe] alla quale l'utente non ha accesso.
9 Per "risolvere" questo inconvenite risulta "comodo" "ingannare l'utente" "facendoli sembrare" che l'enumerazione si trovi nel WRAPPER "StopWatch".
10 Altri metodi potrebbero prevedere la riformulazione totale della logica base sulla quale si basa il progetto.
11 In questo caso, però, avendo sia CORE e corrispondente WRAPPER, risulta più logico definire tutte le eventuali enumerazioni nel CORE.
12 Il WRAPPER fungerà solamente da TRAMITE e INTERPRETE tra utente e codice.
13 */
15 #define StopWatch__WorkingState StopWatchData::WorkingState
16 
34 /*
35 Relazioni tra WRAPPER e CORE:
36 l'utente deve essere a conoscenza solamente del WRAPPER costruito "attorno" al CORE.
37 L'invalidatore del CORE, nominato 'CoreInvalidator' serve solamente per regolare l'invalidatore del WRAPPER.
38 L'utente deve avere in ritorno e occuparsi solamente dell'invalidatore del WRAPPER.
39 */
40 
41 #pragma region INCLUSIONS
42 // Classe per la gestione dell'oggetto CRONOMETRO
43 /*
44 Classe di autori 'Grandieri Andrea', 'Barsotti Mirko', 'Erba Lorenzo' rappresentante l'oggetto CRONOMETRO e tutti gli attributi
45 e i metodi associati.
46 */
47 #include "StopWatchData.h"
48 #pragma endregion INCLUSIONS
49 
50 // Namespace di protezione dalle inclusioni multiple con nominazione uguale
51 /*
52 I valori constexpr, come spiegato appena sopra, equivalgono alla direttiva '#define'. Questo può creare problemi nel momento in cui un singolo file viene incluso
53 in una gerarchia di molti più file, dove si potrebbe riscontrare la presenza di constexpr appartenenti a file diversi ma con gli stessi nomi! Questa ripetitività dei nomi deriva
54 dagli standard di nominazione. Per evitare, quindi, conflitti di multipla definizione, andremo ad utilizzare un 'namespace', che, come dice il nome, fornisce uno SPAZIO per i NOMI del nostro
55 file in cui il 'namespace' è stato dichiarato ed implementato.
56 Mantieniamo comunque la specificazione 'static', per evitare errori di linker in caso di inclusioni multiple di questa unità di traslazione [file].
57 */
66 namespace StopWatch__file
67 {
68  // Valore costante che viene ritornato in caso di invalidità riscontrata nell'oggetto durante il dereferenziamento
69  // per la chiamata dei metodi.
70  // Il valore invalido utilizzato è un valore impossibile, cioè che non potrebbe essere mai restituito naturalmente.
72  static constexpr int _invalidvalue = -1;
73 }
74 
82 class StopWatch
83 {
84  /*Blocco trivial*/
85  /*
86  Stiamo trattando una classe interamente statica. Per la definizione di staticit�, descritta successivamente, questa classe funger� solamente
87  da "contenitore astratto" per organizzare pi� logicamente i dati. In verit�, tutto risieder� principalmente nel Data Segment, quindi sar�
88  globale, ma statico (anche questo descritto successivamente).
89  Questa staticit� implica la NON necessit� di creare istanze di questa classe, che risulterebbero totalmente inutili dato che tutti gli attributi
90  e i metodi esistono nell'ambito globale.
91  Per evitare, quindi, inutili istanziamenti, verranno bloccati il costruttore trivial (di default generato dal compilatore) e il distruttore, reso
92  inutile dalla non-istanziabilit� della classe stessa.
93  */
94 private:
95  // Blocco attraverso privatizzazione del costruttore trivial
102  StopWatch() = default;
103  // Blocco attraverso privatizzazione del distruttore trivial
110  ~StopWatch() = default;
111 
112  /*Attributi*/
113 private:
114  // Puntatore all'oggetto cronometro di classe "StopWatchData"
115  /*
116  Questa variabile conterrà l'istanza dell'oggetto di classe "StopWatchData" creata durante l'operazione di inizializzazione.
117  Questo oggetto rappresenta un vero e proprio cronometro. Fornisce tutti i metodi necessari alla sua gestione e ritorna il valore della
118  'constexpr' '_invalidvalue' per comunicare genericamente errori.
119  L'oggetto sar� sottoposto ad allocazione dinamica [heap]. Questo per evitare problemi con la deallocazione mirata all'ambito
120  caratteristica della memoria statica [stack]. Una allocazione statica [stack] provocherebbe l'allocazione e successiva deallocazione
121  immediata dell'oggetto esistendo solamente nell'ambito di inizializzazione.
122  Essendo statica, la variabile (puntatore) verr� allocata nel 'Data Segment' (segmento dei dati) ed "esister�" fino a termine
123  del programma stesso. Quindi si tratta di una variabile globale, ma statica. Questo la rende esistente solamente in questa unit�
124  di traslazione (file).
125  */
128 
129  /*Init*/
130 public:
131  // Inizializza il cronometro con il rispettivo costruttore.
132  /*
133  Questo metodo, fondamentale, "dà vita" al cronometro. Effettua una allocazione (dinamica [heap]) attraverso il rispettivo costruttore della classe
134  "StopWatchData".
135  Analizzando questo costruttore, notiamo come non accetti nessun parametro. Possiamo quindi trattarlo come un costruttore di default.
136  Il metodo ritorna un valore booleano, utilizzato per comunicare eventuali errori durante l'allocazione.
137  Inoltre, prima dell'effettiva allocazione, esegue una deallocazione [delete] se necessaria.
138  Anche qua ritroviamo la specificazione di staticità. Nel caso di applicazione ad un metodo, dissocia il metodo stesso da qualsiasi possibile istanza
139  della classe. Quindi, il metodo sarà richiamabile come se fosse globale (e statico). Sarà solamente necessario anteporre il nome della classe di
140  appartenenza. Ricordiamo anche che i metodi statici possono operare solo su variabili statiche, che anch'esse, essendo globali (e statiche) sono
141  totalmente dissociate da possibili istanze della classe stessa (da oggetti).
142  */
157  static bool Init();
158 
159  /*Service Management*/
160 public:
161  // Avvia il cronometro
162  /*
163  Questo metodo semplicemente avvia il cronometro.
164  Per fare ciò, effettua una chiamata ad uno specifico metodo di avvio implementato nella classe "StopWatchData".
165  Restitusce un valore booleano per comunicare il corretto avvio 'true' oppure no 'false'
166  Permette quindi, la gestione ad alto livello lasciata all'utente.
167  Anche qua, per via della staticità, viene applicata la gestione analizzata prima.
168  */
181  static bool Start();
182 
183  // Arresta il cronometro
184  /*
185  Questo metodo semplicemente arresta il cronometro.
186  Per fare ciò, effettua una chiamata ad uno specifico metodo di arresto implementato nella classe "StopWatchData"
187  Restituisce un valore booleano per comunicare il corretto arresto 'true' oppure no 'false'
188  Permette quindi, la gestione ad alto livello lasciata all'utente.
189  Anche qua, per via della staticità, viene applicata la gestione analizzata prima.
190  */
203  static bool Stop();
204 
205  // Resetta il cronometro
206  // Procede all'operazione attraverso una reallocazione
207  /*
208  Questo metodo resetta il cronometro, riportandolo allo stato "di zero".
209  Per fare ciò, NON utilizza metodi presenti nella classe "StopWatchData". In effetti, controllando la documentazione
210  della classe "StopWatchData" si può notare come il 'reset' sia implementato come una semplice creazione di una
211  nuova istanza cronometro.
212  Quindi, per fare ciò, effettueremo una nuova allocazione. Il metodo 'Init' della classe "StopWatch" gestirà la presenza
213  al massimo di un cronometro, deallocando il precedente.
214  Il metodo restituisce un valore booleano per comunicare il corretto reset 'true' oppure no 'false'
215  Permette quindi, la gestione ad alto livello lasciata all'utente.
216  Anche qua, per via della staticità, viene applicata la gestione analizzata prima.
217  */
231  static bool Reset();
232 
233  /*LowLevel getters*/
234  /*
235  I seguenti metodi LowLevel sono supposti soprattutto per uso a scopo di debug e management manuale.
236  Forniscono un punto di accesso costante a VALORE MODIFICABILE (quindi dereferenziabile ma non reindirizzabile).
237  In release mode, potrebbe risultare efficace cambiare il contrassegno da 'public' a 'private'.
238  Anche qua, per via della staticità, viene applicata la gestione analizzata prima.
239  */
240 public:
241  // Ritorna un puntatore all'oggetto di classe "StopWatchData"
253  static StopWatchData* const get_StopWatch();
254 
255  /*LowLevel reallocator*/
256  // In questo caso, non è necessaria l'implementazione essendo equivalente al metodo 'Init'
257 
258  /*Metodi*/
259 public:
260  // Restituisce il valore del cronometro
261  /*
262  Questo metodo rappresenta il principale scopo della classe: ottenere il valore del cronometro.
263  Il tipo restituito è 'String' [stringa]. Il formato dei valori è --> 'hh:mm:ss'
264  Il metodo restituisce il valore della 'constexpr' '_invalidvalue' per comunicare eventuali generici errori.
265  Permette quindi, la gestione ad alto livello lasciata all'utente.
266  Anche qua, per via della staticità, viene applicata la gestione analizzata prima.
267  */
280  static String get_CurrentFormattedStopWatch();
281 
282  // Restituisce lo stato attuale del cronometro
283  /*
284  Questo metodo permette di ottenere come valore di ritorno lo stato attuale del cronometro.
285  Sono possibili 2 stati:
286  'WorkingState::OFFLINE' --> il cronometro non è in funzione
287  'WorkingState::ONLINE' --> il cronometro è in funzione
288 
289  Questo metodo, appartenendo al WRAPPER, deve anche gestire eventuali stati INVALIDI, causati da un dereferenziamento impossibile
290  a causa di una mancata allocazione iniziale.
291  Per tale motivo, questo metodo potrà ritornare un altro stato, creato appositamente per queste occasioni nella enum class del CORE.
292  Lo stato --> 'WorkingState::INVALID'.
293  Molto importante è anche precisare l'impossibilità per il metodo di ritornare una 'reference [&]'. Questo, perchè, lo stato 'WorkingState::INVALID' viene ritornato
294  direttamente come un valore numerico, un RVALUE!! Questo è causato dall'impossibilità di chiamare il corrispettivo metodo 'get_WorkingState' della classe "StopWatchData".
295  */
308 
309  // Controlla la disponibilità di una connessione Internet. In caso negativo, effettua il reset di sicurezza del valore del cronometro
318  static void Trigger_to_Check();
319 
320  /*Invalidator*/
321  /*
322  L'invalidatore consiste in quel valore che viene ritornato ogni qualvolta una chiamata da parte dell'utente ai metodi non produce il risultato atteso.
323  E' importante specificare che, l'invalidatore, pur essendo costante, non deve essere dichiarato come 'constexpr' perchè NON deve seguire le regole di
324  comportamento della direttiva '#define'. Il compilatore NON deve sostituire il nome dell'attributo con un valore numerico costante --> i.e. RVALUE!!
325  L'invalidatore deve essere un vero e proprio attributo della classe, che però non deve mai appartenere ad uno specifico oggetto. Per questo deve essere sempre
326  specificato come statico. Ovviamente, avrà una locazione nel Data Segment, sarà quindi globale ma statico (valido sono in questa unità di traslazione (file)) e utilizzabile
327  solamente nell'ambito della classe di dichiarazione.
328  */
329  /*Attributo*/
330 private:
331  // Valore costante che viene ritornato in caso di invalidità riscontrata nell'oggetto durante il dereferenziamento
332  // per la chiamata dei metodi.
333  // Il valore invalido utilizzato è un valore impossibile, cioè che non potrebbe essere mai restituito naturalmente.
335  static const int m_Invalidator;
336 
337  /*getter*/
338 public:
339  // Metodo per il ritorno del valore dell'Invalidatore. Verrà ritornata una referenza [reference --> '&'] costante, in modo tale da ottimizzare il processo e,
340  // allo stesso tempo evitare modifiche inappropriate.
341  /*
342  Un'altra particolarità di questo metodo sta nel fatto che è definita come 'inline'. Questa keyword comunica al compilatore, ovunque trovi una chiamata
343  a questo metodo, di NON effettuare una vera e propria chiamata, ma di sostituire la porzione del codice per la chiamata con il BODY del metodo (la implementazione stessa).
344  Questa tecnica risulta molto utile per funzioni che effettuano pochissime operazioni e sono sottoposte a frequenti chiamate.
345  Anche qua, per via della staticità, viene applicata la gestione analizzata prima.
346  */
357  static inline const int& get_Invalidator();
358 };
359 
360 // Dichiarazione delle variabili GLOBALI STATICHE
361 // Risiederanno nel Data Segment
362 /*
363 Essendo statiche in classe, tutti gli attributi non sono altro che variabili GLOBALI STATICHE.
364 Per questo è richiesta la dichiarazione globale. Non è necessario specificare 'static' essendo già stato specificato nella dichiarazione degli
365 attributi nella classe stessa.
366 */
371 
StopWatch::Stop
static bool Stop()
Arresta l'esecuzione del cronometro.
Definition: StopWatch.cpp:52
StopWatch::Reset
static bool Reset()
Resetta il cronometro, resettandone i valori e lo stato ai valori di default.
Definition: StopWatch.cpp:65
StopWatch::m_StopWatch
static StopWatchData * m_StopWatch
Definition: StopWatch.h:127
StopWatch::Start
static bool Start()
Avvia l'esecuzione del cronometro.
Definition: StopWatch.cpp:39
StopWatch
Classe per la gestione del cronometro integrato digitale.
Definition: StopWatch.h:82
StopWatch::Trigger_to_Check
static void Trigger_to_Check()
Controlla la presenza di una connessione Internet valida. In caso negativo, effettua il reset di sicu...
Definition: StopWatch.cpp:121
StopWatch::get_StopWatch
static StopWatchData *const get_StopWatch()
LowLevel getter per l'attributo m_StopWatch.
Definition: StopWatch.cpp:75
StopWatch::get_WorkingState
static const StopWatchData::WorkingState get_WorkingState()
Permette di ottenere il valore dello stato del cronometro.
Definition: StopWatch.cpp:106
StopWatchData
Classe di definizione dell'oggetto per la funzione 'cronometro'.
Definition: StopWatchData.h:73
StopWatch::~StopWatch
~StopWatch()=default
Distruttore della classe StopWatch.
StopWatchData::WorkingState
WorkingState
Enumerazione per la gestione dello stato del cronometro.
Definition: StopWatchData.h:91
StopWatch__file::_invalidvalue
static constexpr int _invalidvalue
Definition: StopWatch.h:72
StopWatch::get_CurrentFormattedStopWatch
static String get_CurrentFormattedStopWatch()
Permette di ottenere il valore del cronometro formattato nel seguente formato: 'hh:mm:ss'.
Definition: StopWatch.cpp:82
StopWatch::get_Invalidator
static const int & get_Invalidator()
Permette di ottenere l'invalidatore della classe.
Definition: StopWatch.cpp:132
StopWatchData.h
StopWatch::Init
static bool Init()
Metodo di inizializzazione dei componenti della classe.
Definition: StopWatch.cpp:15
StopWatch__file
Spazio dei nomi riferito al file Alarm.h.
StopWatch::m_Invalidator
static const int m_Invalidator
Definition: StopWatch.h:335
StopWatch::StopWatch
StopWatch()=default
Costruttore di default della classe StopWatch.