Adiós Embarcadero, adiós

No es muy conocido que yo he trabajado en la filial española de la empresa Embarcadero, dueña de Delphi y C++ Builder, dos productos que fueron lo más pero que ya no lo son, opinión personal, por supuesto.

Yo dejé la empresa para irme a trabajar a Holanda, y no me arrepiento. El mismo día en el que dije que me iba, nos comunicaron que Idera, una pequeña empresa de bases de datos, había comprado a Embarcadero. Tan solo hubo dos horas entre el momento en que oficialmente pedí la baja voluntaria y el que anunciaron la compra. Para nosotros fue como si un lenguado se hubiera comido una ballena, porque aparentemente Idera era una empresa chiquita comiéndose a una empresa mucho mayor, pero claro, detrás están los grupos de inversión que son los que realmente hacen estas operaciones.

Personalmente he vivido dos compras de este tipo trabajando en empresas grandes, y ninguna fue traumática en exceso para los empleados como yo. Me refiero a que, pese al cambio de jefes, a los currantes poco nos cambió la cosa si no es algún que otro cambio en las reglas de funcionamiento interno…

Pero aquí parece que la cosa se presenta mucho más diferente. Básicamente, parece ser que Idera está echando a la calle a todas las divisiones de Embarcadero en todo el mundo. Un recorte a lo Microsoft, pero mucho más drástico. Al menos es lo que se deja entrever en la entrada del amigo José León, jefazo de la filial española y que él mismo cuenta cómo llegó a serlo.

Para que os hagáis una idea, Embarcadero ha mantenido a lo largo de todo el mundo “pequeños” grupos de trabajo, encargados de distintas partes de sus productos. Sin ir más lejos, en la filial de Elche, una de las que cierran y en la que yo estuve trabajando, se hace parte del producto de Delphi, C++ Builder y DbPower Studio, que era donde yo estaba. Había más grupos, si no recuerdo mal, en Polonia, Rusia…

Parece ser que todos esos grupos están siendo cerrados a golpe de ERE. Lo que es triste, aunque también es algo que se veía venir dado el devenir de Embarcadero porque, por ejemplo, o abandoné C++ Builder asqueado de los bugs y problemas que presentaba, aparte de las restricciones en la activación del producto…

También parece ser que yo dejé de usarlo justo cuando empezó a desarrollarse en España, y por lo que he visto desde dentro, la calidad ha mejorado sensiblemente, pero parece ser que no justifica dos versiones por año que ponen el precio de la herramienta por encima de las posibilidades del usuario medio, máxime cuando en estos momentos Visual Sutdio + Xamarin son gratuitos para ese mismo tipo de usuario.

Tampoco es que Xamarin sea la panacea, las pocas veces que lo he usado he terminado hasta los cojones del producto por su baja calidad, pero es una alternativa al mismo nivel de sencillez que Delphi, así que no llueven buenos tiempos para estos productos, porque si cierran los centros de desarrollo… ¿quién va a continuar con las nuevas versiones?

¿Se van a hacer en Estados Unidos, a 100K/año el desarrollador cuando en España está a cuatro veces menos? ¿Van a contratar de nuevo a Helsberg? ¿Nos ha engañado José León y resulta que no es un súper-developer, sino que es el mayor genio que ha parido madre y va a seguir él solo con el producto? ¿Ha inventado alguien una IA programadora capaz de construir todo eso sin necesidad de personas?

No, lo que creo, tristemente, es que Delphi, C++Builder y quizás los productos de bases de datos se van al garete, sustituidos por los de Idera, que os aseguro no le llegan a la suela de los zapatos.

En fin, es lo que hay. El VHS le ganó al 2000 y al Beta, y no por ser mejor producto o tecnología.

RIP, Delphi.

RIP, C++ Builder.

Vuelta al redil y artículos publicados en otros lados

Muchos de vosotros habréis supuesto que he abandonado el blog y he dejado de escribir de forma definitiva. Si bien en apariencia así, es la realidad es otra, ya que lo que no he puesto aquí lo he hecho en los blogs de la MDSN. 

Eso no quiere decir que haya abandonado esto, sino que simplemente primero publiqué allí y me olvidé de hacerlo aquí, o más bien de poner aquí una entrada que redirigiera allí.

Esta entrada soluciona eso mismo, y recoge todo lo que he publicado hasta la fecha allí y en otro blog que recientemente he abierto y que en próximos días también copiaré dichas entradas aquí.

Respecto a ese otro blog, no pretende sustituirlo, sino más bien complementarlo ya que la idea es publicar la misma cosa en paralelo en ambos, para tener algo más de visibilidad.

Bueno, comentado esto, os pongo la lista de entradas y sus enlaces.

Windows Phone, Windows 8: Portable Library y subida a la tienda: desde cero

Esta es, desde luego, la mejor entrada de todas las que he publicado allí. Como reza el título, en ella explico la creación de una aplicación sencilla tanto para Windows 8 como para Windows Phone usando la portable library y cómo subirla a las dos tiendas. Pese al tiempo transcurrido, todo sigue siendo relevante ya que pese a la unificación de las dos tiendas, el proceso de subida continua siendo igual al descrito.

