Liguria Heritage Review

Crescere in Italia riesce a far diventare normali le situazioni più curiose, e in assoluto la più straordinaria è la trasparenza verso l’arte. Essi’, siamo circondati da un numero di bellezze, musei, monumenti e siti archeologici che sono la totale normalità per chi ci vive. Sono cresciuto in Ventimiglia e nonostante oggi si sia guadagnata un posto di sottoscala dell’economia del panorama intemelio, ti fa ben capire che non è sempre stato così. Una zona assai ricca di memoria, di passato e di persone che oggi giorno sono completamente trasparenti ai più, curiosi compresi.

Cosa ci vorrebbe?

Oggi con la rivoluzione mobile alle spalle, sarebbe così semplice poter usare i dispositivi mobili per sopperire alla secchezza dell’organizzazione turistica (stagionale, interessata e poco pubblicizzata), è così che mi sono ritrovato tra le mani l’applicazione Liguria Heritage. Mi e’ bastato cliccare su Download sul mio telefono Android per capire che le buone intenzioni dell’autore erano finite ben presto. Vi chiederete come mai una Review intera dedicata a questa applicazione? Vi invito a proseguire e trovare voi stessi la risposta.

Design Review, Hands on!

La prima impressione, leggendo la pagina del Google Play market e’ quella di un’applicazione non ancora fruibile per il pubblico: descrizione generica dell’applicazione, pochi screenshot di presentazione che introducono pagine non esplicative della funzionalità proposta. Nessun video di anteprima, e le sole anteprime visibili mostrano quello che e’ essere il contenuto totale dell’applicazione: Un’introduzione, una pagina di download e una pagina di “realtà aumentata”. Sara’ forse un prototipo sviluppato a tesi di laurea? Non proprio: sviluppata da Datasiel SPA, nota azienda genovese ex Telecom Italia e Regione Liguria, operante in supporto tecnico, assistenza e programmazione del servizio pubblico regionale ligure. Insomma, una bella responsabilita’.

screenshot-1

Decido comunque di non fermarmi all’apparenza e clicco su Install. 8.14 MB di Download, manco male per un’applicazione di realta’ aumentata. Normale? Non mi pongo il problema più di tanto ed apro l’applicazione. Il menu introduttivo in lingua italiana (nonostante il mio telefono bandisca lingua inglese di preferenza) mi fa capire per un buon minuto di caricamento che la velocita’ non mi accompagnera’ per il resto della navigazione. Aspetto… Ancora un po’… Ancor… Ok caricata.

Avete presente ritorno al futuro? La stessa sensazione di uscire dalla Delorian e trovarsi negli anni ’90? L’applicazione è proprio un tuffo nel passato: nessuno layout, solo un logo e delle immagini di nomi di paesi. Ma qualcuno gli ha fatto presente che esistono guide per lo sviluppo delle applicazioni mobile? E i margini dove sono? E il material design? Non esisteva ancora negli anni ’90, ma per grazia ricevuta oggi si.

screenshot-2

Effettivamente 8.14 MB di Download erano solo la punta dell’iceberg perché ovviamente dentro l’applicazione (non menzionato precedentemente nella schermata del Google Play) si devono scaricare le mappe dettagliate. Ok, proviamo a scaricare il contenuto aggiuntivo: l’applicazione si blocca con un avviso di download senza percentuale di progressione, e prende il suo tempo per scaricare il contenuto (10-20 minuti per paese). Nel frattempo si perde il controllo sull’applicazione, come se il multi-thread e sistema di activity su Android fosse un lontano ricordo. Se si prova ad uscire dall’applicazione, il download non si interrompe solamente ma si annulla. Non molto pratico se nel bel mezzo dei 20 minuti di download avete la sfortuna mia di ricevere una chiamata telefonica. Pronto? No no… non stavo rifacendo niente di importante, dimmi pure…

Conclusioni

Insomma avrete capito che il tentativo di salvaguardare il patrimonio culturale ligure non si trova in buonissime mani. Un principio molto conosciuto dell’economia online recita “if you are not paying for a product, you become a product“, ossia i prodotti gratuiti non sono poi cosi gratuiti come sembra, e bisogna fare attenzione a non diventare noi stessi i prodotti finali. In questo caso l’applicazione si è scaricabile gratuitamente (nelle condizioni sopra citate), ma ben lontana da essere gratuita.

Sviluppata con finanziamenti Regionali, Nazionali ed Europei, oserei dire che l’abbiamo pagata un po’ tutti, non solo in Liguria. I contributi per il progetto (piu’ ampio della suddetta applicazione) arrivano dall’asse 4 dei fondi FESR 2007-2013 e secondo la rendicontazione regionale è costato (in contributi versati a Datasiel SPA) quasi 600.000 euro tra il 2013 ad oggi. Si poteva forse fare qualcosa di più? Direi proprio di si. Cosa ne pensate?

 

Smart Pointers

