{"id":3816,"date":"2019-11-26T17:33:47","date_gmt":"2019-11-26T17:33:47","guid":{"rendered":"http:\/\/www.colorwave.it\/blog\/?p=3816"},"modified":"2019-11-26T17:33:47","modified_gmt":"2019-11-26T17:33:47","slug":"le-macro-di-gestione-dei-messaggi-fra-oggetti","status":"publish","type":"post","link":"https:\/\/www.colorwave.it\/blog\/widgets\/messages\/le-macro-di-gestione-dei-messaggi-fra-oggetti\/admin\/2019\/11\/","title":{"rendered":"Le macro di gestione dei messaggi fra oggetti"},"content":{"rendered":"<p><a href=\"https:\/\/www.colorwave.it\/blog\/framework\/clb_messenger-la-nuova-interfaccia-di-messaggistica-fra-oggetti\/admin\/2019\/11\/\" target=\"_blank\" rel=\"noopener noreferrer\">Nell&#8217;articolo precedente, relativo alla classe CLB_messenger,<\/a> si sono discusse le funzionalit\u00e0 di trasmissione\/ricezione dei messaggi fra oggetti costruiti con il framework di Colibr\u00ec. In particolare \u00e8 stata analizzata la classe di servizio\u00a0 <a href=\"https:\/\/www.colorwave.it\/blog\/framework\/clb_messenger-la-nuova-interfaccia-di-messaggistica-fra-oggetti\/admin\/2019\/11\/\"><em>test_request\u00a0<\/em><\/a> utilizzata per la formattazione e il <a href=\"https:\/\/it.wikipedia.org\/wiki\/Parsing\" target=\"_blank\" rel=\"noopener noreferrer\">parsing<\/a> dei comandi scambiati.<\/p>\n<p>In questo articolo presenteremo in modo sintetico le macro che semplificano e rendono pi\u00f9 leggibile la scrittura del codice, senza la necessit\u00e0 di usare le funzioni, a volte complesse, che abbiamo descritto\u00a0 nel precedente articolo.<\/p>\n<p>L&#8217;insieme delle macro qui descritte\u00a0 costituisce un sottoinsieme dei comandi che possono essere scritti nel linguaggio di Colibri. Le definizioni relative sono scritte in un insieme di file di inclusione, disponibili\u00a0 attraverso la linea<\/p>\n<pre class=\"height-set:true height:100 width:100 lang:default decode:true \">#include \"WIDGET_DEFINITION.h\"\r\n<\/pre>\n<h4><strong>Comandi, messaggi, parametri..\u00a0<\/strong><\/h4>\n<p>Le macro che verranno descritte, fanno parte del linguaggio di Colibri (<span style=\"color: #0000ff;\"><em>CLB_lang<\/em><\/span>, come definito di seguito) , e consistono in <i>metodi e funzioni<\/i>, nell&#8217;accezione di un linguaggio come c \/c++; Nel nostro caso, per comodit\u00e0 parleremo di <strong>comandi <\/strong>quando faremo riferimento alle macro di CLB_lang, parleremo di <strong>messaggi<\/strong> quando definiremo la frase che viene scambiata fra gli oggetti usando\u00a0 le macro relative di CLB_lang; ad esempio:<\/p>\n<pre class=\"lang:default decode:true\">#define __send_cmd_to_obj(receiver,...)  send_to_obj(receiver,__VA_ARGS__,_$end)\r\n<\/pre>\n<p><em><span style=\"color: #0000ff;\">__send_cmd_to_obj \u00e8\u00a0 un comando di CLB_lang<\/span><\/em> i cui parametri sono <em><span style=\"color: #0000ff;\">receiver<\/span> <\/em>ed una lista <em>variadic<\/em> di altri elementi.<\/p>\n<p>Quando usiamo il comando nel codice, probabilmente scriveremo un&#8217;istruzione di questo tipo:<\/p>\n<pre class=\"lang:default decode:true\">__send_cmd_to_obj(w_plot, _$get, _$selected, _$curve, curva);<\/pre>\n<p>il parametro <em><span style=\"color: #0000ff;\">w_plot, <\/span><\/em><span style=\"color: #808080;\">\u00e8 il destinatario del messaggio<\/span><\/p>\n<p>la sequenza di parametri <em><span style=\"color: #0000ff;\">_$get, _$selected, _$curve, curva\u00a0<\/span><\/em>costituisce il <strong>messaggio<\/strong> che sar\u00e0 ricevuto dalla funzione slot_messenger<\/p>\n<p><em><span style=\"color: #0000ff;\">$get, _$selected, _$curve <\/span><\/em><span style=\"color: #0000ff;\"><span style=\"color: #808080;\">\u00e8 la frase del messaggio<\/span><\/span><\/p>\n<p><em><span style=\"color: #0000ff;\">curva\u00a0<\/span><\/em>\u00e8 il puntatore ad un oggetto passato come allegato al messaggio;<\/p>\n<p>la frase che compone il messaggio \u00e8 in genere formato da stringhe nella forma <em>_$word <\/em>dove il suffisso mnemonico _$ serve ad indicare che \u00e8 una stringa appartenente a CLB_lang;\u00a0 tutti gli altri costituenti il messaggio sono parametri, come in questo esempio. Lo scopo \u00e8 quello di rendere evidente a chi legge il programma (anche chi lo scrive, magari dopo mesi, dovr\u00e0 rileggerlo..) la funzione svolta dal messaggio. ad esempio un comando come il seguente \u00e8 simile nella forma a quello sopra riportato, ma il significato \u00e8 evidentemente diverso.<\/p>\n<pre class=\"lang:default decode:true\">__send_cmd_to_obj(w_plot, _$get, _$selected, _$document, doc);<\/pre>\n<p>Cosa c&#8217;\u00e8 scritto nelle stringhe di tipo <span style=\"color: #0000ff;\">_$<\/span>word? un testo mnemonico che richiama la descrizione stessa: ad esempio, facendo riferimento agli elementi della frase appena descritta,<\/p>\n<pre class=\"lang:default decode:true\">#define _$get\u00a0 L\"get\"\r\n#define _$selected L\"selected\"\r\n#define _$document L\"document\"<\/pre>\n<p>Ma nella logica del programma<span style=\"color: #0000ff;\">$get<\/span> poteva contenere l&#8217;italiano\u00a0 &#8220;estrai&#8221;, ma non sarebbe cambiato nulla per il significato d&#8217;uso.<\/p>\n<!--nextpage-->\n<h4><strong>__send_cmd( cmd,&#8230;)<\/strong><\/h4>\n<p>E&#8217; usato per richiamare una funzione CLB_messenger::send(&#8230;.) con una facilitazione: la macro send_cmd\u00a0 inserisce automaticamente _$end a fine lista, come atteso\u00a0 dalla CLB_messenger::send(..).\u00a0 Per usare la send_cmd:<\/p>\n<p>il messaggio \u00e8 trasmesso a tutti gli oggetti connessi\u00a0 (vedi CLB_regs(..)) ed esistono due diverse modalit\u00e0 d&#8217;uso, a seconda che si mandi il messaggio da un oggetto dato il suo putatore obj, o da una funzione della classe<\/p>\n<ul>\n<li>per un oggetto obj:\u00a0 \u00a0<span style=\"color: #0000ff;\"> obj-&gt;<\/span>send_cmd(pars, ..) dove obj \u00e8 un puntatore ad una istanza CLB_messenger (ad esempio un qualunque WIDGET)<\/li>\n<li>per una chiamata da dentro una funzione della classe:<span style=\"color: #0000ff;\"> send_cmd(pars, ..)<\/span><\/li>\n<\/ul>\n<pre class=\"lang:default decode:true\">__send_cmd_to_obj(w_plot, _$get, _$selected, _$document, doc);\r\n...\r\nobj-&gt;__send_cmd_to_obj(w_plot, _$get, _$selected, _$document, doc);\r\n<\/pre>\n<p>_<strong>_send_cmd_to_obj(receiver,&#8230;) <\/strong><\/p>\n<p>E&#8217;\u00a0 usato per richiamare una funzione CLB_messenger::send_to_obj(&#8230;.)<br \/>\nla macro send_cmd(..) inserisce automaticamente _$end a fine lista, come richiesto dalla send(..)<br \/>\nanche in questo caso come per\u00a0 per usare la send_cmd:<br \/>\nper un oggetto obj:\u00a0 <span style=\"color: #0000ff;\">obj-&gt;<\/span>__send_cmd_to_obj(pars, ..)<br \/>\nper una chiamata da dentro una funzione della classe: <span style=\"color: #0000ff;\">__send_cmd_to_obj(pars, ..)<\/span><\/p>\n<p>Il primo parametro del comando \u00e8 l&#8217;oggetto CLB_messenger che deve ricevere il comando:<\/p>\n<pre class=\"lang:default decode:true\">\/** WIDGET *w_plot   \/\/ assegnato in precedenza..\r\n*\/\r\nCURVE curva;\r\n__send_cmd_to_obj(w_plot, _$get, _$selected, _$curve, &amp;curva);\r\n...\r\n<\/pre>\n<p>Le due macro permettono la spedizione di un comando da parte di una classe con interfaccia CLM_messenger verso altri oggetti con la stessa interfaccia. I comandi usano, per trasferire il comando un dei due metodi di CLB_messenger:<\/p>\n<pre class=\"lang:default decode:true \">bool CLB_messenger::send(__arg_value cmd, ...);\r\n\r\nbool CLB_messenger::send_to_obj(CLB_messenger *receiver, __arg_value pars, ...);<\/pre>\n<p>Comunque il messaggio, attraverso i due metodi, se il destinatario \u00e8 correttamente definito, arrivera alla funzione\u00a0 slot_messenger della classe derivata: la funzione, essendo virtuale, sar\u00e0 stata riscritta per ciascuna classe, e sar\u00e0 in grado, utilizzando altre macro di CLB_lang, di estrarre il messaggio ed effettuare le scelte conseguenti:<\/p>\n<pre class=\"lang:default decode:true\">\tbool Widget_plotter::slot_messenger(_received_data)\r\n\t{\r\n\t\t__getstr\r\n\t\t__is_request(_$get,_$selected, _$curve)\r\n\t\t{\r\n\t\t\t__pop_p(cv, CURVE);\r\n\t\t\t_$str-&gt;edit-&gt;get_selected_curve(cv);\r\n\t\t}\r\n\t\treturn true;\r\n\t}\r\n<\/pre>\n<p>L&#8217;esempio di codice\u00a0<a href=\"https:\/\/www.colorwave.it\/blog\/framework\/clb_messenger-la-nuova-interfaccia-di-messaggistica-fra-oggetti\/admin\/2019\/11\/\" target=\"_blank\" rel=\"noopener noreferrer\"> \u00e8 gi\u00e0 stato riportato in questo articolo<\/a>.\u00a0 Lo riprendiamo per spiegare nei particolari il metodo di costruzione delle funzioni slot_messenger.<\/p>\n<p>La funzione slot_messenger contiene nella dichiarazione dei parametri la macro _received_data;\u00a0 dovr\u00e0 sempre essere in questa forma, poich\u00e8 la macro con \u00e8 altro che un&#8217; istanza test_request\u00a0 (_requ_) usata all&#8217;interno delle macro di analisi del messaggio utilizzabili all&#8217;interno della funzione.<\/p>\n<pre class=\"lang:default decode:true\"> #define _received_data test_request &amp;_requ_<\/pre>\n<p>descriviamo ora le macro di analisi del messaggio usate, sapendo che contengono inplicitamente la istanza\u00a0 _requ_\u00a0 parametro della funzione slot_messenger.<\/p>\n<h4>_is_request(&#8230;)<\/h4>\n<pre class=\"lang:default decode:true\">#define __is_request(...) if (_requ_.is( __VA_ARGS__,0))<\/pre>\n<p>la macro , che ha come argomenti la frase del messaggio ( <span style=\"color: #ff0000;\"><em>__is_request(_$get,_$selected, _$curve)<\/em><\/span> ) utilizza la funzione\u00a0 test_request::is(..) per testare il significato del\u00a0 messaggio ricevuto; se il messaggio \u00e8 quello testato, allora il blocco di codice che segue viene eseguito;<\/p>\n<p>Nel blocco troviamo il comando CLB_lang\u00a0 <em><span style=\"color: #ff0000;\">__pop_p(cv, CURVE); <\/span><\/em><span style=\"color: #808080;\">che estrae dallo stack del messaggio il successivo parametro, che per la sintassi attesa deve essere un CURVE * (vedi poco sopra questo esempio..)<\/span><\/p>\n<h4>__pop_p(ptr,type)<\/h4>\n<pre class=\"lang:default decode:true \">#define __pop_p(ptr,type) type *ptr=(type *)_requ_.pop_param();<\/pre>\n<p>la macro costruisce un pointer ptr\u00a0 di tipo type (nel caso in esempio CURVE *cv ) richiamando al suo interno la\u00a0 <span style=\"color: #0000ff;\">test_request::<em>pop_param(); <\/em><span style=\"color: #808080;\">\u00a0\u00a0<\/span><\/span><span style=\"color: #0000ff;\"><em>(<span style=\"color: #808080;\">notare che l&#8217;istanza di questa classe usata \u00e8 proprio\u00a0 la\u00a0 _requ_ passata alla funzione con la macro _received_data..)<\/span><\/em><\/span><\/p>\n<p><span style=\"color: #0000ff;\"><span style=\"color: #808080;\">Ovviamente la sequenza di estrazione del parametro obbedisce all&#8217;ordine di trasmissione definito nel comando\u00a0 lanciato dal sender.\u00a0<\/span><\/span><\/p>\n<p>la macro\u00a0_is_request(&#8230;) verr\u00e0 usata tante volte quante sono le frasi di ricezione accettate dalla classe; le frasi non riconosciute corrisponderanno a messaggi non intercettati, e non avranno alcun effetto sulla classe; questo permette ad esempio che pi\u00f9 istanze CLB_messenger, connesse ad una classe mediante la funzione CLB_messenger::regs(..) intercetteranno solo i messaggi (le frasi)\u00a0 analizzati in slot_messenger, quindi classi diverse registrate possono intercettare messaggi diversi; notare che la stessa frase ovviamente potr\u00e0 essere intercettata da classi diverse, purch\u00e8\u00a0 registrate nel sender.<\/p>\n<p>per concludere questa esposizione, di seguito \u00e8 riportato un altro esempio di slot_messenger, relativo ad un&#8217;altra classe, la WIDGET_DOCUMENT, dove si potr\u00e0 osservare l&#8217;uso pi\u00f9 volte delle due macro __pop_p e __is_request per intercettare diversi tipi di messaggio e parametri mandati dall&#8217;oggetto chiamante (definito qui sender)<\/p>\n<pre class=\"lang:default decode:true \">\t\tbool WIDGET_DOCUMENT::slot_messenger(_received_data)\r\n\t\t{\r\n\t\t\t__getstr\r\n\r\n\t\t\t__is_request(_$attach, _$dock_navigator)\r\n\t\t\t{\r\n\t\t\t\tSETBIT(NAVIGATOR,true)\r\n\t\t\t}\r\n\r\n\t\t\t__is_request(_$display, _$area)\r\n\t\t\t{\r\n\t\t\t\t__pop_p(r, RectF);\r\n\t\t\t\t$obj-&gt;ZoomArea(r-&gt;X, r-&gt;Y, r-&gt;Width, r-&gt;Height); \r\n\t\t\t}\r\n\r\n\t\t\t__is_request(_$zoom, _$area)\r\n\t\t\t{\r\n\t\t\t\t__pop_p(sender, void)\r\n\t\t\t\tif (sender == this)\r\n\t\t\t\t\treturn false;\t\t\/\/ \u00e8 il chiamante ..\r\n\t\t\t\t__pop_p(org, PointF);\r\n\t\t\t\t__pop_p(scale, float);\r\n\r\n\t\t\t\tif (_MAPPER.Zoom(*scale) &amp;&amp; _MAPPER.SetOrig(*org))\r\n\t\t\t\t{\r\n\r\n\t\t\t\t\tPointF *orgig = _MAPPER.GetOrig();\r\n\r\n\t\t\t\t\tINVALIDATE_SV_AREA(CANVAS, 1)\r\n\t\t\t\t\tPAINT(CANVAS)\r\n\t\t\t\t\tPAINT(_$str-&gt;scr_vert)\r\n\t\t\t\t\tPAINT(_$str-&gt;scr_horz)\r\n\t\t\t\t\tPAINT(_$str-&gt;h_ruler);\r\n\t\t\t\t\tPAINT(_$str-&gt;v_ruler);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n<\/pre>\n<p><img decoding=\"async\" data-attachment-id=\"3285\" data-permalink=\"https:\/\/www.colorwave.it\/blog\/?attachment_id=3285\" data-orig-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2018\/03\/word-image-97.png?fit=24%2C24&amp;ssl=1\" data-orig-size=\"24,24\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"word-image\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2018\/03\/word-image-97.png?fit=24%2C24&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2018\/03\/word-image-97.png?fit=24%2C24&amp;ssl=1\" tabindex=\"0\" role=\"button\" class=\"alignleft size-full wp-image-3285\" src=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2018\/03\/word-image-97.png?resize=24%2C24&#038;ssl=1\" alt=\"\" width=\"24\" height=\"24\" data-recalc-dims=\"1\" \/><strong>Nota:<\/strong> il programmatore che progetter\u00e0 una classe derivata da CLB_messenger, potr\u00e0 comunque definire messaggi basati su keyword personali: ad esempio potr\u00e0 lanciare comandi che contengono la keyword _$myDefin (=L&#8221;my definition word&#8221;) . In questo caso si consiglia di utilizzare almento una lettera maiuscola ed evitare le definizioni tutte minuscolo, per evitare conflitti con eventuali keyword di CLB_lang (che sono tutte, appunto minuscolo).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nell&#8217;articolo precedente, relativo alla classe CLB_messenger, si sono discusse le funzionalit\u00e0 di trasmissione\/ricezione dei messaggi fra oggetti costruiti con il framework di Colibr\u00ec. In particolare \u00e8 stata analizzata la classe di servizio\u00a0 test_request\u00a0 utilizzata per la formattazione e il parsing dei comandi&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"aside","meta":{"_acf_changed":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false,"jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[114,112],"tags":[],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9rwsf-Zy","jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts\/3816"}],"collection":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/comments?post=3816"}],"version-history":[{"count":7,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts\/3816\/revisions"}],"predecessor-version":[{"id":3823,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts\/3816\/revisions\/3823"}],"wp:attachment":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/media?parent=3816"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/categories?post=3816"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/tags?post=3816"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}