Este artículo tiene su historia, ya que en origen iba a ser publicado en la revista DotNetManía pero a causa del cierre de la misma lo reutilicé allí.

Workaround para Windows Phone ListBox y LongListSelector y ScrollIntoView en elementos de diferente tamaño

 Este es un truco para hacer que el ListBox de Windows Phone 7.x se comporte como debe cuando se añaden valores de diferente tamaño y se llama a ScrollIntoView() para que se seleccione uno de ellos. Es decir, tanto Windows Phone 7 como 8 tienen un bug que ninguna actualización (hasta donde yo sé) ha resuelto: a veces no se muestra el elemento completo. Este truco mejora, aunque no solventa del todo, el problema.

Windows Phone: Subiendo un fichero a un servidor WEB con credenciales básicas sin tener que reintentar

El componente WebRequest de Windows Phone primero intenta la operación sin credenciales y cuando falla, lo hace con ellas si se han indicado. Pero eso le sienta bastante mal a algunos servidores Web, así que con este truco hacemos que el componente lo haga con ellas desde el primer momento.

El interior de Windows

Esta es una de esas entradas típicas mías que resumen o cuenta cosas que posiblemente sólo interesen a mi y a algún que otro trasnochado. Aquí hablo de Windows 8 y cómo es su arquitectura real y no la que nos muestran esos gráficos tan bonitos que hace Microsoft.

Llamando al API de WinRT desde aplicaciones de escritorio normales en C#

En este artículo describo cómo llamar al API de las aplicaciones de la tienda de Windows (las aplicaciones antes conocidas como Metro y ahora Modern UI, vamos, la de los cuadraditos de Windows 8) desde una aplicación de escritorio. La cosa queda más clara si antes de leer esta entrada, se lee la anterior de la lista.

Llamando al API de WinRT desde aplicaciones de escritorio normales en C#

 

NOTA IMPORTANTE:

 

Esta entrada está obsoleta porque lo que describo más abajo no funciona tal y como está contado. Es un mea culpa en toda propiedad por no haber probado antes lo que escribía, pero es que la entrada original es bastante creíble.

Eso me llevó a crear un nuevo artículo, esta vez verificado, que se puede leer aquí:

 

Llamando al API de WinRT desde aplicaciones de escritorio normales en C#

 

******************************************************

El otro día twiteé un enlace que tenía apuntado por ahí y que no había leído hasta el momento del twitt, como me pasa con una docena más, que tengo en la lista de encontrar tiempo y tranquilidad para leerlos en detalle.

Y como creo que debería estar en castellano, os voy a contar de qué va la cosa.

Todos sabemos que ahora hay dos Windows 8. El tradicional de toda la vida y el RT. A ver, son el mismo, pero a la vez diferentes. El RT es la versión para tabletas, que en teoría permite desarrollar usando sólo un subconjunto de Win32 y de .NET, pese a que por debajo sigue estando el Windows de toda la vida.

La otra versión es la normal, la del escritorio pleno y funcional a la que estamos acostumbrados, que a su vez usa el API tradicional, ya sea el nativo Win32 o el de .NET.

Y si bien está prohibido usar el API completo en las aplicaciones RT, lo contrario no es así ya que en el escritorio tenemos plena libertad para utilizar cualquier cosa, incluyendo el API de Windows RT. Lo que ocurre es que el soporte directo para ello está ausente en las versiones de Visual Studio.

Pero se puede hacer editando el texto plano del fichero de nuestro proyecto: <proyecto>.csproj. Ahí dentro debemos añadir las líneas

<propertygroup>

<targetplatformversion>8.0</targetplatformversion>

</propertygroup>

Y a partir de ahí, una vez recargado el mismo, podremos usar el API de Windows RT con sólo añadir las referencias adecuadas según se vayan necesitando. El mayor problema es que tenemos que saber cuáles son y añadirlas a mano.

clip_image001

clip_image003

Workaround para Windows Phone ListBox/LongListSelector y ScrollIntoView() cuando los elementos tienen diferente tamaño

En Windows Phone 7.5 hay un bug bastante asqueroso que sólo se presenta cuando quieres mostrar un elemento en un ListBox o en un LongListSelector llamando a ScrollIntoView() y los elementos contenidos tienen diferentes tamaños. El bug también está presente en Windows Phone 8, pero sólo en el componente ListBox. LongListSelector está construido de otra forma y, según Microsoft, ya no presenta el problema.

Como es habitual en la empresa, y aparte de ser un problema conocido desde hace tiempo, no se va a solucionar. Personalmente podría entender que no se haga en las versiones actuales ya que requeriría que luego los fabricantes reconstruyeran sus propias plataformas, pero me resulta completamente inaceptable que siga estando en el nuevo Windows Phone 8, y encima conociéndolo de antemano.

En fin, es lo que hay, y encima tampoco existe ningún workaround oficialmente sancionado para resolver el problema. En otras palabras, si tienes un programa en el que te ocurre eso, básicamente te jodes y bailas.