If you know a bit of C++ coding, you are forcely aware of the pitfalls you may encur while using pointers. However such an abstract data type is mostly used via its smart versions. Smart pointers are abstractions that aids the developer to overcome issues of memory allocation, leak and loosen relationship between what the execution program has in memory and what the executed code it is capable of handling. This small post is aimed to list and summarize the different smart pointers that can be used in C++ and give a little of background on how to use them and why. The examples are taken from the web.

std::auto_ptr

Description: it is part of the C++ Standard Library, it stores a pointer to single allocated objects. It means that whenever the pointer is referenced by a second auto_ptr it loses the ownership: sauto_ptr have strict ownership, it means that only the last assigned scoped_ptr really contains the address of the object. Look at the example for clarifications. Strict ownership is useful while you want to ensure to really knows that the pointer you are handling is the only one that can destroy the object and it cannot be done by someone else.

Benefits: This pointer is useful whenever you need to allocate local variables that you never want to have accessible outside of the scope.

Example:

#include <iostream>
#include <memory>

int main(int argc, char **argv)
{
 int *i = new int;
 std::auto_ptr<int> first(i);
 std::auto_ptr<int> second;

 second = first;

 std::cout << first.get() << std::endl;  // NULL
 std::cout << second.get() << std::endl; // Good address

 return 0;
}

boost::scoped_ptr

Description: it is part of boost.org C++ Library. Peculiariy of scoped_ptr is that it guarantees the object to be deleted. You can delete it either via destructor or by calling reset function. Once the definition of the pointer exits the execution scope, the destructor is automatically called and it deallocate the memory taken by the scoped_ptr.

Benefits: scoped_ptr adds an extra guarantee that all dynamic allocate memory areas will be deallocated when the execution is out of scope, even if the destructor for the given type is never called (or forgotten). Like the auto_ptr it does not have extra attributed definite with it, therefore it has no memory overhead (i.e. no extra storage required compared to a classic pointer).

Example:

#include <boost/scoped_ptr.hpp>
#include <iostream>

struct Shoe { ~Shoe() { std::cout << "Buckle my shoe\n"; } };

class MyClass {
 boost::scoped_ptr<int> ptr;
 public:
 MyClass() : ptr(new int) { *ptr = 0; }
 int add_one() { return ++*ptr; }
};

int main()
{
 boost::scoped_ptr<Shoe> x(new Shoe);
 MyClass my_instance;
 std::cout << my_instance.add_one() << '\n';
 std::cout << my_instance.add_one() << '\n';
}

boost::shared_ptr

Description: The shared_ptr is an enhanced version of scoped_ptr. It guarantees that the memory allocated will be finally deleted after the last instance of shared_ptr to that memory index is reset or destroyed. It is part of the boost.org C++ Library and it is using reference counting to detect when the destructor needs to be called (also called shared ownership principle).

Benefits: It takes care of deallocating the memory when the very last reference to that pointer is used. It could be very helpful in distributed environments since it can be used to reference the same object concurrently by different Thread “safely”.

Example:

shared_ptr<A> a(new A);
shared_ptr<A> b(a);

// Thread 1     // Thread 2
 a.reset();      b.reset();

boost::weak_ptr

Description: It is a smart pointer that holds a non-owning reference to an object that is already maanged by a shared_ptr. Since its relationship is “weak”, it does not increase the reference counter of shared_ptr. It is again part of the boost.org C++ Library.

Benefits: It is useful whenever you do not need to add a new reference that change the last ownership of the pointer. It can also be used to solve tricky issues with cyclic references.

Example:

std::shared_ptr<int> p1(new int(5));
std::weak_ptr<int> wp1 = p1; //p1 owns the memory.

boost::intrusive_ptr

Description: it is a smart pointer that enables embedded reference count. It means you can redefine functions that are adding references and releasing them. They have really specific uses, therefore it is generally adsivsable to use shared_ptr pointers.

Benefits: Gives you more control on the refering system of smart pointer whereas in the meanwhile does not had any overhead in memory to the pointer itself.

Example:

#include <boost/intrusive_ptr.hpp>
#include <boost/atomic.hpp>

class X {
public:
 typedef boost::intrusive_ptr<X> pointer;
 X() : refcount_(0) {}

private:
 mutable boost::atomic<int> refcount_;
 friend void intrusive_ptr_add_ref(const X * x)
 {
 x->refcount_.fetch_add(1, boost::memory_order_relaxed);
 }
 friend void intrusive_ptr_release(const X * x)
 {
 if (x->refcount_.fetch_sub(1, boost::memory_order_release) == 1) {
 boost::atomic_thread_fence(boost::memory_order_acquire);
 delete x;
 }
 }
};

std::unique_ptr

Description: This last smart pointer is the most restrictive smart pointer: not only it handles the ownership of the allocated memory but it does not allow any other smart pointer to reference to the same address. as scoped_ptr it destroys the object when out of scope. It replaces the old auto_ptr in std library.

Benefits: it avoids uncertain ownership among scoped_ptr pointers.

Example:

void foo()
{
 std::unique_ptr<int> p(new int);
 //do some stuff that might throw
}