Pero no, aquí está RFOG que te va a sacar las castañas del fuego. Como sabéis llevo unos meses currando en Yuilop para Windows Phone, y también debéis saber que me toca mucho las narices que te digan eso no se puede hacer y similares. Y por supuesto, a tu jefe tampoco le agrada mucho que le digas: es un bug y no tiene solución.

Para descargo propio he de deciros que la solución es un poco chorra y que sólo había que pensar un poco, pero tenéis que reconocerme que debo de darme algo de bombo y platillo.

***

Bueno, ahora la parte técnica.

En el ejemplo que anexo más abajo, cuando se pulsa el botón de Insert… se genera un elemento de tres posibles mediante Code Behind. Los tres tienen como elemento base un Grid, pero el interior es diferente y por tanto su altura. Dos de ellos contienen una imagen y el tercero, un texto.

En cada elemento creado, se llama a ScrollIntoView() sobre el citado, para que se visualice adecuadamente.

Conforme vamos creando elementos, llega un momento en el que uno de ellos se queda cortado a medias como en la captura:

clip_image001

El comportamiento adecuado debería ser que se mostrara completo, mostrando la parte inferior. Ese es el problema: cuando los elementos tienen diferente altura, termina ocurriendo esto mismo. Y según Microsoft, no se va a solucionar. Las apuestas suben cuando hay campos de edición y cambios de orientación: con total seguridad te quedará el elemento cortado.

El código que genera los elementos es:

        private void Button_Tap(object sender, GestureEventArgs e)
        {
            switch (s_rnd.Next(0,3))
            {
                case 0:
                    var itemText = new ListBoxItemText("Hola mundo");
                    ListBox.Items.Add(itemText); 
                    ListBox.ScrollIntoView(itemText);
                    break;
                case 1:
                    var itemImgBien = new ListBoxItemImage(StaticResources.ImageBien);
                    ListBox.Items.Add(itemImgBien);
                    ListBox.ScrollIntoView(itemImgBien);
                    break;
                case 2:
                    var itemImgMal = new ListBoxItemImage(StaticResources.ImageMal);
                    ListBox.Items.Add(itemImgMal);
                    ListBox.ScrollIntoView(itemImgMal);
                    break;
            }
        }

Fijaos en el detalle. Dependiendo de un número aleatorio creamos uno de tres. Eso debería funcionar bien, pero como podéis comprobar vosotros en vuestra casa, no lo hace en el momento en el que empiezan a aparecer elementos con el texto y con una de las dos imágenes.

***

Como ya os he dicho, la solución es bastante sencilla. Os pego el código:

        private void ButtonNoBug_Tap(object sender, GestureEventArgs e)
        {
            switch (s_rnd.Next(0, 3))
            {
                case 0:
                    var itemText = new ListBoxItemText("Hola mundo");
                    ListBox.Items.Add(itemText);
                    ForceScrollListBox();
                    break;
                case 1:
                    var itemImgBien = new ListBoxItemImage(StaticResources.ImageBien);
                    ListBox.Items.Add(itemImgBien);
                    ForceScrollListBox();
                    break;
                case 2:
                    var itemImgMal = new ListBoxItemImage(StaticResources.ImageMal);
                    ListBox.Items.Add(itemImgMal);
                    ForceScrollListBox();
                    break;
            }
        }

Y el truco del almendruco:

        private void ForceScrollListBox()
        {
            var fake = new Grid();
            ListBox.Items.Add(fake);
            ListBox.ScrollIntoView(fake);
        }

Sí, señores. El truco consiste en crear un nuevo elemento del mismo tipo base pero completamente vacío, añadirlo y llamar a ScrollIntoView() sobre él. El uso de memoria es mínimo porque el componente no debe ocupar muchos bytes ya que está vacío, y tampoco se visualiza, pero en general el sistema empuja hacia arriba al elemento que queremos mostrar.

No obstante, creo haber detectado que no siempre funciona, al menos en el emulador, pero de momento la gente de QA de Yuliop todavía no me ha protestado. [Aplausos de fondo].

En el ejemplo tenéis tres botones. En el primero hacemos inserciones con el bug, en el segundo sin él y con el tercero corregimos si tenemos un elemento a medio mostrar o nos vamos abajo del todo si estamos a medias.

Finalmente, el código fuente de todo esto está aquí:

https://github.com/rfog/InsertInListboxproblem_Solution

Sed buenos y hasta otra.

Repetid conmigo mil veces:

Los elementos del DataTemplate en un FrameworkElement con DataBinding deben ser propiedades.

 

Los elementos del DataTemplate en un FrameworkElement con DataBinding deben ser propiedades.

Los elementos del DataTemplate en un FrameworkElement con DataBinding deben ser propiedades.

Los elementos del DataTemplate en un FrameworkElement con DataBinding deben ser propiedades.

Los elementos del DataTemplate en un FrameworkElement con DataBinding deben ser propiedades.

O en otras palabra, cuando uses el modelo MVVM (al menos en Windows Phone) los elementos de binding en la plantilla de datos deben ser propiedades aunque sean del tipo genérico.
Es decir en
            <ListBox>
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin=»10″>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition />
                            </Grid.RowDefinitions>
                            <TextBlock Text=»{Binding Name}» Grid.Row=»0″ FontWeight=»Bold» FontSize=»20″/>
                            <TextBlock Text=»{Binding Surname}» Grid.Row=»1″ FontSize=»10″/>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
tanto Name como Number deben ser propiedades y públicas.
Me da igual si está documentado en algún lado o no, pero me ha costado sudores darme cuenta. El objeto que se va a enlazar en la colección puede ser una clase o una estructura, pero debe ser pública sí o sí.
Ya os imagináis por qué estoy poniendo esta entrada, ¿no? 😛

 

Yoda Code y el Optimizador de .NET

Dicen que a veces la vida te da sorpresas, sorpresas te da la vida. Y en este caso es completamente cierto. A raíz de la entrada anterior, un par de amigos comentaron en Twitter sobre la misma, haciendo uno de ellos hincapié en el Yoda Code que había puesto.

No soy yo muy partidario de Yoda, más que nada porque todos los lenguajes con los que programo suelen avisarte del uso de un solo igual en las comparaciones, aparte de que, como perteneciente a la vieja escuela, veo raro poner eso al revés. No es que sea gratuito, sino que viene de la forma en que aprendimos los lenguajes.

Digamos que para nosotros, en null==handler, null es un lvalue y debe ir a la derecha sí o sí. A ver, que es un poco tontería porque es una comparación, no una asignación, pero así lo veo al menos yo.

Evidentemente no hay nada en contra de utilizar al amigo Yoda (esperemos que Spielberg no se nos enfade y empiece a pedirnos derecho de marca). Simplemente yo lo veo extraño.

***

Pues nada, el RFOG pone las manos en la masa y decide investigar si hay alguna diferencia en el código generado por el compilador entre ponerlo de una forma u otra. Y ahí es donde se lleva una sorpresa que seguro vosotros tampoco os esperáis (no, no es la que pensáis. Paciencia, joven padawan).

Para ello se crea un proyecto de consola con el siguiente código fuente en C#:

        static void Main(string[] args)
        {
            var a = 33;
            if (40 == a)
                Console.WriteLine("Es diferente");
            else
                Console.WriteLine("Es igual");
        
            if (a == 40)
                Console.WriteLine("Es diferente");
            else
                Console.WriteLine("Es igual");
        }

Y en C++ (más bien C, pero a efectos de nuestro interés da igual):

            auto a = 33;
            if (40 == a)
                printf("Es diferente");
            else
                printf("Es igual");
        
            if (a == 40)
                printf("Es diferente");
            else
                printf("Es igual");
			return 0;

Y finalmente en C++/CLI, más que nada por mor de completitud:

int main(array<System::String ^> ^args)
{
	auto a = 33;
	if (40 == a)
		Console::WriteLine("Es diferente");
	else
		Console::WriteLine("Es igual");

	if (a == 40)
		Console::WriteLine("Es diferente");
	else
		Console::WriteLine("Es igual");
	return 0;
}

Si os fijáis, el código es idéntico excepto sus diferencias de sintaxis. Para ver el código resultante, se pone un punto de interrupción en la asignación de la variable a, se lanza el programa y luego nos vamos a Debug -> Windows -> Disassembly (o pulsamos Alt-8). Y miramos el código resultante en los tres casos. Primero en Debug y para C#:

clip_image002

Nítido como el agua: tanto monta, monta tanto, a==40 que 40==a. Perfecto. Vamos con C++/CLI:

clip_image004

Más o menos como en C#, de hecho el código es prácticamente el mismo. Finalmente C++ nativo:

clip_image006

Otra vez como lo esperado. Ninguna diferencia en la generación de código en la parte de la comparación. Bueno, no, algo peor porque el código generado en C++ es a todas luces peor que el de C#, cosa que me extraña. Esta es la primera sorpresa, pero todavía hay más.

De todos modos, si te preocupaba la generación de código tanto usando a Yoda como sin usarlo, ves que no hay diferencia.

Aun así, te recomiendo que sigas leyendo. Lo interesante viene ahora.

***

Pasemos a las versiones Release, que se suponen generan mejor código. La versión en C# genera exactamente el mismo código, por lo que realmente el compilador no está haciendo nada de nada. No hace falta que ponga ninguna captura: el código es idéntico.

En C++/CLI ya vemos algo diferente, y es que el breakpoint se ha movido él solo hacia abajo. Eso quiere decir que ha entrado el optimizador de código:

clip_image008

La versión en ensamblador es terroríficamente simple:

clip_image010

Como el compilador ya sabe el resultado, simplemente ejecuta el código adecuado y punto. El que el primer bloque de ensamblador sea tan largo se debe al prefijo de carga de main, y ese je 00000015 no es más que la comparación de a con 40, que el optimizador todavía realiza.

¿Por qué lo hace? Buena pregunta: otro hilo podría haber cambiado el valor de a, por lo tanto es necesaria la comparación. Ya sé que en este contexto no es válido, pero en otro sí que podría serlo.

Lo mismo nos pasa con C++ nativo, y ahora sí que vemos cómo el código está más que optimizado y apenas son unas cuantas línea de código ensamblador. La siguiente captura está dedicada a todos aquellos que piensan que no vale la pena desarrollar en C++:

clip_image012

***

Hasta ahora está todo meridianamente claro: No hay diferencia entre ir con Yoda o sin él y que el compilador de C++ es una caña generando código.

¿Estamos todos de acuerdo? Yo al menos lo estaba hasta hace bien poco. Ahora os dedico dos nuevas capturas de pantalla:

clip_image014

clip_image016

Y este es el bombazo: el código en .NET es casi idéntico al nativo. Cosa que hace unos años no pasaba. ¿Cómo he obtenido esas capturas? Os vais a Tools -> Options -> Debugging -> General -> Supress JIT optimization on module load y desmarcáis la casilla.

Bueno, el código es casi tan bueno como el nativo, pero fijaos que es mucho menor que las versiones anteriores. Esto me lleva a confirmar una sospecha: la gente de Microsoft está haciendo bien sus deberes, llevando al compilador de C# a cotas cada vez más altas.

Y es que con los años parece ser que han mejorado mucho:

Cross Threading en MVVM y Windows Phone 8 (y también 7)

 

Os cuento una rápida que seguro os va a solucionar un montón de quebraderos de cabeza y que me ha traído loco un rato hasta que me he dado cuenta del pufo.

Todo viene cuando estás usando el patrón MVVM y varías algún dato que se está mostrando en algún componente visual. Todos los tutoriales te dicen que heredes de ObservableCollection y que implementes el método NotifyPropertyChanged(). Y te ponen el típico ejemplo:

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
    var handler = PropertyChanged;
    if (null != handler)
    {
      handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Hasta aquí nada extraño. Cuando una propiedad cambia su valor, quien quiera que esté observando tu colección se enterará del mismo y actuará en consecuencia. Eso si alguien está observando tu colección, que no siempre ocurre, sobre todo si hay algún converter de por medio (ya hablaré largo y tendido sobre esto).

Pero el problema viene cuando ese cambio se produce fuera del hilo principal de la aplicación, como suele pasar a poco que estés haciendo algo medianamente serio. No veo yo bloqueando tu aplicación mientras un servicio web o lo que sea se baja lo que se tenga que bajar, aparte de que en Windows Phone la mayoría de llamadas a todo eso son asíncronas.

Si haces un cambio en un hilo que no sea el de la UI, en Windows Phone 7.5 no pasa nada. Simplemente se ejecuta el código y en general tu colección cambia de valor y a veces, sólo a veces, la visualización cambiará. O no.

En Windows Phone 8 ocurre otra cosa no muy diferente. Recibes dos first chance de dos excepciones diferentes, el IDE no te captura nada a no ser que cambies la configuración de captura de excepciones y el hilo en el que se esté ejecutando el código se muere silenciosamente. Y por supuesto no se cambia nada en la parte visual de tu aplicación.

Vale. Tonto si no pones un bloque try/catch en cada hilo. Pero aquí estamos hablando de otro combate.

¿Cómo puñetas puedo actualizar eso de forma automática? Es decir, ¿tengo que hacer un BeginInvoke() cada vez que asigne algo? La respuesta corta es que sí. La larga es lo siguiente.

Primero tienes que crearte una propiedad nueva en la clase App que vas a llamar UiDispatcher (o como te salga de los OO):

internal static Dispatcher UiDispatcher=Current.RootVisual.Dispatcher;

Y luego cambia el código de arriba por el siguiente:

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var handler = PropertyChanged;
            if (null != handler)
            {
                if (App.UiDispatcher.CheckAccess())
                    handler(this, new PropertyChangedEventArgs(propertyName));
                else
                    App.UiDispatcher.BeginInvoke(() => handler(this, new PropertyChangedEventArgs(propertyName)));
            }
        }  

Ahora, si os fijáis, si el cambio de vuestra propiedad se realiza dentro del hilo principal, se llamará directamente, y si lo hace desde otro lo hará dentro del Dispatcher de la UI.

¿Por qué una propiedad y no llamar siempre a Current.RootVisual.Dispatcher? Pues porque podría interesarnos tener diferentes dispatchers para otras cosas, pero esa es otra guerra que hay que combatir en otro momento.

ReSharper para Visual Studio

Esta es una historia un tanto extraña porque ni en mis más locos sueños hubiera yo decidido usar este complemento en Visual Studio. No porque no me guste la empresa, ni porque piense que el producto sea malo.

Simplemente porque no soy yo mucho de añadir complementos a mi herramienta de trabajo más allá de las cosas imprescindibles, más que nada porque los tiempos de carga se alargan en extremo, y la estabilidad de Visual Studio decae en picado.

Por ejemplo, si ya la versión 2010 de VS anda algo inestable, con vahídos extraños, cuando le añades el SDK de Windows Phone la cosa empeora y te encuentras con que a veces el compilador se encuentra errores fantasma que sólo él ve, o simplemente el IDE se queda autista.

Añádele alguna herramienta más y eres un firme candidato a lanzar tu ordenador por la ventana y dedicarte a criar setas en el sótano de tu abuelo.

Sin embargo Visual Studio 2012 parece más estable, y he estado como dos semanas usándolo sin que hiciera cosas raras, incluso tras añadirle el citado SDK, que es imprescindible para mi en estos momentos.

De repente a un compañero que trabaja en la aplicación de Java de mi empresa le compraron el IntelliJ y comenzó a comentar las bondades del producto y cómo había pasado de desesperarse y tirarse de los pelos con la cosa esa del Eclipse a tener un IDE en condiciones.

Eso me llevó a recordar que cuando asisto a alguna charla virtual suelen regalar un ReSharper a los asistentes… y una cosa me llevó a la otra, y es que la envidia es tiñosa, y muy mala malosa, y yo soy el peor de todos. Por lo tanto entré en la web de JetBrains y me bajé el producto en su versión demo de treinta días y…

 

¡¡MADRE DEL AMOR HERMOSO!!

 

¡Como alguien me quite el producto me lo como con ropa y todo! ¿Cómo he podido vivir yo sin eso?

A ver, que no estoy exagerando ni mucho menos. El producto cuesta sus pelas, pero os aseguro que las vale. Ahora que estoy desarrollando en C# porque no tengo más cojones, se me ha hecho prácticamente indispensable y eso que lo llevo usando tan sólo unas dos semanas.

Os cuento lo que hace. Y ya me conocéis, que yo no me caso con nadie y no tengo pelos en la lengua.

***

ReSharper es una extensión a Visual Studio (creo que soportan todas las versiones del producto desde la 2003 menos las Express). En mi caso lo instalé en mi Visual Studio Ultimate de la MSDN.

Lo que hace el producto es ayudarte a teclear código, pero a todos los niveles. Hay que verlo para creerlo. Cuando está instalado lo que más llama la atención es que te coloca una tira vertical al lado derecho de la ventana de edición, similar a la de la derecha en donde pones los breakpoints, bookmarks y el IDE te marca el código modificado.

En esa columna te coloca una serie de rayitas horizontales de colorines. Rojo para los errores. Naranja para las mejoras (ahora os cuento), verde para las sugerencias. Creo que hay más colores, pero en este momento no me acuerdo (son las cosas de estar tirado en el sofá tecleando en mi MacBook). Arriba del todo hay una marca global que te dice el 

Cuando posas el ratón sobre la rayita, te dice de qué va la cosa, y si haces clic te lleva al código fuente en cuestión. 

Y aquí es donde viene lo interesante. Te ofrece la mejora o la solución, y si le dices que sí, te lo corrige. 

Pero os aseguro que es algo terrorífico. Hay cosas más o menos chorras, como cambiar un tipo por una variable automática, pero otras dan miedo.

Es capaz de cambiar tus bucles for o foreach por sentencias LINQ. Con eso ya os lo he dicho todo. A mi al menos eso me da mucho miedo. Del bueno, ojo. Que coja tres bucles anidados y te los convierta en una sentencia LINQ de una línea me deja embobado.

Peor hay más. Simplifica los operadores lambda, te transforma bloques de código en otros menos agresivos con la aplicación, te formatea el código, te ofrece lo que vas a escribir a continuación…

No sé, cada vez que hago algo nuevo me sorprendo por las posibilidades que te ofrece. Otra de las cosas que me trae loco es que es capaz de eliminar código redundante, como la creación de delegados o la eliminación de código redundante.

Os pongo un ejemplo que me dejó todo loco.

Yo solía poner sentencias del tipo:

 

Debug.WriteLine(String.Format(“bla bla {0} bla bla {1}”,a.Hola,a.Adios));

 

Pues bien, él me sugiere

 

Debug.WriteLine(“bla bla {0} bla bla {1}”,a.Hola,a.Adios);

 

Vale. Tú lo sabes. Yo no lo sabía hasta que no me lo ofreció ReSharper. Y así con muchas cosas más, pero lo que de verdad me admira son las transformaciones a LINQ y viceversa. No me canso de repetirlo. Bucles a LINQ. Bucles a LINQ.

También tiene soporte en XAML. Es decir, editar XAML pasa de ser una pesadilla a ser bastante mejor. Si tu usas Blend, mejor para ti. Yo la última vez que intenté hacer algo con el producto terminé hasta la coronilla. Entre excepciones y la puta manía de ponerle márgenes hasta a su madre… Pues bien, con ReSharper editar a mano XAML también mejora la cosa.

Refactoring. Todo lo que te puedas imaginar y más. Si añadimos las reglas para estilo de código, te detecta las variables y los métodos que no lo siguen, ofreciéndote cambiarlos si así lo deseas. Y es una cosa a la que vas a decir que sí, porque esas rayitas naranjas no molan nada, y que no te las vea el jefe… 😛

Lo dicho, en cuanto te sales de las guías de estilo el producto no solo te lo dice sino que te ofrece la posibilidad de cambiarlo. Por supuesto puedes definir las tuyas, no las que el programa quiera. 

Como abras la pantalla de opciones te vas a caer de culo, porque puedes configurar cualquier cosa. Por tener hasta tienes “juegos de configuración”, pudendo cargar la que quieras cuando quieras, por si tienes un proyecto con unas reglas y otro con otras.

También tiene algunas chorradillas (es un decir) interesantes, como que te pinta una raya de color debajo de un número que represente un código ARGB, por poner un ejemplo. Son cosas que no se echan en falta hasta que no las tienen y luego te las quitan.

Ya para terminar comentaros los Find Usages. Algo así como Find all references pero con muchos esteroides. Pones el cursor sobre un símbolo, le das a la opción con el botón derecho del ratón y goza. Así he encontrado un par de problemas serios de sincronización que me tenían todo loco, y encima en un rato de nada.

Opciones que no he probado han sido la de limpiar el código de toda la solución de una tacada y otras que seguro se me escapan.

Bueno, pues lo dicho, si quieres aumentar tu productividad de forma bastante seria, prueba el producto. Seguro que luego pasas por caja. Y si entráis en la Web de JetBrains podréis ver capturas de pantallas y algún vídeo enseñando lo que es capaz de hacer.

Yuliop y Windows Phone 7 SDK: Una introducción

Como ya comenté hace algo de tiempo, he realizado un cambio laboral bastante radical, dejando de lado el desarrollo de sistemas embebidos verticales escritos en C y C++ para subir un paso en el escalón del desarrollo en cuanto a tipos de proyecto. En otras palabras, ahora mi tarea principal es desarrollar con Windows Phone para una startup llamada Yuilop.

He pasado de ser un desarrollador más o menos versátil a estar no sólo centrado en una plataforma fija, sino en una única aplicación: su cliente de mensajería. Os contaré cómo funciona la cosa.

La aplicación está disponible para la mayoría de teléfonos Android y para iOS, y próximamente habrá una versión para Windows Phone 7.5, la que estoy haciendo yo. Olvidaros de Windows Phone 7.0 porque no tiene sockets y es prácticamente imposible hacer algo ahí. Se podría implementar con BOSH, pero no vale la pena.

Con la aplicación instalada en un teléfono se pueden enviar mensajes de texto, con emoticonos y emojis, de manera similar a como se realiza con otras aplicaciones similares. También puedes enviar fotos y localizaciones. Hasta aquí nada nuevo bajo el sol.

Lo novedoso está en que también puedes hacerlo a gente que no tenga la aplicación. Es decir, puedes chatear con prácticamente cualquier persona que tenga un móvil a través de SMS. Es decir, tu envías un mensaje de chat y la otra persona recibe un SMS, y justo al revés.

También puedes hablar por teléfono mediante VOIP. Siempre que la otra parte tenga Yuilop instalado podrás hablar con ella de forma gratuita a través de la WiFi o del 3G, sin gastar una llamada de voz tradicional…

No, espera, no. Eso también lo puedes hacer con cualquiera. Incluso con teléfonos fijos. O en otras palabras: no es necesario que la otra persona tenga la aplicación instalada para poder hablar con ella a través de Yuilop.

Todo ello con coste cero. O más bien, pagas la transferencia de datos, el Wifi o el 3G. No pagas ni SMS ni establecimiento de llamada ni a razón del tiempo que estés hablando o chateando o SMSseando.

¿Cómo puede funcionar algo así? Pues bastante fácil: la aplicación tiene publicidad, y el pulsar en ella, o instalarte aplicaciones recomendadas, o seguir ciertas indicaciones te dan energía, que es lo que gastas a la hora de hablar o chatear con gente no Yuilop.

Es decir, que cada vez que hagas algo con gente de fuera de la aplicación, gastas energía. Cada vez que instalas las aplicaciones recomendadas, o haces clic en la publicidad, o chateas con gente Yuilop, obtienes energía. También por invitar a amigos y que estos acepten la invitación.

***

Como veis resulta algo bastante interesante y más potente que las aplicaciones de la competencia (que no nos dejan nombrar).

Pues bien, el que esto suscribe tiene en un estado bastante avanzado la aplicación para Windows Phone. Dadas las características de este sistema operativo, hay algunas opciones que no van a estar disponibles, no porque no queramos, sino porque no podemos.

Y eso me lleva al tema técnico. Llevo dos meses desarrollando con Visual Studio 2010 y el SDK 7.1. Ha habido momento en los que he estado a punto de renunciar dadas no ya las enormes carencias de la plataforma, sino también la falta de documentación y las inconsistencias y bugs de todo ello.

Y de eso es de lo que voy a hablar próximamente aquí. Primero haré una lista de todos los problemas con los que me he encontrado y la forma que te tenido de solucionarlos cuando he podido hacerlo, que no siempre ha sido así.

Para adelantaros un poco el tema, el modelo MVVM es una mierda limitadísima que sólo permite realizar aplicaciones típicas y sencillas, el acceso a bases de datos es, más que pésimo, limitado e incoherente, y existen ciertas limitaciones incoherentes para realizar algunas tareas. Además, la gestión de eventos es mínima, la creación de controles personalizados deja mucho que desear, así como el API expuesto en relación a los componentes con los que podemos trabajar (y ahí incluyo también el Windows Phone Toolkit y sus amigos de Coding4Fun).

Y no, el modelo asíncrono de desarrollo es toda una gozada si no existieran las limitaciones arriba descritas. Los métodos asíncronos, los operadores lambda, los métodos de extensión (pese a ser aberraciones, ya os contaré) y demás zarandajas son una gozada.

Mejor no hablar de XAML, menuda porquería de implementación aunque la idea esté genial.

Y a todo ello añadimos el hecho de que apenas existe documentación. Mientras que para la explicación de una clase en .NET 3, 3.5 ó 4.0 tienes una explicaciones más que detalladas contándote todo, en Silverlight las páginas están más que peladas. Por no incluir ni siquiera ponen lo imprescindible. Parece que se hayan creado a partir del propio código fuente sin más. Y no, no vale aplicar las explicaciones de una a la otra: simplemente funcionan diferente o el comportamiento no existe.

Bueno, lo dicho, estad atentos que le voy a dar caña a Windows Phone 7.5 (Parece ser que la versión 8 ya es adulta y han añadido cosas muy interesantes. También os contaré dentro de unos meses, cuando empiece con ella).

Viendo el código fuente de .NET con Visual Studio 2012

Quien tenga una versión anterior de Visual Studio seguro que sabe que se puede navegar por las tripas de .NET y ver cómo Microsoft ha implementado todo el tema. Pues bien, más o menos a mediados de agosto del corriente (2012) se anunció la disponibilidad del código fuente de .NET 4.5, lo que nos permite meternos en las tripas del Framework y, lo que es mucho más interesante, mirar cómo funciona todo lo nuevo relacionado con Windows 8.

El artículo citado da un somero repaso a las novedades no específicas de la biblioteca, entre las que se pueden destacar el añadido de métodos asíncronos en conjunción con las clases de tareas, y que ahora el jitter es capaz de optimizar el código para los procesadores multinúcleo. También se mejora el rendimiento de casi todo (como siempre dicen, lo que a veces no es cierto), y se potencia el acceso de .NET a nueva parte nativa de Windows 8 (o RT o Metro o como quieras llamarlo), que es código nativo escrito en C++ y C++/CX, permitiendo a este lenguaje acceder, también, a código escrito en otros lenguajes .NET gracias a su parte CX (que como ya he dicho varias veces, es nativa).

Como en otras versiones, el código fuente está disponible para descarga directa, o para ser visto desde nuestro propio código, y también como símbolos de depuración.

La captura de abajo nos muestra una aplicación Metro por defecto, detenida en un punto de interrupción, tal y como se ve en mi Visual Studio 2012 sin cambiar la configuración por defecto:

clip_image002

Fijaos en que la ventana de Call Stack estgá prácticamente vacía, y si hacemos Step Into simplemente saltamos a la siguiente línea de nuestro código fuente.

Vamos a habilitar la posibilidad de meternos dentro del código de Microsoft.

Nos vamos a TOOLS -> PROPERTIES, abrimos la pestaña lateral de Debugging, y cambiamos las siguientes opciones:

· Marcar Enable Just My Code

· Marcar Enable .NET Framework source stepping

· Desmarcar Step over porperties and operators (Managed only)

· Marcar Enable source server support

· Desmarcar Require source files to exactly match the original version.

Dejadlo todo más o menos como en la imagen:

clip_image003

Ahora, en la pestaña de Symbols, hay que añadir una nueva dirección de descarga de los mismos: http://referencesource.microsoft.com/symbols. Como en la capura.

clip_image004

Finalmente, cuando le deis a OK el IDE se quedará bajando ficheros. Hay que esperar a que termine, y dependiendo de lo rápida que sea tu conexión, tendrás que esperar bastante tiempo.

Con esta configuración, cada vez que se necesite algo, el IDE irá a los servidores de Microsoft, por lo que la carga y depuración de vuestro programa podría ser muy lenta a veces… por lo que se pueden bajar todos los símbolos de una tacada e instalarlos de forma local, apuntando la URL anterior a done los hayamos instalado. Podéis bajarlos de aquí.

La siguiente captura muestra algo de las tripas de Metro:

clip_image006

Vale. Ahora el tío de la rebaja. ¿Habéis intentado profundizar en el código fuente, en métodos como el Activate() de la primera captura? No entra, ¿verdad? No muestra código fuente, sino que simplemente salta sobre la llamada.

Un gallinfante a quien adivine por qué es.

Vale: es código nativo. Es decir, la parte Metro del .NET Framework no es código manejado, sino nativo. Es decir, está escrita en C++/CX, en donde la parte CX actúa como Sugar Syntax de todo el perifostio COM y COM+ que finalmente es .NET

Y todavía me atrevería a añadir algo más. Metro esconde en la manga algunos trucos de desarrollo que a MS no le interesa que se sepan, y ya visteis lo fácil que es hacer ingeniería inversa de una aplicación .NET. Si toda esa parte hubiera estado hecha con .NET, sería facilísimo meterle mano.

¡Y qué cojones, donde esté C++ que se quite cualquier lenguajucho de mala muerte! 😉