Sei sulla pagina 1di 68

Portada Sp 172:Portada Sp 171 5/6/09 10:53 Página 1

LA PRIMERA REVISTA DE PROGRAMACIÓN EN CASTELLANO

M
OE
-R UY
D CL
C IN

Precio: 6 € (España) (IVA incluido) • AÑO XVI. 2.ª ÉPOCA • Nº 172 • UNA PUBLICACIÓN DE: REVISTAS PROFESIONALES S.L.

172

Arquitectura de
Fuentes
Hispano
Podcast java st – 043, 044,
JavaHispano Podca
048
045, 046, 047,

sobre
Vídeo-Curso a Visual
REVISTAS , S.L. Actualización
P SIONALES LinQ con
Studio 2008:
ROFE , 42 - 3.ª
9.0 (VI)
Visual Basic
VALENTÍN BEATO
28037 MADRID
M-26827- 1994
DEPÓSITO LEGAL: 92
ISSN: 1134-47

Y además…
res 170
Solo Programado f
en formato pd

Solo Programadores
número 170
en formato pdf

Videocurso
Curso Actualización a Visual Studio 2008 -
LinQ con Visual Basic 9.0 (VI)

JAVAHISPANO
Actualidad Java

REDES
Cookies en el navegador y en el servidor (II)

ALGORITMOS
Programación orientada a objetos con C++ (V)
XNA Framework 2.0 y 3.0: DirectX y Direct3D
en C# para mortales (IV) Incluido en el CD de regalo
“LinQ con Visual Basic 9.0
BASES DE DATOS (VI)”, código de los artículos
Arquitectura de Oracle (I) principales, últimos podcast
de JavaHispano

Noticias, Dudas, CD-Rom


Interior portada:Layout 1 9/6/09 08:56 Página 1
03 Editorial 172:03 Editorial 163 5/6/09 11:04 Página 3

Número 172
Edi ta : R EVISTAS PR OF ESIO N AL ES S. L .
solop@revistasprofesionales.com
EDITORIAL
C/ Valentin Beato 42, 3ª 28037 - Madrid
www.revistasprofesionales.com

Parece que Windows 7 estará disponible en Navidad y suponemos


••••••••••••••••••••••••••••••••••
E d it o r
Agustín Buelta que a partir de ese momento los usuarios de Windows Vista
comenzarán la carrera de migración a Windows 7. Pero, ¿qué pasará
••••••••••••••••••••••••••••••••••

con los usuarios de Windows XP?.


D ir e c t o r

Tras los años que le ha costado a Windows XP ganarse la confianza


Ricardo Álvarez
••••••••••••••••••••••••••••••••••
C o la b o r a d o r e s del usuario, el temor y desconfianza en Windows Vista ha supuesto
un freno importante frente a nuevas versiones por lo que
Abraham Otero, Juan Martos,
Adolfo Aladro, Guillem Alsina,
posiblemente el usuario satisfecho con Windows XP será muy cauto
Nicolás Velásquez, Gastón Hillar,

a la hora de eliminar el S.O. que tantas satisfacciones le ha dado y


David Roldán
••••••••••••••••••••••••••••••••••
M a q u e t a ci ó n que merece su confianza y sustituirlo por el nuevo desconocido.
Posiblemente, tengan que transcurrir muchos meses antes de que el
Alfonso Sabán Mejías - Raúl Clavijo

usuario tenga la suficiente confianza en la nueva promesa de


••••••••••••••••••••••••••••••••••

Microsoft y dé el paso definitivo hacia lo desconocido.


D e p a r t a m e n t o d e P u b l ici d a d
Felipe Ribagorda
Tel.: 91 304 87 64
D e l e g a c i ón e n B a r c e l o n a
C/ Rocafort, 241/243, 5º 1ª
Mariano Sánchez
Tel.: 93 322 12 38
••••••••••••••••••••••••••••••••••
D p t o. S u s c r i p c i o n e s
Tel: 91 304 87 64
Fax: 91 327 13 03
•••••••••••••••••••••••••••••••••••
I m p re si ó n
SUMARIO
ALGORITMOS
L.M.S. Solución Gráfica
ideasimpresion@telefonica.net

46 Programación orientada a objetos con C++ (V)


•••••••••••••••••••••••••••••••••••
D i s t r i b u ció n
30 XNA Framework 2.0 y 3.0 : DirectX y Direct3D en C# para mortales (IV)

Coedis S.L. REDES


54 Cookies en el navegador y en el servidor (II)
C/ Alcorcón nº 9 - 28850 Torrejón de Ardoz (Madrid)
Teléfono 91 676 96 62

BASES DE DATOS
DISTR I B U CION EN MEX ICO
DIMSA - C/ Mariano Escobedo, 218
Col. Anáhuac. 11320 México, D.F.

D ISTR IB U CIO N EN AR GEN TIN A 16 Arquitectura de Oracle (I)

Y ADEMÁS. . .
Capital Federal: Distrimachisa
Interior: York Agencysa - Tlf: (5411) 433 150 51
••••••••••••••••••••••••••••••••••

04
Quedan expresamente prohibidas la reproducción, la
distribución y la comunicación pública de todo o parte de Noticias
14 javaHispano
los textos contenidos en esta publicación, por cualquier
medio y en cualquier soporte, y para cualquier fin,

60 Dudas
incluyendo la realización de resúmenes de prensa
comerciales, sin la autorización expresa de esta Editorial,

64 Vídeo-Curso
conforme a lo dispuesto en la vigente Ley de Propiedad
Intelectual. La infracción de la presente prohibición

66 Contenido CD
será perseguida penalmente.
Cualquier forma de reproducción, distribución, comunicación
pública o transformación de esta obra solo puede ser
realizada con la autorización de sus titulares, salvo excepción
prevista por la ley. Diríjase a CEDRO (Centro Español de
Derechos Reprográficos, www.cedro.org) si necesita
fotocopiar o escanear algún fragmento de esta obra.
Depósito legal: M-26827-1994
P R IN TED IN SPAIN
P.V.P. 6 euros
04-13 Noticias:NOTICIAS 5/6/09 11:00 Página 4

NOTICIAS

LA GRIPE PORCINA SE CONVIERTE EN la circulación de correos electrónicos con manos a la obra para redefinir y fortalecer
VIRUS INFORMÁTICO supuestos vídeos y mensajes del Presidente su infraestructura informática.
de México, Felipe Calderón, o de empleados Los principales problemas que se detecta-
La gripe porcina ha creado las condiciones de la Secretaría de Salud, ofreciendo nue- ron fueron los de software mal configura-
perfectas para que el ciber-crimen actúe y vas medidas y datos sobre la epidemia. do y programas reinstalados a los que no se
coseche nuevos “éxitos”, tal y como explica El mensaje ya ha sido bloqueado por Trend les volvían a aplicar los parches de seguri-
Trend Micro, que alerta de la difusión men- Micro gracias a su tecnología Smart dad acumulativos. No obstante, parece ser
sajes de spam a través de los que se propa- Protection Network. Asimismo, la compañía que no se valoró un cambio de plataforma,
gan virus y código malicioso. se ha encargado de avisar a los usuarios sino que se optó por hablar directamente
Después de que la Organización para que ignoren este y otros men- con el fabricante, con Microsoft, para ver si
Mundial de la Salud (OMS) sajes similares que puedan llegar esta compañía podía suministrarles una
elevara el nivel de alerta a sus bandejas de entrada y versión de Windows con seguridad aumen-
sobre la difusión del virus opten por elegir fuentes más tada. Y para ello, la USAF accedió directa-
de la gripe porcina, el fiables para informarse sobre mente a lo más alto de la compañía de
equipo de técnicos de la gripe porcina. La pandemia Redmond: su CEO Steve Ballmer.
Trend Micro, líder global ya se ha cobrado 159 víc- Ballmer se involucró personalmente en el
en seguridad de conteni- timas en México, donde proyecto y, de resultas, el equipo de des-
dos en Internet, advierte de se sitúa el foco del arrollo encargado acabó produciendo una
que los spammers rápida- brote, mientras que, a versión de Windows XP en la cual se había
mente han aprovechado esta medida que pasan los cambiado la forma en la que se manejan las
situación de alerta para extender sus cam- días, cada vez es mayor el número de casos contraseñas de administradores, a la vez
pañas de spam. Así, ya se han detectado que se conocen en otras partes del mundo. que se introducían herramientas para
casos de correo basura con mensajes del actualizar de forma automática el sistema
tipo “¡La gripe porcina afecta a todo el COMO HACER QUE WINDOWS con los últimos parches y prevenir altera-
mundo!” o “¡Brote de gripe porcina!”. SEA UN SISTEMA MUY SEGURO: ciones en la configuración. Más de 600 pre-
Los spammers están utilizando esta técnica ferencias y “flags” se bloquearon para que
de ingeniería social porque aprovechando LA EXPERIENCIA DE LA USAF no fuesen cambiados por el usuario.
las últimas noticias y dada la alerta social El despliegue de estos Windows XP modifi-
que se está produciendo, el hecho de incluir Microsoft creó en 2005 una versión ultra- cados se inició en 2005 y finalizó en 2007.
estos temas en el asunto del mensaje de segura de su sistema operativo Windows Su efectividad se demuestra con los núme-
correo electrónico supone incrementar de XP para la fuerza aérea norteamericana. ros: según John Gilligan, es-CIO (Chief
forma notable la posibilidad de que el des- Esta es su particular historia que nos deja Information Officer) de la USAF, hasta un
tinatario que lo reciba abra estos mensajes una pregunta: ¿cuánta de su tecnología ha 85% de los ataques son bloqueados direc-
de spam. pasado a Windows Vista y 7? tamente gracias a la nueva configuración
“Mediante el uso de ingeniería social, la Es obvio que unas fuerzas armadas necesi- blindada de que disponen sus escritorios
gripe porcina se ha convertido en un virus tan sistemas informáticos seguros, inde- Windows. El éxito ha sido tal que estos sis-
informático que aprovecha el miedo, la pendientemente del país al que pertenez- temas reforzados están en uso en otros
confusión y el interés por la información can, y es también obvio que Microsoft departamentos del gobierno.
disponible en la web acerca de la epidemia Windows no tiene precisamente buena La USAF impone a sus contratistas que
para propagar códigos maliciosos, correos fama en este aspecto. A los posibles ata- incluyan el Windows XP modificado como
electrónicos basura e infectar equipos ques procedentes de fuerzas armadas de sistema preinstalado en todas las computa-
informáticos”, tal y como explica Juan países enemigos o potencialmente enemi- doras que adquiere, por lo que un efecto
Pablo Castro, Coordinador de Tecnología de gos, sus respectivos servicios de inteligen- colateral del nuevo sistema es que se ha
Trend Micro Latinoamérica. cia y los miles de hackers repartidos por simplificado la gestión ya que ahora no hay
“La gripe porcina no sólo ha hecho que los todo el mundo que no sienten un gran que lidiar con varias configuraciones dis-
ciudadanos permanezcan recluidos en sus afecto por los estamentos gubernamenta- tintas, sino con una sola.
hogares. Este fenómeno hará que pasen les norteamericanos, hay que sumarle las Después de todo esto, particularmente se
más tiempo conectados a Internet en busca vulnerabilidades normales y corrientes del me ocurren dos preguntas: en primer lugar,
de información, recomendaciones o sistema, las posibilidades de infección con y si se necesitaba un sistema muy seguro
comentarios sobre el tema, prolongando de virus y, en general, todas las incidencias de ¿por qué no recurrir a OpenBSD o NetBSD?
paso su tiempo de exposición a ataques de seguridad que afectan al común de los ambos han demostrado ser de los más
ciber-criminales. Es la tormenta perfecta mortales.
para la delincuencia por Internet”, comenta Es por ello que la USAF (United States Air
el directivo. Force) encargó en 2003 a la NSA (National
El contenido de estos mensajes de spam Security Agency, la agencia federal nortea-
evidentemente no está relacionado con el mericana encargada de garantizar la segu-
virus de la gripe porcina, sino que se trata ridad en las comunicaciones) una auditoria
de un mensaje breve relativo a spam far- de seguridad de sus sistemas. El resultado
macéutico y de medicinas con un link que fue, como mínimo, decepcionante, y podría
dirige directamente al usuario a una tienda resumirse diciendo que la red de la USAF
online que vende medicamentos para la era un auténtico queso de gruyere... Así que
erección. para garantizar la seguridad de la primera
Asimismo, Trend Micro también advierte de potencia del mundo, la fuerza aérea se puso

SOLO PROGRAMADORES nº 172 4 www.revistasprofesionales.com


04-13 Noticias:NOTICIAS 5/6/09 11:00 Página 5

NOTICIAS

seguros hasta la fecha. Y, en segundo lugar, Las guerras de religión son probablemente
si Microsoft es capaz de ofrecer una versión tan antiguas como la misma historia de la
tan segura de Windows a las fuerzas arma- humanidad, que no solamente no se pone
das ¿por qué toda o parte de esta tecnolo- de acuerdo en si existe o no un ser superior,
gía no pasa a nuestros Windows de consu- sino en cuál de los postulados es el verda-
mo? dero y único. Internet se ha convertido en
La segunda pregunta tiene, sin lugar a arma y campo de batalla en estas nuevas
dudas, una respuesta más simple que la pri- cruzadas religiosas, una de las cuales -por
mera. Y es que si hacemos un sistema segu- suerte para todos incruenta- es la que
ro, complicamos más su gestión para el enfrenta a partidarios y detractores de la
usuario final, que es precisamente lo que Iglesia de la Cienciología.
no quiere hacer Microsoft para que su pla- Esta viene de lejos, y ha tenido diferentes
taforma continúe siendo tan popular como episodios, cosa que no es de extrañar ya
hasta ahora. Cortar servicios y limitar lo que la Iglesia de la Cienciología ha pasado
que se puede hacer con el software de ter- casi toda su breve pero intensa historia
ceras partes podría llevar a un desencanto envuelta en la polémica. La última ha sido
de sus usuarios con la plataforma, lo que máquina a otra, dificultan mucho su locali- dada a conocer por el rotativo británico
llevaría a los clientes a alzar la vista hacia zación. dedicado a las nuevas tecnologías The
alternativas como Mac OS X o GNU/Linux, Esta es una de las tretas que usa el gusano Register, el cual ha informado que la enci-
con la consiguiente pérdida de cuota de Conficker, el más mencionado en la reunión clopedia en línea Wikipedia, regida por el
mercado y dominio. como ejemplo del auge del código malicio- modelo colaborativo al mismo estilo que
Por lo tanto, va a ser difícil que Windows so, que dobla sus cifras cada año y sobre- proyectos de software como Open
sea mucho más seguro de lo que ya es pasa en ritmo de crecimiento al "phishing". Office.org o Linux, ha incluido las direccio-
Windows Vista, tal vez el mayor exponente Panda Security detectó 20 millones de nue- nes IP de las computadoras que se sabe a
hasta ahora de la seguridad en los sistemas vos virus en 2008. Cambian muy rápido, ciencia cierta pertenecen a la Iglesia de la
operativos de la compañía de Redmond, y tanto en su forma como en los mensajes de Cienciología en una lista mediante la cual
que ha sido mucho menos criticado en este correo en los que viajan, las páginas web en se les prohíbe editar artículos de la enciclo-
aspecto que Windows XP, el cual (y reto- las que se esconden y las direcciones IP de pedia. Es lo que se conoce como banear a
mando una frase del principio del artículo) las mismas. Se necesitan meses para desci- dicha organización.
tenía fama de auténtico “queso de gruyere”. frar su código, cuando antes se hacía en
De hecho, es posible que alguna parte de la días. FACEBOOK Y OTROS SERVICIOS
tecnología y las configuraciones desarrolla- MIENTEN: LAS FOTOS RETIRADAS
das para este Windows tan particular WIKIPEDIA VS. LA CIENCIOLOGÍA
hayan pasado a nuestros Windows de POR LOS USUARIOS NO SON
escritorio a través de Vista y el futuro El comité directivo que se encarga de ELIMINADAS INMEDIATAMENTE
Windows 7, del que recientemente se ha supervisar los “baneos” de usuarios en la
publicado su primera release candidate. famosa enciclopedia libre ha cortado el Con diversos casos de personas que han
acceso a todas las IP's correspondientes a sufrido las consecuencias de haber colgado
LA SEGURIDAD EN INTERNET computadoras que se sabe son propiedad fotografías online que después las han
VA DE MAL EN PEOR de la Iglesia de la Cienciología, acusando a puesto en situaciones comprometidas, el
esta organización de manipular artículos tema es serio y polémico. Un estudio lleva-
"Hay millones de delitos informáticos que para eliminar las críticas dirigidas contra do a cabo por la Universidad de Cambridge
no se denuncian y los que sí, sólo el 9% ella. Es un episodio más de la larga guerra ha demostrado que la mayoría de los sitios
acaban en detenciones", afirmó la investi- que esta organización religiosa, tolerada en sociales de la Web 2.0 tardan demasiado en
gadora Erin Kenneally en la reunión anual algunos países y prohibida en otros, eliminar las imágenes o nunca lo hacen,
del Anti Phishing Working Group (APWG), mantiene en la Red de redes con sus pese a honrosas excepciones.
celebrada en Barcelona. Y eso no es nada detractores. La prueba fue fácil: crear un perfil en cada
según el asesor de las Naciones Unidas, uno de los servicios online sociales más
Raoul Chiesa: "Por suerte los terroristas aún populares de la Web (16 en total), publicar
no saben atacar las infraestructuras críti- imágenes en ellos, retirarlas y comprobar
cas, que están desprotegidas en todo el cuanto tardaban en desaparecer de forma
mundo". efectiva. Los resultados fueron en algunos
El robo de identidad, sean contraseñas o casos decepcionantes y, en otros, sorpren-
datos bancarios, es la estrella de los fraudes dentes. Facebook y MySpace se encuentran
en Internet que, según la empresa S21sec, entre las redes sociales que más han tarda-
se han doblado en un año. El 62% son do en retirar las fotografías (hasta un mes
casos de "phishing", que se está cebando en después de haberlas eliminado del perfil,
el Sistema de Nombres de Dominio: los cri- aún se podía acceder a ellas), mientras que
minales registran o secuestran dominios y Orkut (propiedad de Google) y Flickr
los dan a ordenadores infectados bajo su (Yahoo!) se contaron entre las más rápidas
control, que actúan como señuelo para que en eliminar de forma efectiva el contenido
los incautos introduzcan datos bancarios. tras la solicitud del usuario de darlo de baja.
Al cambiar velozmente el dominio de una El estudio fue llevado a cabo por cuatro

www.revistasprofesionales.com 5 SOLO PROGRAMADORES nº 172


04-13 Noticias:NOTICIAS 5/6/09 11:00 Página 6

NOTICIAS

balón de oxígeno en este terreno y en el de cebidos como un proceso de información


la publicidad en línea), la multinacional que devuelve un resultado determinado
norteamericana parece decidida a cabalgar después de procesar unos datos determina-
en solitario contra la compañía del célebre dos, las patentes pueden afectar al modo
buscador. Para ello, y tras la reforma de sus en que el programa lee la entrada de datos,
servicios Live, ahora asalta el campo de las como los procesas o como produce los
investigadores de la Universidad de búsquedas. resultados.
Cambridge (Inglaterra), dando de alta perfi- Durante las últimas semanas se especuló - Si el software está concebido como una
les en 16 de los sitios web sociales más sobre el nombre del futuro buscador, si descripción formal de un algoritmo, escrito
populares, cargando una imagen en ellos, sería Kumo o Bing. Ha ganado esta última en una forma ejecutable, cualquier parte
apuntando la URL de acceso, y dándola de opción, parece ser porque diversos domi- del algoritmo puede ser patentable.
baja. Una vez realizado este proceso, y nios (sobretodo nacionales) que incluían la Patentes o copyright
durante un periodo de 30 días, fueron con- palabra Kumo se le han escapado a Los programas de ordenador, el software,
trolando si era posible acceder a la imagen Microsoft, además que esta ya estaba han venido tradicionalmente siendo prote-
a través de la dirección anotada. registrada en algunos países. gidos por la legislación de Propiedad
Los casos más flagrantes son los de Bing intenta ir un paso más allá de la expe- Intelectual, el copyright o derechos de
Facebook y MySpace, ya que un mes des- riencia de usuario que ofrece Google, inte- autor. Esta legislación otorga derechos
pués de retirar la imagen del perfil, ésta aún grando mayor cantidad de información en exclusivos de comercialización al autor de
era accesible a través de la URL directa. los resultados de las búsquedas, como imá- un programa y consecuentemente prohíbe
Pese a que inicialmente puede parecer difí- genes o compra de productos (lo que en la copia, la distribución o modificación sin
cil encontrar dicha URL, existen trucos para Europa se llevará a cabo mediante un el debido permiso.
llegar a acceder a las fotografías privadas acuerdo con el portal Ciao). Con ello se per- En consecuencia, para tener derechos en un
de un perfil o, incluso, conocer las URLs de sigue proporcionar al usuario una herra- programa, es necesario y es suficiente ser el
las imágenes individuales. Este pasado mienta para tomar decisiones más que creador, en otras palabras, probando la
febrero, uno de estos trucos facilitó el acce- solamente para buscar información. autoría de un programa es suficiente para
so a fotografías privadas de la siempre asegurar que el autor tiene todos los dere-
polémica Paris Hilton e incluso del creador DECLARACIÓN DE ATI SOBRE LAS chos en un programa.
de Facebook, Mark Zuckerberg. PATENTES DE SOFTWARE Las patentes operan de una manera muy
diferente. Primero el titular de la patente no
MICROSOFT PLANTARÁ CARA A Con motivo de la campaña que la Oficina necesita desarrollar un programa de orde-
GOOGLE EN LAS BÚSQUEDAS CON Europea de Patentes (EPO) está llevando a nador para demostrar su funcionalidad.
cabo con el fin de lograr que las patentes Segundo, el autor que escribe un programa
BING de software sean aprobadas por la Unión puede perfectamente utilizar un elemento
Europea de la cual no forma parte, la ya patentado sin saberlo, simplemente
Después de algunos cambios en su nombre, Asociación de Técnicos de Informática, ATI, “reinventando” el concepto él mismo. En
la compañía de Redmond empieza a gene- continuando en su posición estratégica términos simplistas, la legislación del copy-
rar expectación alrededor de su nuevo bus- contraria a este tipo de patentes ha formu- right protege al creador de un programa,
cador, con el que intentará competir con la lado ante la EPO su declaración de posición. mientras que la legislación de patentes
todopoderosa Google. Aprovecho también El término “patente de software”, aunque otorga derechos a las personas que descri-
para matizar las últimas informaciones muy popular, es considerado por algunos ben las técnicas que pueden utilizar los
aparecidas en este mismo rotativo sobre el legisladores como no riguroso y en conse- programas.
posible uso de GNU/Linux en su operativa cuencia, se utilizan otros términos tales Este mecanismo diferente de protección es
La compañía de Steve Ballmer ha hecho como “patentes de invenciones implemen- también destacable porque el software es
público finalmente su próximo desafío a tadas mediante ordenador”. En la presente uno de los campos en que las patentes
Google en el mundo de las búsquedas onli- declaración al mencionar “patentes de soft- intentan proteger un elemento del progra-
ne. Después de fracasar el intento de absor- ware” nos referimos a aquellas patentes ma de ordenador que ya se encuentra pro-
ción de Yahoo! (que le hubiera dado un que pueden afectar a la comercialización de tegido específicamente por otra legislación.
un programa de ordenador, en otras pala-
bras, “patentes de software” son aquellas EL NUEVO BUSCADOR DE MICROSOFT
patentes que se utilizan para reclamar FUNCIONA ¡SOBRE LINUX!
derechos frente a terceros debido a la pro-
ducción, distribución o uso de programas Buscando información sobre la nueva
de ordenador. herramienta de búsqueda de la multinacio-
Con esta definición las patentes de softwa- nal de Redmond, un blogger se ha topado
re pueden afectar a: con que el dominio Kumo.com se encuen-
1.- Un servicio facilitado por un programa tra hospedado en servidores que utilizan
de ordenador. En esta categoría incluimos GNU/Linux
los modelos de negocio soportados por un La noticia no debería tener especial trans-
software determinado. cendencia, pues Microsoft puede haber
2.- Funcionalidades internas de un softwa- subcontratado su desarrollo a una empresa
re. Tomemos una doble visión, dependiendo externa, ni que sea en parte, y que esta tra-
del concepto de software que apliquemos: baje sobre el sistema operativo del pingüi-
- Si los programas de ordenador están con- no, o bien que lo aloje en un ISP que tam-

SOLO PROGRAMADORES nº 172 6 www.revistasprofesionales.com


04-13 Noticias:NOTICIAS 5/6/09 11:01 Página 7

Sólo Programadores
en Formato
Digital
Por mucho menos dinero
Llegará antes a su ordenador que a los quioscos
Suscríbase en www.revistasprofesionales.com

Suscripción a Sólo Programadores (12 números) por sólo 32 euros


Suscripción a Sólo Programadores (12 números) + Mundo Linux (6 números) por sólo 36 euros
04-13 Noticias:NOTICIAS 5/6/09 11:02 Página 8

NOTICIAS

bién trabaje con Linux, pero sin lugar a arquitectura x86; se trata de un Xcore86 de adquirir un paquete de pilas (dos en caso
dudas la guerra que se mantiene entre los bajo voltaje que funciona a 1 GHz. y no que sean de cuatro unidades), abrir la com-
creadores de Windows y la comunidad del necesita ventilador para disipar el calor putadora, instalarlas... ¡y empezar a utilizar-
software libre hacen que cualquier peque- generado, lo que permite reducir el consu- lo nuevamente!
ña noticia de este tipo adquiera un carácter mo eléctrico de la máquina a la vez que se Los amantes de realizar pruebas y experi-
marcadamente importante. disminuye su volumen y se eliminan ruidos. mentos pueden aprovechar la tarjeta SD
Algo parecido sucedió hace tiempo cuando Su precio también se ve disminuido gracias que utiliza como medio de almacenamien-
salió a la luz que Hotmail utilizaba también al uso de estos componentes, y pese a que to para tener diversas tarjetas, cada una de
servidores Linux, aunque debe tenerse en aún no ha salido al mercado, en su sitio ellas con un sistema operativo diferente. Y
cuenta que esta empresa fue adquirida por web podemos leer que rondará los 200 los distribuidores y vendedores pueden
Microsoft, con lo que la entonces compañía dólares en su configuración más básica. adaptarlo exactamente a las necesidades
de Bill Gates debió manejar una situación Para la unidad de almacenamiento, el que tenga su cliente.
heredada de antemano. Y no resulta tan Gecko EduBook puede funcionar con un Las operadoras de telecomunicaciones
fácil migrar los servidores de un servicio disco duro de 2,5” estándar o con una uni- también pueden venderlo configurado con
con tantos usuarios y datos almacenados. dad SSD. Incluso podemos reciclar viejas módulos WiMAX o 3G a su conveniencia,
No obstante, es de destacar que solamente unidades de almacenamiento para utilizar- sin hablar de aplicaciones empotradas y
por pundonor y por imagen, Microsoft las con él. usos muy concretos que le queramos dar.
debería poner su nuevo motor de búsque- Dispone de un puerto USB interno (además El único handicap que va a tener es el
das online en funcionamiento sobre sus de tres externos), lo que permite conectar microprocesador, del que sin lugar a dudas
propios servidores, ya que si utiliza los de la un módulo WiFi, WiMAX o 3G sin excesivos muchos potenciales clientes no se van a
competencia directa y, se presupone que problemas. También en el interior, y una vez fiar al no ser un Intel Atom u otra marca
toda empresa busca lo mejor, deberíamos retirada la tapa inferior, disponemos de un conocida. También al ser de un fabricante
entender que tal vez Microsoft no confíe en slot para memorias SD (al igual que un slot pequeño y desconocido, esto probablemen-
su propio producto... externo), el cual podemos utilizar como te disuadirá a muchos potenciales compra-
almacenamiento de bajo coste o, incluso, dores.
EL NETBOOK MÁS VERSÁTIL DEL para tener diversas tarjetas con diferentes
MUNDO FUNCIONA CON PILAS sistemas operativos instalados. MICROSOFT LANZA EL SP2
Esta máquina puede funcionar con PARA WINDOWS VISTA... SIN DECIR
El NorhTec Gecko EduBook presenta una Windows XP, aunque según reza en su
estructura modular fácilmente ampliable y página web, viene con Ubuntu Netbook NADA
adaptable a la funcionalidad concreta que Remix preinstalada y puede funcionar con
se le quiera dar, se basa en un procesador cualquier distribución de GNU/Linux (y es La nula publicidad que ha dado la compa-
compatible x86 y utiliza ocho pilas AA de suponer que con cualquier otro sistema ñía de Redmond al lanzamiento deja bien
recargables como batería, lo que le da la operativo que funcione sobre procesadores patente el futuro que le espera a esta ver-
posibilidad de ser utilizado incluso cuando x86 como OpenSolaris). sión de su sistema operativo, que ha repre-
se nos acaba la carga, comprando pilas en sentado junto a Windows ME uno de sus
cualquier comercio. Una oferta muy intere sante grandes fiascos comerciales y de crítica.
Rompe esquemas en diversos puntos, Solamente por el uso de pilas estándar Si habitualmente las grandes compañías
empezando por la batería: tal y como afir- como batería, esta máquina ya se presenta de informática en general y Microsoft en
man desde este fabricante de hardware tai- como una opción muy suculenta. particular nos tienen acostumbrados a
landés, no emplea ninguna batería propie- Imaginemos la siguiente situación: de viaje, espectaculares lanzamientos de sus princi-
taria, sino que echa mano de pilas estánda- se nos acaba la batería de nuestro netbook pales productos y las posteriores actualiza-
res de formato AA, recargables. y nadie es tan amable como para permitir- ciones, la compañía de Steve Ballmer ha
Dependiendo del tipo de pilas, la autonomía nos acceder a un enchufe. Si realmente hecho todo lo contrario con el Service Pack
de la máquina oscila entre las cuatro y las necesitamos utilizar nuestra máquina, 2 para Windows Vista, cuyo desarrollo ter-
seis horas (dependiendo de si se utilizan podemos entrar en cualquier tienda y minó a finales del pasado mes de abril con
pilas basadas en Níquel o en Litio). la versión RTM (Release To Manufacture) y
NorhTec, la compañía madre que ha des- cuya versión final vio la luz el 26 de mayo.
arrollado y fabrica esta computadora (que Ni la página inicial del sitio web de la com-
no se encuentra todavía en el mercado), ha pañía ha reflejado la novedad, ni se ha
previsto el Gecko EduBook como una podido encontrar una nota de prensa al
máquina altamente flexible y adaptable a respecto, por lo menos en las primeras
casi cualquier necesidad imaginable: el horas de disponibilidad del producto.
microprocesador y la memoria RAM se Con la publicidad que se le está dando a
encuentran en módulos independientes y Windows 7, la próxima iteración de la pla-
actualizables, de forma que puede ampliar- taforma de Microsoft, y la buena acepta-
se en cualquier momento según se necesi- ción y críticas de las que está disfrutando,
te, reutilizando la CPU y memoria RAM en esta es la puntilla que marca el próximo
otras máquinas del mismo tipo. punto y final de Windows Vista, un sistema
El microprocesador no es un Intel Atom o que seguirá recibiendo soporte técnico por
un VIA, ni siquiera un AMD, sino que se parte de la multinacional norteamericana
corresponde con una marca mucho menos siguiendo los plazos fijados pero que,
conocida, aunque es compatible con la obviamente, no va a disfrutar de prórrogas

SOLO PROGRAMADORES nº 172 8 www.revistasprofesionales.com


04-13 Noticias:NOTICIAS 5/6/09 11:02 Página 9

NOTICIAS

a los microchips VIA Nano. Por la definición, como proyectos que empiezan y empresas
estos serían los candidatos ideales a equi- que prevén una expansión y crecimiento
par máquinas del tipo netbook o MID, constante.
pequeñas y que necesitan de componentes También es un producto orientado a com-
que pese a ser poco potentes, tampoco ele- petir en un segmento de clientes que habi-
ven el precio ni el tamaño del aparato. Y así tualmente apuestan por servidores en for-
los concibió VIA pero sin desmerecer sus mato torre, menos ampliables o, como
capacidades para tareas “superiores”. Y de mínimo, ampliables de forma menos
esta forma lo ha entendido Dell, que ha cómoda.
presentado la nueva serie de servidores El precio de cada uno de los módulos (que
XS11-VX8, más conocidos por su sobre- recordemos, constituyen un servidor por si
nombre “Fortuna”, que los emplean como solos) estará acorde con la filosofía mini-
procesadores centrales. malista, ya que rondará los 400 dólares, por
en su ciclo de vida como ha tenido Estos no son servidores para lo que para una empresa que empiece
Windows XP, sin lugar a dudas el sistema competir directamente su actividad y tenga previsto crecer,
más exitoso de la compañía. La misma con las grandes máqui- supondrá una inversión inicial baja
Microsoft se contradice con sus acciones, nas de los centros de que podrá ir creciendo según sus
pues pese a admitir algunos errores con proceso de datos necesidades y recursos económi-
Vista y que no ha sido tan exitoso como el (para los que la cos disponibles. A esto, debere-
resto de versiones, no ha llegado a admitir misma compañía ya mos añadirle el coste del basti-
nunca abiertamente que haya sido un fra- tiene las potentes dor.
caso y, en cambio, el trato que le da (al sis- series PowerEdge), sino El movimiento de Dell abre todo
tema y a sus usuarios) es de segunda fila, para empresas que nece- un campo de posibilidades, espe-
según podemos ver. sitan mantener sus propios cialmente a Intel para su arquitectu-
Técnicamente, Windows Vista SP 2 no servidores, que no requieran de ra Atom, hasta la fecha inédita en otro
aporta grandes novedades: incluye una potencia desmedida ni de unas campo que no sean los netbooks y UMPC's.
Windows Search 4.0 (la herramienta de infraestructuras costosas para mantener- ¿Tardaremos mucho en ver un servidor
búsqueda desktop), un asistente para la los. modular basado en estos microchips? ¿y
conexión rápida y simple a redes WiFi Los VIA Nano utilizados por Dell son proce- quién será la afortunada que los lance en
(WCN, Windows Connect Now), soporte sadores de 64 bits construidos empleando primer lugar? ¿HP? ¿IBM? Personalmente
para CPU's VIA de 64 bits, y mejora la ges- tecnología de 65 nanometros, cuyo consu- apuesto por Hewlett-Packard.
tión de la energía hasta en un 10%, sin mo energético oscila entre los 20 y los 29
lugar a dudas algo muy útil en los portáti- vatios a pleno rendimiento, y unos 15 PUBLICADO CHROME 2...
les. También se ha añadido soporte para cuando no mantiene carga de trabajo. PERO SÓLO PARA WINDOWS
Bluetooth 2.1 y se han adjuntado parches Cuentan también con extensiones de vir-
que corrigen diversos bugs. tualización, algo ya imprescindible en cual- Mayor rapidez para la nueva versión de un
La descarga de este Service Pack puede ser quier servidor moderno que se precie, pues programa que progresa de forma inusita-
realizada mediante la herramienta de todos los sistemas operativos líderes en damente rápida respecto a otros desarro-
actualización del sistema operativo, o bien este campo cuentan con sus funcionalida- llos de Google. Los “maqueros” y “linuxeros”
descargándolo manualmente desde el sitio des de virtualización, ya sean nativas o pro- aún no ven en el horizonte una versión
web de Microsoft. En caso de haber instala- porcionadas por software de terceras par- final para sus respectivas plataformas.
do alguna versión previa de este mismo tes. Las velocidades a las que pueden fun- Con aún muy poca vida a sus espaldas, el
paquete, esta deberá ser desinstalada pre- cionar estos chips varían entre 1 y 1,8 GHz. navegador web Google Chrome ha llegado
viamente. El formato en el que se presenta uno de a su versión 2.0, un proceso de madurez
Paralelamente al Service Pack 2 de estos servidores no es mucho más grande inusitadamente rápido que se contradice
Windows Vista, también se ha lanzado el que un disco duro. Las imágenes que ha con la habitual filosofía de “beta continua”
SP2 para Windows 2008. El binario de ins- publicado Dell son, de hecho, una infraes- de los productos de la multinacional del
talación es el mismo, demostrando así que tructura muy modular, disponiendo cada buscador. Esta veloz progresión es probable
ambas ramas del sistema operativo com- uno de los módulos de los recursos sufi- que se deba a la necesidad estratégica de la
parten la mayor parte del código fuente. cientes para actuar en solitario (memoria compañía de contar con una opción de
RAM, conexión de red, microprocesador, mercado fuerte, potente, y probablemente
DELL PODRÍA REVOLUCIONAR almacenamiento). Estos módulos se enca- un paso más en el asalto de la compañía a
EL MUNDO DE LOS SERVIDORES denan montándolos en un chasis que faci- los sistemas operativos de escritorio.
lita su interconexión. De hecho, Chrome también se encuentra en
GRACIAS A LOS CHIPS VIA NANO La conexión de un nuevo módulo en un un desarrollo continuado en el seno de
rack preexistente puede realizarse en Chromium, un proyecto de código abierto
La compañía norteamericana ha presenta- caliente (hot plug), lo que significa que el que recopila el código donado por progra-
do una arquitectura altamente modular y servidor puede ampliarse sin tener que madores independientes y contribuidores y
de gran eficiencia energética, basada en la pararlo. se ocupa de compilar las betas intermedias
plataforma del fabricante taiwanés, inicial- El target de este tipo de servidores son, entre versiones. Así que esta versión 2.0
mente destinada al segmento de los netbo- como he dejado a entrever anteriormente, estable ha sido el producto de compilar los
oks. Pequeños, baratos y con un bajo con- compañías que no requieren de un servidor últimos avances producto de diversas betas
sumo, así podemos definir de forma rápida exageradamente potente pero si escalable, previas.

www.revistasprofesionales.com 9 SOLO PROGRAMADORES nº 172


04-13 Noticias:NOTICIAS 5/6/09 11:02 Página 10

NOTICIAS

En esta versión 2.0 de Chrome nos microchip moderno y que se dedica en


encontramos con un navegador más cuerpo y alma a la producción de diversas
rápido, hasta un 30% según Google. El soluciones de hardware junto a los micro-
motor de procesamiento de JavaScript, procesadores, como por ejemplo chipsets,
conocido como V8 en honor a un motor módulos de conexión WiFi, WiMAX o tar-
de coches de origen norteamericano - jetas gráficas. No obstante, esto no ha sido
también utilizado para aviones-, ha sido óbice para que la multinacional california-
más optimizado aún para obtener el na haya hecho sus “pinitos” en dicho sec-
máximo rendimiento cuando se accede a tor, habitualmente con herramientas vin-
las modernas aplicaciones online, como culadas directamente con el hardware.
el gestor de correo Gmail o Google Docs. Moblin es un cambio al respecto.
Otras novedades que nos trae Chrome 2.0 Moblin es una distribución GNU/Linux
son el autorellenado de formularios, un basada en Fedora e impulsada por Intel Imaginemos una Intel persiguiendo acuer-
modo de pantalla completa y la posibili- para su arquitectura Atom. Está optimiza- dos con los fabricantes que integran sus
dad de eliminar miniaturas de las páginas da para un rápido arranque y un funcio- procesadores para que utilicen Moblin en
visitadas en la pestaña inicial. Esta última namiento y rendimiento óptimos en sus netbooks. Sin dudas, esta distribución
funcionalidad podría haber sido añadida máquinas con un hardware poco potente, conseguiría un hueco importante entre los
en gran medida debido a las críticas por propio de netbooks y MIDs (Mobile netbooks con Linux, y sería incluso capaz
parte de internautas que han visitado Internet Device). La última versión dispo- de robarle una parte significativa del pas-
páginas con contenidos “delicados” para nible es la 2.0 beta. tel a Windows en dicho segmento. Algo
que los vean otros usuarios de la misma El principal cambio en la distribución se ve por lo que Microsoft tal vez no debe preo-
máquina (léase pornografía en la mayoría en su aspecto. La interfaz gráfica ha sido cuparse, pero que sin lugar a dudas le
de los casos), y que hasta ahora no tení- trabajada para asemejarse mucho más a sería molesto.
an forma de esconder sus visitas inconfe- aquella clásica de un netbook y no tanto a Por su parte, a Intel le interesa no depen-
sables. un escritorio tradicional como el que nos der de la compañía capitaneada por Steve
Chrome 2.0 ya puede ser descargado podemos encontrar en una máquina de Ballmer, continuar siendo la plataforma
desde su sitio web, y aquellos usuarios sobremesa. Así, se asemeja mucho más a hardware de referencia sea cual sea el sis-
que ya lo tengan instalado en su compu- una Ubuntu Netbook Remix, por poner un tema operativo utilizado. Su verdadero
tadora recibirán la actualización directa. ejemplo, que a un Windows XP. Una barra rival aquí podrían ser los netbooks basa-
Pese a que Chrome para Windows ha lle- de tareas situada en la parte superior del dos en chips ARM con Android, que han
gado a su versión 2.0, pocas noticias se escritorio nos despliega hojas con las dife- empezado a hacer su aparición tímida-
tienen aún de las esperadas versiones rentes aplicaciones a las que podemos mente en el mercado y de los cuales se
para GNU/Linux y Mac OS X con excep- acceder o acciones para llevar a cabo. espera un desembarco mucho más masivo
ción de algunos apuntes que indican que Desde esta barra de tareas, y cada vez que en fechas próximas.
su progresión continúa a buen ritmo en entramos en una sección que agrupa dife- Con Moblin, la multinacional californiana
el marco del proyecto Chromium, y pese rentes opciones relacionadas, estas se nos perseguiría ofrecer una alternativa de bajo
a que la compañía -por varias voces presentan en forma de paneles, siendo de coste a estos portátiles (ahorrando el
autorizadas- insistió que desde la salida a esperar que más adelante se vayan publi- importe de la licencia de Windows) para
la luz de las primeras versiones para cando plug-ins que añadan nuevos pane- ocupar su nicho de mercado y asfixiar su
Windows, no pasaría mucho tiempo para les y, por lo tanto, funcionalidades al sis- comercialización. Por lo menos, este es mi
que los “maqueros” y “linuxeros” pudie- tema. El cometido de la distribución se ha punto de vista.
ran disfrutar de una versión nativa de orientado a la reproducción de contenidos ¿Y Microsoft? va a hacer la vista gorda. Le
Chrome para sus respectivos sistemas digitales audiovisuales, la navegación por interesa, pues por el momento no va a
operativos. Internet y el uso de redes sociales y servi- adaptar su Windows a la arquitectura
cios 2.0 principalmente. ARM, con lo que esta maniobra junto al
¿HARÁ INTEL LA COMPETENCIA Promover esta distribución como sistema bloqueo que Intel va a llevar a cabo res-
AL WINDOWS DE MICROSOFT? operativo llevaría a Intel a un enfrenta- pecto a ARM, va a dejar el mercado de los
miento con Microsoft, que domina ya el netbooks más o menos tal y como está
El fabricante de microchips está generan- segmento de los netbooks gracias a haber ahora mismo.
do mucho interés sobre su distribución permitido a los fabricantes e integradores
GNU/Linux optimizada para la plataforma la adquisición y uso de licencias de CISCO PREPARA LAS REDES
Atom y máquinas de tipo netbook o Windows XP, un sistema operativo teóri- INALÁMBRICAS DEL FUTURO
UMPC, de la cual se ha presentado recien- camente descatalogado para las máquinas
temente la beta de la versión 2.0, con una de escritorio pero que debido a las insufi- CON AIRONET 1140
nueva interfaz de usuario que incide en la ciencias de Vista, aún triunfa en ellas y es
facilidad de uso y la reproducción de muy buscado por los usuarios. Con un Con la integración de la tecnología M-
medios digitales. Un proyecto conjunto Windows 7 próximo a estrenarse y que Drive, el nuevo punto de acceso responde
con Nokia también apunta a ciertas posi- dispondrá de versiones optimizadas para a las necesidades actuales de movilidad y
bilidades en el campo de los sistemas ope- netbooks, la compañía de Redmond pare- colaboración.
rativos basados en GNU/Linux. ce tenerlo todo ganado en este segmento Con el objetivo de rentabilizar el uso de
El campo del software nunca ha sido un de máquinas ultraligeras, pese a que éste todos los dispositivos y aplicaciones móvi-
punto fuerte de Intel, evidentemente sien- es aún lo suficientemente joven para ser les que se utilizan en el entorno empresa-
do la empresa que creó el concepto de permeable a cambios. rial, Cisco ha anunciado la comercializa-

SOLO PROGRAMADORES nº 172 10 www.revistasprofesionales.com


04-13 Noticias:NOTICIAS 5/6/09 11:02 Página 11
04-13 Noticias:NOTICIAS 5/6/09 11:02 Página 12

NOTICIAS

(RF) fiable y homogénea para que las máquinas, optimizarlas para el máximo
empresas puedan ampliar su cobertura y rendimiento con él, y desarrollar nuevos
mejoren así su capacidad inalámbrica. drivers para que el hardware existente
La tecnología M-Drive de Cisco incluye funcione bien y el nuevo que será lanzado
además la función ClientLink, que ayuda a en el futuro sea compatible.
prolongar la duración de los dispositivos La llegada de la RTM de Windows 7 se
802.11a/g, mejorando el rendimiento de hará a tiempo para que los fabricantes
los nuevos 802.11n. De hecho, según el tengan listas sus nuevas computadoras
laboratorio independiente Miercom, la para la campaña navideña preparadas con
ción del Aironet 1140, el primer punto de función ClientLink incrementa hasta el Windows 7, especialmente en lo que res-
acceso inalámbrico que combina todas las 65% la velocidad de los dispositivos pecta a los netbooks, de los que se prevé
prestaciones del protocolo 802.11n con 802.11a/g actuales conectados a una red que serán nuevamente una de las estrellas
una fácil instalación. Cisco 802.11n. Además, al aumentar la de la campaña -aunque probablemente
En un momento en el que la movilidad de velocidad de los clientes 802.11a/g, sin llegar a las altísimas cotas que consi-
los trabajadores es cada vez más impor- ClientLink incrementa eficazmente la guieron estas pasadas navidades-.
tante y en el que se precisan de soluciones capacidad total del canal disponible hasta El lanzamiento de Windows 7 debe consi-
colaborativas para alcanzar las mayores el 27% y puede ayudar a optimizar el ren- derarse estratégico para Microsoft, des-
cotas de productividad dentro de la dimiento de los dispositivos 802.11n y pués de que Windows Vista se haya con-
empresa, el nuevo punto de acceso Cisco 802.11a/g. vertido en un fracaso de crítica y comer-
Aironet 1140 ha sido diseñado para inte- cial en ventas OEM comparable al que
grar voz, vídeo y dispositivos móviles CONFIRMADO: WINDOWS 7 supuso en su momento Windows
802.11n en las redes inalámbricas, con un PARA NAVIDADES Millenium. Pasar otra campaña navideña
rendimiento y una velocidad nueve veces con Vista podría significar para la compa-
superior a las redes inalámbricas Un post en uno de los blogs oficiales de ñía de Redmond perder ventas en favor de
802.11a/g anteriores. Asimismo, Cisco Windows 7 alojados por la red MSDN, GNU/Linux, especialmente en las máqui-
Aironet 1140 se completa con el estándar indica que la RTM del nuevo sistema esta- nas de bajo coste.
Power over Ethernet (PoE), que proporcio- ría lista en agosto y, por lo tanto, la ver- En el terreno de los netbooks, un Vista
na un ahorro considerable en gastos y sión final podría ser instalada en máqui- demasiado “pesado” y lento para estos
mantenimiento, ya que evita la necesidad nas por navidades. pequeños aparatos podría ser el que más
de alimentar independientemente el punto Microsoft ha revelado un nuevo dato que sufriese la pérdida de cuota de mercado,
de acceso. apunta a que el sucesor de Windows Vista canibalizado por su propio antecesor
La compañía, que ya en 2007 anunció la estará al alcance de los consumidores Windows XP, con el que los chicos de
primera plataforma homologada 802.11n para la campaña navideña. Con esto, la Steve Ballmer parecen incapaces de cortar
para empresas, comercializa ahora nuevas compañía de Redmond persigue borrar lo lazos debido a esta incapacidad de su
soluciones basadas en dicho estándar que más rápidamente posible el fiasco que ha sucesor para funcionar medianamente
ofrecen facilidad de uso e instalación, fia- supuesto Windows Vista a nivel comer- bien en los ultraportátiles más pequeños.
bilidad y rendimiento. Para conocer el cial. Con un Windows 7 optimizado para esta
catálogo de productos de Cisco para el La revelación se ha producido a través de categoría de máquinas, Microsoft podría
estándar 802.11n, se puede visitar el vídeo un post del blog Engineering Windows 7, permitirse dejar de proporcionar licencias
de Ben Bibson, director sénior para solu- oficial de la compañía de Redmond y alo- de XP a los fabricantes de netbooks,
ciones de movilidad de Cisco. jado en los servidores de MSND. En dicho pasando página definitivamente por lo
Entre los beneficios del nuevo Aironet post se analizan las distintas etapas por que se refiere a este sistema operativo.
1140 destacan un incremento significativo las que está pasando y va a pasar el futu- También hay que tener en cuenta la
de la velocidad de los dispositivos ro sistema de Microsoft, y se afirma que la entrada en escena de los netbooks basa-
802.11a/g; un aumento en la capacidad versión RTM del sistema (Release to dos en chips ARM equipados con Ubuntu
general de los canales inalámbricos; y una Manufacturing, es decir, preparada para y Android, cuyo rendimiento comercial es
reducción de los huecos de cobertura enviar a fabricantes e integradores) esta- toda una incógnita pero que están levan-
inalámbrica de dispositivos anteriores. rá lista para agosto. Esto significa que, tando mucha expectación en los medios
Ecológico e innovador entre agosto y octubre/noviembre, los especializados y la audiencia profesional.
Cisco Aironet 1140 cuenta, además, con un fabricantes e integradores podrán experi- Si no se llegase a tiempo para la campaña
diseño innovador y elegante, que favorece mentar con este sistema, probar sus navideña de este año, un retraso signifi-
la reducción de gastos y la eficiencia ener- caría perder una gran cantidad de ventas
gética. El Aironet 1140 será distribuido en y, sensiblemente, cuota de mercado, por
un paquete ecológico, que agrupa 10 pun- lo que podemos tener por seguro que la
tos de acceso, que reduce el embalaje en multinacional de Redmond hará lo impo-
un 50% y facilita el desembalado, la sible para que Windows 7 esté listo para
ampliación y su instalación en las organi- estas fechas. Le queda muy poco, pues la
zaciones. existencia de la versión Release Candidate
Mejora del rendimiento con la tecnología indica que ya buena parte del trabajo está
M-Drive hecho.
Por otro lado, Cisco ha integrado en el
Aironet 1140 la tecnología M-Drive, que Por: Guillem Alsina (guillem@imatica.org)
crea una plataforma de radiofrecuencia

SOLO PROGRAMADORES nº 172 12 www.revistasprofesionales.com


04-13 Noticias:NOTICIAS 5/6/09 11:02 Página 13

Suscripción a Sólo Programadores


Opción A: Suscripción anual con 25% descuento:  Transferencia al Banco Popular:
SUSCRIPCIÓN PARA ESPAÑA FORMAS DE PAGO PARA ESPAÑA

54 euros* (3 revistas gratis, 18 euros de ahorro) c.c:0075/1040/43/0600047439


Opción B: Suscripción anual con 15% descuento:  Talón Bancario a nombre de Revistas Profesionales
61,20 euros* (tapas de regalo, 10,80 euros de ahorro)  Domiciliación Bancaria
*10 euros de gastos de envío para la opción contrareembolso  Tarjeta de Crédito

Opción C: Suscripción anual con 25% descuento


SUSCRIPCIÓN PARA EXTRANJERO
 Tarjeta de crédito
FORMA DE PAGO EXTRANJERO:
Europa: 78 euros (gastos de envío incluidos)
Opción D: Suscripción anual con 25% descuento
Resto de paises: 102 euros (gastos de envío incluidos)

Suscríbase en www.revistasprofesionales.com Más información en el teléfono 91 304 87 64,


en el fax 91 327 13 07 y en rpsuscripciones@revistasprofesionales.com
Javahispano:Javahispano 5/6/09 11:05 Página 14

JAVAHISPANO

Actualidad Java de la mano


de javaHispano
El popular servidor web Jetty pasa a ser un proyecto de EclipseRT

Jetty, el contenedor web Java EE cuya popularidad sólo es sobrepasada por la de Tomcat, está
en la incubadora de proyectos de EclipseRT (Eclipse Runtime Projec). Desde hace tiempo que la
fundación Eclipse y Jetty (proyecto que hasta ahora sólo estaba alojado en Codehaus) estaban
discutiendo sobre la posibilidad de mover Jetty a Eclipse. Uno de los motivos era que el entor-
no de desarrollo está cada vez más integrado con este servidor web. Finalmente, se han deci-
dido a dar este paso.
Jetty, al menos por lo de ahora, también va a seguir alojado en Codehaus, pero el código de
lo que será Jetty 7 ya ha sido movido al paquete org.eclipse.jetty y ya se encuentra en el repo-
sitorio SVN de Eclipse. La anterior licencia del proyecto, Apache 2.0, se va seguir manteniendo.
Pero ahora se va a distribuir bajo una doble licencia, añadiendo la licencia de Eclipse.

Oracle JRockit JVM establece un nuevo récord en el SPECjbb2005 Benchmark

La antigua máquina virtual de BEA Systems (compañía reciente-


mente adquirida por Oracle) que ahora se llama "Oracle JRockit" ha
establecido un nuevo récord en el SPECjbb2005, el benchmark
estándar que se emplea para determinar el rendimiento de las
máquinas virtuales. Para ello han empleado una máquina con 16
procesadores de seis núcleos cada uno de ellos y 256 GB de
memoria RAM corriendo sobre Linux.
El nuevo récord está en 2150260 bops (business operations per
second, la medida de rendimiento empleada por el benchmark).
Este récord duplica al anterior récord, ostentado por la máquina
virtual Hot Sput de Sun, y triplica al mejor resultado obtenido por IBM. La clave para conseguir este récord
ha estado en la capacidad de la máquina virtual para escalar sobre un número muy elevado de núcleos.

Linux ejecutándose dentro de un Applet

JPC (Java PC) es un emulador de un PC x86 con periféricos


virtuales implementado al 100% en Java. JPC permite ins-
talar sobre el emulador cualquier sistema operativo y,
sobre el sistema operativo, aplicaciones. El propósito de
este proyecto es permitir experimentar con virus, código
malicioso, crear honeypots (ordenadores que se conectan
deliberadamente a Internet sin ningún tipo de protección
para que se infecten y estudiar el software maligno que los
ha infectado) o realizar cualquier otra tarea que sería
arriesgado ejecutar directamente sobre un PC. El robusto
modelo de seguridad de Java garantiza que nada afectará
realmente a nuestra máquina.
La última novedad del equipo de físicos que está detrás de
este proyecto es que han construido un Applet 100% Java basado en JPC desde el cual se lanza a una
versión básica de RedHat 9. Por tanto, es posible correr un Linux dentro de un navegador web bajo cual-
quier sistema operativo que tenga una máquina virtual Java disponible. ¡Parece mentira los avances que
se están realizando en temas de virtualización/emulación!

SOLO PROGRAMADORES nº 172 14 www.revistasprofesionales.com


Javahispano:Javahispano 5/6/09 11:06 Página 15

JAVAHISPANO
Actualidad Java de la mano de javaHispano

OPINIÓN
Sobre IBM y la compra
Soporte para Java en Google App Engine

Google App Engine es la solución de cloud compu-


ting de Google. A diferencia de EC2 de Amazon, no
de Sun Microsystems
consiste en proporcionar a los usuarios una CPU vir-
tual donde éstos pueden instalar el sistema operativo El pasado 18 de abril, nos despertamos con una
que quieran, y sobre dicho sistema operativo y las noticia desconcertante en javaHispano: IBM estaba
aplicaciones que deseen. La solución de Google en conversaciones para comprar Sun Microsystems,
proporciona tanto sistema operativo como la empresa detrás de Java, Solaris y MySQL. Lo que
servidor de aplicaciones e incluso framework más llamaba la atención de este movimiento era que
de desarrollo, y el desarrollador sólo tiene que el precio que IBM pagaría se estimaba en $7.500,00
preocuparse de crear la aplicación, no millones de dólares, una verdadera ganga para una
pudiendo modificar ninguna capa del stack.
empresa tan innovadora y protagonista en el mundo
Indudablemente, esta alternativa pierde en flexibili-
dad pero gana en simplicidad. de las TI como lo es Sun.
Hasta hace poco, el único lenguaje de programación que se podía emplear Después de días de rumores sobre si se realizaba o
en Google App Engine era Python. Recientemente, se ha anunciado la disponi- no la adquisición, al final IBM decidió retirarse de las
bilidad de Java, el lenguaje más demandado por la comunidad de usuarios de negociaciones al no concretar un acuerdo por el
Google App Engine. Para ello, Google ha creado un wrapper para las APIs de su precio por acción a pagar. Esto deja a Sun en una
servidor de aplicaciones, de tal modo que éstas presenten a los desarrolladores posición muy vulnerable ya que ahora tendrá que
interfaces equivalentes a Servlet, JDO y JPA, javax.cache, y javax.mail. iniciar negociaciones con otras empresas (se habla
Con este movimiento, Google no sólo se ha abierto la puerta para escribir de HP o Cisco) o continuar como empresa indepen-
aplicaciones en el lenguaje Java, sino en cualquier otro lenguaje soportado diente con la desventaja de que ahora tiene que
en esta plataforma, como Groovy, Scala, o JRuby. Actualmente Google App convencer a sus inversionistas y clientes que a pesar
Engine es completamente gratuito para aquellas aplicaciones que no super-
de que estuvo buscando comprador, puede salir
en los 5 millones de pageviews por mes; a partir de esta carga de tráfico se
paga una tarifa (bastante modesta) en función del uso de CPU y del consu- adelante por sí misma.
mo de ancho de banda.

Liberado Rome 1.0

Recientemente se ha hecho pública la versión 1.0 de Rome, una librería Java


para producir y consumir feeds RSS/Atom. Aunque acabe de lanzar su prime-
ra versión estable, se trata de una librería con ya bastantes años de rodaje
dentro de la plata-
forma Java: lleva
empleándose
desde el 2004 y en
la actualidad se Hasta ahora los inversionistas no han respaldado
puede considerar del todo las decisiones del CEO Jonathan Schwartz
como el estándar quien desde el 2006 ha venido implantando estra-
de facto dentro tegias basadas en publicar los productos insignia de
del mundo Java la empresa como proyectos de código libre (es el
para producir y caso de OpenJava y OpenSolaris); por ello es muy
consumir feeds probable que estos accionistas apoyen la línea de
RSS/Atom. buscar otra empresa compradora. En este contexto
La librería destaca lo que esperamos los desarrolladores Java es que
por su gran senci-
quien sea quien adquiera a Sun, no deje de lado la
llez de uso, pre-
sentando una API plataforma Java y continúe con la línea de innova-
sencilla, pequeña e intuitiva; pero sin por ello causar una pérdida de flexibili- ción y renovación del lenguaje que ha marcado la
dad en las aplicaciones que la manejen. Es un claro ejemplo de un problema etapa de Schwartz.
bien resuelto. La licencia de Rome es Apache 2.0, por lo que puede emplearse
en proyectos comerciales sin ningún problema. Erick Camacho (ecamacho@javahispano.org),
miembro de javaHispano

Sobre el autor
Abraham Otero (abraham.otero@javahispano.org) es responsable de calidad y miembro de la junta de javaHispano.

www.revistasprofesionales.com 15 SOLO PROGRAMADORES nº 172


oracle:Portales Vocales 5/6/09 11:09 Página 16

BASES DE DATOS

Arquitectura de Oracle

DAVID ROLDÁN MARTÍNEZ
Los procesos relacionados con el usuario.

Dr. Ingeniero en Telecomunicación, Analista-Programador
del ASIC de la Universidad Politécnica de Valencia La instancia de Oracle.
 La base de datos.
En este artículo, el primero de una Por cada instancia de Oracle se tiene una sola
serie sobre la base de datos Oracle base de datos. En un servidor se pueden crear
(http://www.oracle.com), se estudiará varias instancias, pero se recomienda solo una
porque cada instancia consume muchos recur-
con cierto nivel de detalle la sos.
arquitectura de este sistema de
gestión de base de datos. Para seguir Procesos de usuario
este artículo y el resto de la serie, se A nivel de usuario, existen dos procesos que per-
recomienda instalarse la Express miten al usuario final interactuar con la instan-
Edition de Oracle, disponible en cia, y en último punto, con la base de datos y son
el proceso de usuario y el proceso servidor.
http://www.oracle.com/technology/pr Dependiendo de la arquitectura técnica de la
oducts/database/xe/index.html. aplicación, el Proceso de Usuario corre en el pro-
Queda fuera del ámbito de este pio PC del usuario o en algún servidor de capa
intermedia. Cuando un usuario ejecuta una apli-
artículo ofrecer la instalación y el cación, Oracle inicia un Proceso de Usuario que
manejo básico de esta herramienta, soporta la conexión del usuario con la instancia.
ya que en la web de Oracle existe El proceso de iniciar y mantener una comunica-
ción entre el Proceso de Usuario y la instancia de
suficiente documentación al respecto. Oracle, recibe el nombre de conexión. Una vez
que ha conexión se ha creado con éxito, el usua-
Introducción rio establece una sesión con la instancia sobre
dicha conexión.
La arquitecutra del servidor de base de datos Puesto que los procesos de usuario no se pueden
Oracle se divide en tres componentes básicos: comunicar directamente con la base de datos,
tras establecer una sesión, cada usuario arranca
un Proceso Servidor en el propio servidor, que
será el responsable de realizar aquellas tareas
que permiten al usuario interactuar con la base
de datos.

Figura 1. Arquitectura del servidor de base de Figura 2. Relación entre los procesos de usuario
datos Oracle. y el resto de componentes de Oracle.

SOLO PROGRAMADORES nº 172 16 www.revistasprofesionales.com


oracle:Portales Vocales 5/6/09 11:09 Página 17

BASES DE DATOS
Arquitectura de Oracle

Además de los procesos asociados a cada El tamaño de las estructuras del SGA puede
conexión de usuario, por cada sesión de cambiar en múltiplos de la unidad de gra-
usuario se crea un área específica de nularidad. Esta unidad depende del tamaño
memoria llamada PGA (Program Global definido de SGA; así, la unidad de granula-
Area) que almacenará información especí- ridad es 4 MB si el SGA es menor que 128
fica de la sesión del usuario y que no se MB y 16 MB, si el SGA es mayor de 128 MB.
comparte con otras sesiones. Cada Proceso El tamaño de las estructuras del SGA puede
Servidor tiene su correspondiente PGA y es consultarse en la vista v$SGA_DYNAMIC_
es el que realmente se comunica con la ins- COMPONENTS.
tancia de Oracle en nombre del usuario.
La PGA contiene datos e información de Figura4. Datos de la instancia de Oracle
control para los procesos de usuario que se obtenidos de la vista v$instance.
ejecutan en el servidor de Oracle. El tama-
ño y contenido de la PGA depende de las En SQL/Plus podemos ver el tamaño del
opciones del servidor que se hayan instala- SGA con la instrucción
do.

La instancia de Oracle
La instancia está formada por procesos los
procesos de respaldo que acceden a los Figura 7. Consulta de los parámetros de
inicialización.
ficheros de la base de datos y por un área
de memoria compartida denominada El SGA compuesta por las siguientes
System Global Area (SGA). Es la SGA con la estructuras de memoria, cada una de ellas
que se comunica el proceso de servidor del de tamaño fijo:
usuario cuando éste accede a la base de  El buffer de caché (database buffer
Figura 5. Datos de la instancia de Oracle
datos Oracle. obtenidos de la vista v$instance. cache): almacena los bloques de datos
que han sido cargados recientemente (se
El tamaño del SGA es determinado por hayan o no confirmado sus cambios en
varios parámetros de inicialización. Los uti- el disco) como consecuencia de la ejecu-
lizados con más frecuencia son: ción de sentencias SQL desde los datafi-

DB_CACHE_SIZE Tamaño del Database Buffer cache en bytes


LOG_BUFFER Tamaño del Redo log Buffer en bytes
SHARED_POOL_SIZE Tamaño del Shared Pool en bytes
LARGE_POOL_SIZE Tamaño del Large Pool en bytes
DB_BLOCK_SIZE Tamaño del bloque de Oracle (unidad de lectura y escritura)
en bytes.

Figura 3. Arquitectura de la Instancia de Si queremos consultar el valor de un pará- les, tales como tables, índices y clusters.
Oracle. metro debemos consultar la vista Al utilizarse este buffer, se reducen las
v$parameter. Por ejemplo: operaciones de entrada y salida y por
Podemos utilizar la vista v$instance para esto se mejora el rendimiento.
consultar los datos relacionados con la ins-  Cuando un proceso requiere datos, el
tancia. proceso servidor mira en el Database
Buffer si encuentra el bloque de datos
El Área Global del Sistema (SGA) buscado lo retorna al cliente, sino lo
El SGA es un área de memoria compartida carga desde los Data Files. Se trata de
por todos los usuarios que se utiliza para evitar cuando sea posible el acceso a
almacenar información de control y de los archivos en disco, pues la lectura es
datos entre el servidor y las aplicaciones costosa en términos de desempeño.
cliente. Se crea cuando se “levanta” (es  El buffer de redo log (redo log buffer
decir, se arranca) la instancia y se borra cache): guarda los cambios efectuados
cuando ésta se “baja” (es decir, cuando se en la base de datos y que serán escritos
hace shutdown). La SGA está situada en la en el archivo físico de redo log. Se uti-
memoria virtual del computador, donde Figura 6. Parámetros de inicialización de liza para recuperar la base de datos
reside el servidor Oracle. la SGA. ante eventuales fallos del sistema.

www.revistasprofesionales.com 17 SOLO PROGRAMADORES nº 172


oracle:Portales Vocales 5/6/09 11:09 Página 18

BASES DE DATOS

 Los cambios almacenados en este buf- información acerca del espacio asigna-  Java Pool: Es una estructura opcional,
fer se llaman “redo entries” y contienen do y utilizado por los objetos de un se requiere solo si se esta usando Java
la información necesaria para poder esquema. y se utiliza para realizar el parse de las
reconstruir los cambios realizados por  El área de librería (library cache): con- clases java que se utilizan como los
las instrucciones INSERT, UPDATE, CRE- siste de dos estructuras: Shared SQL y métodos PL/SQL.
ATE, ALTER ó DROP. Shared PLSQL: Oracle utiliza el algoritmo LRU (Least
 Shared pool: almacena las sentencias  Shared SQL: Almacena y comparte el Recently Used) para gestionar los conteni-
SQL y PLSQL más recientemente ejecu- plan de ejecución de las sentencias SQL dos del Shared Pool y el database buffer
tadas y los datos más recientemente que han sido ejecutadas más reciente- cache. Cuando el proceso servidor de un
utilizados del diccionario de datos. Una mente. El Parse es el proceso por el cual usuario necesita poner una sentencia SQL
cantidad insuficiente de espacio asig- el servidor Oracle determina la forma en el shared pool o copiar un bloque de la
nado a esta área podría acarrear pro- más conveniente de acceder a los datos bbdd en el buffer cache, Oracle utiliza el
blemas de rendimiento. o de ejecutar la sentencia, a este méto- espacio en memoria ocupado por la última
 La asignación de memoria para el do se le conoce como Plan de sentencia SQL accedida o el buffer para
Shared Pool está determinada por el Ejecución. albergar la SQL solicitada o copiar el blo-
parámetro de inicialización SHA- que. Con esta técnica, las SQL más frecuen-
RED_POOL_SIZE. Este parámetro puede tes permanecen más tiempo en memoria,
ser modificado dinámicamente ejecu- mejorando las prestaciones.
tando el comando ALTER SYSTEM SET. El tamaño de los componentes de la SGA
Después del análisis de rendimiento es puede configurarse de dos modos: manual-
posible afinar el tamaño pero sin que el mente, y entonces habrá que ajustar el
SGA sobrepase el tamaño definido por tamaño inicial explícitamente de acuerdo al
el parámetro SGA_MAX_SIZE. funcionamiento de la aplicación; y, auto-
 Contiene las áreas del caché de biblio- máticamente, y es Oracle el que ajusta el
teca y del caché del diccionario de tamaño de los componentes de la SGA de
datos. Figura 8. Consulta de la estructura de la manera transparente al usuario.

SGA.
Caché de biblioteca (Database dictio- Independientemente de cual sea la opción
nary cache): almacena la información escogida, Oracle divide el espacio de alma-
de los datos del diccionario más recien-  Shared PLSQL: Almacena las unidades cenamiento de la SGA en porciones más
temente utilizados, como definiciones de programa como procedimientos pequeñas denominadas gránulos, que son
de tablas y columnas, nombres de almacenados, funciones y paquetes que alojados y desalojados dinámicamente.
usuario, claves y privilegios. Aquí se han sido parseados, compilados y eje-
manejan los árboles de parsing y el plan cutados recientemente. Procesos de la Instancia
de ejecución de las queries. Durante la Estructuras de datos opcionales Los procesos de una instancia Oracle reali-
fase parse, el proceso del servidor busca  Large Pool: Es una estructura opcional zan funciones que son necesarias para
la información en el Data Dictionary que se puede definir dentro del SGA, atender las solicitudes de varios usuarios
Cache para resolver los nombres de los sirve para almacenar datos de la sesión concurrentes, sin comprometer la integri-
objetos especificados en la sentencia de usuario y operaciones de backup y dad y rendimiento de todo el sistema. Se
SQL y para validar los privilegios de restauración de datos, este pool se usa cargan en memoria y son transparentes
acceso. Si es necesario, el proceso del en un entorno de servidor compartido. para los usuarios.
servidor inicia la carga de esta informa-
ción a partir de los ficheros de datos. Si Componentes obligatorios de la SGA
varias aplicaciones utilizan la misma Shared pool Guarda las sentencias SQL ejecutadas más recientemente por
sentencia SQL, esta área compartida los usuarios
garantiza el acceso por parte de cual- Database buffer cache Almacena los datos que han sido accedidos más reciente-
quiera de ellas en cualquier instante. mente por los usuarios
 El caché del diccionario de datos está Redo log buffer Guarda información de las transacciones para los procesos de
conformado por un grupo de tablas y recuperación de la base de datos
vistas que identifican la base de datos.
La información que se almacena aquí Componentes opcionales
guarda relación con la estructura lógi- Guarda los objetos JAVA y el código de aplicación más recien-
Java Pool
ca y física de la base de datos. El diccio- temente empleado cuando se utiliza la JVM de Oracle.
nario de datos contiene información tal Large Pool Guarda datos para operaciones costosas.
como los privilegios de los usuarios, Guarda información asociada con los mensajes de petición
restricciones de integridad definidas Streams Pool encolados cuando se emplea la opción de encolado avanzado
para algunas tablas, nombres y tipos de de Oracle.
datos de todas las columnas y otra

SOLO PROGRAMADORES nº 172 18 www.revistasprofesionales.com


oracle:Portales Vocales 5/6/09 11:09 Página 19

BASES DE DATOS
Arquitectura de Oracle

Estos procesos relacionan las estructuras copia los datos afectados desde los datafi-  El número de Checkpoint en las cabece-
físicas con las estructuras lógicas en les a al Database Buffer Cache del SGA. Si el ras de los Data Files.
memoria y manejan el tránsito de informa- usuario comitea una transacción que modi-  El número de Checkpoint, número de
ción desde y hacia la SGA, mejorando así el fica esos datos, el proceso DBWn escribirá secuencia de log, nombre de los
rendimiento y las prestaciones al centrali- los datos modificados en los correspon- Archived Log Files y el número de cam-
zar las tareas que son compartidas por dientes datafiles. bio del sistema dentro del Control File.
todos los usuarios. Por otra parte, el LGWR (Log Writer) escribe El proceso de Checkpoint no registra blo-
Se pueden utilizar varios procesos, depen- datos desde la SGA hacia los redo log files. ques de datos en los Data Files ni en los Log
diendo de la configuración, pero hay cinco Como se verá más adelante, el proceso de Files, registra el control de secuencia en los
procesos obligatorios en una instancia llenado de estos ficheros es circular, por lo Data Files y en el control File.
Oracle. que antes de empezar a sobreescribir en Este proceso es opcional. Si no está presen-
El DBWR (Database Writer) es el responsa- uno de ellos, se marca un punto de verifica- te, es el proceso LGWR quien asume la res-
ble de la escritura en disco de toda la infor- ción y el LGWR envía la orden de escritura ponsabilidad de la tarea.
mación almacenada en los buffers de blo- en los datafiles al DBWR. Por su parte, el PMON (Process Monitor)
ques que no se han actualizado. Cuando un LGWR realiza escrituras secuenciales en los monitoriza los procesos del servidor y
usuario realiza una operación SQL sobre ficheros redo log en las siguientes situacio-
una tabla, proceso servidor del usuario nes:
 Cuando una transacción es confirmada
con COMMIT.
 Cuando el redo log buffer cache esta
lleno en un tercio de su capacidad.
 Cuando hay mas de 1Mb de cambios
registrados en el redo log buffer cache.
 Antes que el DBWR escriba los bloques
modificados en el database buffer a los
data files.
 Cada tres segundos.
LGWR confirma el Commit solo después
que los cambios fueron escritos a disco.
Podemos utilizar la vista v$logfile para con-
sultar los archivos Redo Log Files.
Otro de los procesos obligatorios es el CKPT
(Checkpoint). Es el responsable de advertir al
proceso DBWR de efectuar un proceso de
actualización en el disco de los datos man- Figura 12. Funcionamiento del LGWR.

tomar acciones correctivas cuando alguno


Figura 9. Procesameinto de una sentencia de ellos se interrumpe en forma abrupta,
SQL.
limpiando la caché y liberando los posibles
recursos que pudieran estar asignados en
ese momento. También es responsable por
el restablecimiento de aquel proceso que
se ha interrumpido bruscamente.
En caso que la conexión a través del
proceso servidor asignado falle, durante
Figura 11. Funcionamiento del DBWR. la limpieza de la sesión realiza lo
tenidos en memoria, incluyendo los datafi- siguiente:
les y control files (para registrar el check-  Hace Rollback a las transacciones
point). actuales del usuario.
Un evento de Checkpoint ocurre cuando el  Libera las filas de datos de las tablas que
DBWR escribe los cambios confirmados y no mantiene bloqueados a los usuarios.
confirmados en los Data Files. Los check- Finalmente, el SMON (System Monitor) es el
point aseguran que los bloques de memoria supervisor del sistema y se encarga de
que cambian frecuentemente se escriban en recuperar la instancia durante el arranque,
los Data Files regularmente. tantas veces como sea necesario. Para
Al producirse un evento Checkpoint se recuperar la instancia sigue los siguientes
Figura 10. Componentes de la SGA de la
instancia de Oracle. registra la siguiente información de control: pasos:

www.revistasprofesionales.com 19 SOLO PROGRAMADORES nº 172


oracle:Portales Vocales 5/6/09 11:09 Página 20

BASES DE DATOS

Procesos Oracle en ejecución


las tablas, índices o agrupamientos
Listado 1 (clusters) y procedimientos. Estos
$ ps -ef |grep PROD archivos son los únicos que contienen
oracle 3969 1 0 10:02 ? 00:00:05 ora_pmon_PROD los datos de los usuarios de la base de
oracle 3971 1 0 10:02 ? 00:00:00 ora_mman_PROD
datos.
 Dos o más archivos redo log: almace-
oracle 3973 1 0 10:02 ? 00:00:07 ora_dbw0_PROD
oracle 3975 1 0 10:02 ? 00:00:07 ora_lgwr_PROD
oracle 3977 1 0 10:02 ? 00:00:10 ora_ckpt_PROD
oracle 3979 1 0 10:02 ? 00:00:20 ora_smon_PROD
nan los cambios hechos en la base de
oracle 3981 1 0 10:02 ? 00:00:00 ora_reco_PROD datos para recuperarla en caso de fallo.
oracle 3983 1 0 10:02 ? 00:00:09 ora_cjq0_PROD Estos archivos almacenan la historia de
oracle 3985 1 0 10:02 ? 00:00:00 ora_d000_PROD
oracle 3987 1 0 10:02 ? 00:00:00 ora_s000_PROD cambios efectuados sobre la base de
oracle 4052 1 0 10:02 ? 00:00:00 ora_qmnc_PROD datos y son particularmente útiles
oracle 4054 1 0 10:02 ? 00:00:29 ora_mmon_PROD
oracle 4057 1 0 10:02 ? 00:00:08 ora_mmnl_PROD cuando se necesita corroborar si los
oracle 4059 1 0 10:02 ? 00:01:04 ora_j000_PROD cambios que la base de datos ya ha
oracle 27544 1 0 20:29 ? 00:00:00 ora_q000_PROD confirmado se han efectuado realmen-
te en los datafiles.
 Graba los cambios registrados en los La Base de Datos  Uno o más control files: contienen
redo log files, estos cambios se graban información que se utiliza cuando se
después del Commit de las transaccio- Una instancia es una estructura de memo- levanta una instancia, tal como la
nes, antes de la caída del SGA por falla ria temporal, pero la base de datos Oracle información de dónde se encuentran
de la instancia. está compuesta por un conjunto de fiche- ubicados los datafiles y los
 Abre la base de datos para que los ros física que residen en el disco duro del archivos redo log. Estos archivos de
usuarios puedan hacer logon. servidor Oracle. Sobre esta capa física, control deben encontrarse siempre
 Deshace las transacciones que no fue- tenemos una capa lógica en la que se defi- protegidos.
ron confirmadas antes que fallara la nen las estructuras que mapean los datos Hay tres ficheros más que técnicamente no
instancia. en estos componentes de la capa física. forman parte de la base de datos pero que
 Además de estos procesos, existen están asociados a ella y son:
otras opciones que están recogidos en La Capa Física  Parameter File: Contiene parámetros y
la tabla de la Figura 15. La capa física de la base de datos Oracle valores que definen las características
En entornos UNIX es posible saber cuáles de está formada por: de la instancia y de la base de datos,
estos procesos se están ejecutando con el  Uno o más datafiles: estos archivos sir- por ejemplo contiene parámetros que
comando: ven para el almacenamiento físico de dimensionan el SGA.

Nombre del proceso Descripción


Copia la información de respaldo de la transacción escrita el LGWR (log writer) en los ficheros
Archiver ARCn Redo Log a una ubicación secundaria, por si fuera necesaria en caso de recuperación del sis-
tema. Casi todos los entornos de producción hacen uso de este proceso.
Recoverer RECO Recupera la transacciones fallidas que son distribuidas entre mútiples bases de datos cuando
Oracle funciona en modo distribuido.
Job Queue Monitor CJQn Asigna trabajos a los procesos Jnnn cuando se emplea la planificación de trabajos de Oracle.
Ejecuta trabajos de base de datos que han sido planificados por la planificación de trabajos de
Job Queue Jnnn
Oracle.
Monitoriza los mensajes de la cola de mensajes cuando se emplea el encolado avanzado de
Queue Monitor QMNn
Oracle.
Se emplea para llevar ejecutar fragmentos de una consulta compleja, si la funcionalidad de
Parallel Query Slave Qnnn
consulta paralela está activada.
Asigna peticiones de usuario de base de datos a un cola en donde serán servidas por el pro-
Dispatcher Dnnn
ceso servidor compartido, si esta funcionalidad está habilitada.
Procesos servidores que son compartidos entre varios usuarios de la base de datos, si esta fun-
Shared Server Snnn cionalidad está activada.
Gestiona el tamaño de cada componente individual del SGA cuando la gestión automática de
Memory Manager MMAN la memoria compartida está habilitada.
Recoge y mantiene las estadísitcas empleadas por el Repositorio Automático de carga de tra-
Memory Monitor MMON
bajo.
Recoge y analiza las estadísitcas empleadas por el Repositorio Automático de carga de traba-
Memory Monitor Light MMNL
jo.
Escribe la información de recuperación en disco cuando la funcionalidad de recuperación flas-
Recovery Writer RVWR
hback de la base de datos está habilitada.
Mantiene una pista sobre qué bloques de la base de datos han cambiado cuando se utiliza la
Change Tracking Writer CTWR funcionalidad de recuperación incremental.

SOLO PROGRAMADORES nº 172 20 www.revistasprofesionales.com


oracle:Portales Vocales 5/6/09 11:09 Página 21

BASES DE DATOS
Arquitectura de Oracle

 Password File: es opcional y almacena Data files corrompiese. Estos conjuntos de redo logs
los nombres de los usuarios con privile- Los datafiles son los ficheros físicos que reciben en el nombre de grupos de redo
gios SYSDBA y SYSOPER. almacenan los datos de las tablas, índices o logs y cada bbdd debe tener, como mínimo
 Archived Log Files: son copias off-line agrupamientos (clusters) y procedimientos. dos grupos que se emplean de manera cir-
de los archivos Redo Log que son nece- El tamaño de los datafiles está directamen- cular.
sarios para el proceso de recuperación te relacionado con la cantidad de datos que La Figura muestra un ejemplo de una bbdd
Es posible utilizar un nombre de base de pueden contener. que tiene tres grupos de redo logs. Cada
Los datafiles son la estructura física que se grupo está compuesto por dos miembros y
encuentra por debajo de otra área de alma- el primer miembro de cada grupo se guar-
cenamiento llamada tablespace. Un tables- da en el directorio /u02/oradata/PROD; el
pace es un área de almacenamiento lógica segundo, se multiplexa y se guarda en
en que se divide la base de datos. Los /u04/oradata/PROD.
tablespace agrupan segmentos relaciona-
dos desde un punto de vista lógico.
En una base de datos Oracle se puede tener
sólo uno datafile o cientos de ellos. Muchos
objetos (tablas, índices) pueden compartir
Figura 13. Ubicación de los ficheros redo varios datafiles. El número máximo de
log.
datafiles que pueden ser configurados está
datos distinto al nombre de la instancia, limitado por el parámetro de sistema MAX-
aunque Oracle recomienda que utilicemos DATAFILES.
el mismo nombre para la instancia y para la Cuando un usuario ejecuta una sentencia
base de datos para que su administración SQL sobre una tabla, el proceso servidor del
sea más sencilla. usuario copia los datos implicados en el
database buffer cache de la SGA. Si el usua- Figura 16. Determinación del número
Control files rio comitea los datos y los modifica, el d eprocesos de la instancia en ejecución.
Los control files son críticos porque contie- DBWn guarda los datos modificados en los
nen información que no se guarda en nin- datafiles correspondientes. Se puede utilizar la vista v$logfile para
gún otro sitio, ya que contienen la descrip- obtener los nombres de los grupos de redo
ción física y la dirección de los data files y logs y sus ubicaciones físicas:
de los redo log files, necesarios para el
correcto arranque de la base de datos.
Los control files se crean al crearse la bbdd
y se guardan en ubicaciones especificadas
en el parámetro control_files del fichero de
parámetros. Puesto su pérdida tendría un
impacto negativo en la capacidad para
recuperar la bbdd, en algunos entornos de
producción suelen duplicarse en ubicacio-
nes diferentes. El proceso CKPT es el encar-
gado de actualizar estos ficheros, mante- Figura 15. Otros procesos de la instancia.
niendo todas las copias sincronizadas.
Figura 17. Estructura de la base de datos
Para saber los ficheros y sus ubicaciones es Redo logs Oracle.
posible emplear la vista v$controlfile: Cuando un usuario realiza una transacción
en la base de datos, la información necesa- Esta salida muestra que la bbdd tiene un
ria para reproducir la transacción en caso total de dos grupos de redo logs y que cada
de que se produjera una caída de la base de grupo tiene un miembros. Cada uno de
datos se almacena en los redo log buffer. estos miembros está ubicado en un directo-
Los contenidos de este buffer, finalmente, rio y un volumen de disco separados, de
se escritos en los redo log files por el pro- manera que un fallo en un único disco no
ceso LGWR. producirá la pérdida de la información
Dado el importante papel que juegan los guardada en los redo logs.
redo logs en la recuperación de una bbdd Cuando un usuario ejecuta una sentencia
Oracle, se suelen multiplexar o copiar, es DML, la información de recuperación de
decir, que cada redo log contiene una o más esta transacción es escrita en el redo log
copias de sí mismo por si se produjese un buffer por el proceso servidor del usuario.
Figura 14. Funcionamiento del CKPT. fallo de harware o alguna de ella se Cuando el redo log activo se llena con la

www.revistasprofesionales.com 21 SOLO PROGRAMADORES nº 172


oracle:Portales Vocales 5/6/09 11:09 Página 22

BASES DE DATOS

información de la transacción, el LGWR


cambia al siguiente grupo y así sucesiva-
mente hasta que todos los redo logs de
todos los grupos se llenan. En ese momen-
to, el LGWR empieza a utilizar el primer
redo log del primer grupo, con lo que la
información de recuperación almacenada
en éste se sobreescribirá.
Es posible utilizar la vista v$log para mos-
trar qué grupo de redo log está activo y, por Figura 22. Determinación del estado de
tanto, está siendo escrito por el LGWR: los grupos de redo logs.

Figura 20. Utilización de los redo log.

Los Tablespaces y los Datafiles


La base de datos se encuentra dividida en
una o más piezas lógicas llamadas tables-
paces, que son utilizados para separar la
información en grupos y así simplificar la
administración de los datos. Por defecto,
toda base de datos Oracle debe tener el
tablespace SYSTEM, aunque lo habitual es Figura 23. Funcionamiento de los archive
Figura 18. Ubicación y nombre de los tener, al menos: logs.
ficheros de control.
Sin embargo, si la bbdd está operando en Tablespace Descripcion
modo archive log, los contenidos del redo SYSTEM Guarda las tablas del diccionario de datos y el código PL/SQL
log se copiarán a una ubicación secundaria SYSAUX Guarda segmentos empleados para las funcionalidades
antes de sobreescribirlos. Estas copias reci- opcionales de la BBDD
ben el nombre de archive logs. TEMP Se emplea cuando se realizan operaciones de ordenación cos-
tosas. Solamente es obligatorio si el tablespace SYSTEM se
gestiona de manera local. En otro caso, es un tablespace
opcional.
Cada tablespace debe ocupar al menos un
Cuando se crea una tabla, debe indicarse el datafile, aunque existe tablespaces que
tablespace al que se destina. En caso con- ocupan varios por razones de gestión o
trario, se ubicará en el SYSTEM, por lo que prestaciones (ver Figura 28). En este último
conviene que cada aplicación tenga su pro- caso, el DBA puede indicar que éstos que-
pio tablespace. den localizados en discos diferentes, lo que
Los tablespaces pueden ser consultados aumentará el rendimiento del sistema,
con la vista v$tablespace, tal como se ilus- principalmente por la mejora en la distribu-
tra a continuación: ción de la carga de entrada/salida.
Figura 19. Ubicación y nombre de los
datafiles. La vista del diccionario de datos
DBA_DATA_FILES muestra los datafiles
La Capa Lógica asociados con cada tablespace.
Oracle divide la base de datos en unidades
más pequeñas para manejar, almacenar, y
recuperar los datos eficientemente. El
siguiente grafico muestra la estructura
lógica de la base de datos.
La capa lógica de una base de datos consta
de los siguientes elementos:
 Uno o más tablespaces
 El esquema de la base de datos (sche- Figura 21. Estructura de los grupos de
redo log.
ma), el cual consiste de objetos como
tablas, clusters, índices, vistas, procedi- Para obtener todos los tablespaces del sis-
mientos almacenados, triggers, secuen- tema, se utiliza la vista del diccionario de Figura 24. Estructura lógica de una base
cias y otros. datos dba_tablespaces: de datos Oracle.

SOLO PROGRAMADORES nº 172 22 www.revistasprofesionales.com


oracle:Portales Vocales 5/6/09 11:09 Página 23

BASES DE DATOS
Arquitectura de Oracle

El siguiente grafico muestra la relación que mensionar para aprovechar mejor el


existe entre las estructuras físicas y las espacio de almacenamiento.
estructuras lógicas de almacenamiento.  Bloques: Cada extensión se compone
Una base de datos de ejemplo contiene tres de un cierto número de bloques, que
tablespaces lógicos (parte superior de la constituye la unidad de almacenamien-
figura) que utiliza para almacenar informa- to más pequeña en una base de datos
ción del sistema, de los datos del usuario y Oracle. Contiene una pequeña porción
de los índices de las tablas. Asimismo, exis- de información (header) referente al
ten los espacios físicos (datafiles) que bloque en sí y el resto a los datos que
guardan esta información en los diferentes guarda. Generalmente, un bloque de
Figura 27. Tablespaces del sistema.
discos disponibles y que se señalan en la datos ocupará aproximadamente 2 KB
parte inferior del dibujo. de espacio físico en el disco (asignación
Segmentos, Extensiones y Bloques típica), aunque también es usual
Dentro de los tablespaces y datafiles, el emplear tamaño de bloque de 4 KB, 8
espacio utilizado para almacenar datos es KB y 16 KB.
controlado por el uso de ciertas estructu-  Bloques del sistema operativo: cada
ras; éstas son las siguientes: bloque de la base de datos está com-
 Segmentos: Es un grupo de extensiones puesto por uno o más bloques del sis-
utilizados para almacenar un tipo parti- tema operativo, cuyo tamaño depende
cular de datos. Existen 5 tipos de seg- del sistema operativo concreto, pero
mentos: que suele estar comprendido entre 512
 De datos: almacenan datos en forma de bytes y 2 KB.
filas y columnas (es decir, las tablas de
Figura 25. Tablespaces habituales en la base de datos).
Oracle.  De índices: mejoran el acceso a los
datos de las tablas de datos, ya que las
Los datafiles pueden ser consultados con la consultas que sólo referencian a
vista v$datafile, tal como se ilustra a conti- columnas indexadas se resuelven en el
nuación: índice. Cada índice ocupa un segmento
independiente del segmento de datos y
se recomienda que, además, los índices
estén en un tablespace distinto.
 De rollback: se emplean para mantener
la consistencia de la lectura en las
transacciones de usuario y para llevar Figura 28. Organización de la base de
a cabo la recuperación de transaccio- datos en tablespaces.
nes. Almacena objetos internos de la
base de datos y son tan importantes El Esquema de la base de datos
que una base de datos no puede En una base de datos pueden existir objetos
Figura 26. Tablespaces de la base de
arrancar si no accede, al menos, a uno que no contengan datos. Sin embargo, todo
datos. de ellos. objeto debe pertener a un esquema. Un
 Temporales: son creados por la base de esquema es una colección de objetos lógi-
Y para consultar los archivos de los tablespaces datos para realizar ordenaciones que cos, utilizados para organizar de manera
temporales debemos utilizar la vista no caben en memoria y en algunas más comprensible la información y conoci-
v$tempfile, tal como se ilustra a continuación: otras operaciones. Son eliminados dos como objetos del esquema.
cuando sentencia finaliza. Una breve descripción de los objetos que lo
 De bootstrap: se crea en el tablespace componen es la siguiente:
SYSTE y contiene las definiciones de las  Tabla: es la unidad lógica básica de alma-
tablas del diccionario de datos. cenamiento. Contiene filas y columnas
 Extensiones: Cada segmento está for- (como una matriz) y se identifica por un
mado por porciones de espacio de nombre. Las columnas también tienen un
almacenamiento contiguas que reciben nombre y deben especificar un tipo de
el nombre de extensiones. Un segmen- datos. Una tabla se guarda dentro de un
to debe tener al menos un segmento. tablespace (o varios, en el caso de las
Se establecen en un tamaño fijo y cre- tablas particionadas).
cen a medida que van almacenando  Cluster: es un grupo de tablas almace-
Figura 27. Tablespaces del sistema. más datos. También se pueden redi- nadas en conjunto físicamente como

www.revistasprofesionales.com 23 SOLO PROGRAMADORES nº 172


oracle:Portales Vocales 5/6/09 11:09 Página 24

BASES DE DATOS

una sola tabla que comparten una  Un objeto puede almacenarse en uno En caso de encontrarla, no sería nece-
columna en común. Si a menudo se nece- o más datafiles pero de un solo sario procesar la sentencia, ganando así
sita recuperar datos de dos o más tablas tablespace. en prestaciones.
basado en un valor de la columna que  Dos objetos diferentes de un esquema,  Si la sentencia SQL no está en el Shared
tienen en común, entonces es más efi- pueden estar en distintos tablespaces. Pool, se procesa y su versión ejecutable
ciente organizarlas como un cluster, ya  Los objetos pueden almacenarse en se coloca en el lugar del Shared Pool
que la información podrá ser recuperada múltiples discos. corresEl proceso del servidor intenta
en una menor cantidad de operaciones leer los bloques de datos del database
de lectura realizadas sobre el disco. buffer caché de la SGA. Si no están,
 Indice: es una estructura de la base de deberán cargarlos desde los datafiles
datos creada para ayudar a recuperar en que se encuentren
datos de una manera más rápida y efi-  Se registra el valor antiguo de los datos
ciente. Un índice se crea sobre una o en un segmento derollback y se crea un
varias columnas de una misma tabla. registro redo log.
De esta manera, cuando se solicita  Se crea una copia de la transacción en
recuperar datos de ella mediante algu- un registro redo log.
na condición de búsqueda (cláusula Figura 29. Datafiles asociados a cada  Se ejecuta la sentencia SQL modifican-
tablespaces.
where de la sentencia), ésta se puede do los datos, y se crea un registro redo
acelerar si se dispone de algún índice log que así lo refleje.
sobre las columnas-objetivo. Las Transacciones  El proceso usuario valida la transacción
 Vista: Una vista implementa una selec- (COMMIT), registrandose en un regis-
ción de varias columnas de una o dife- El término transacción describe a una uni- troredo log.
rentes tablas. Una vista no almacena dad lógica de trabajo que está compuesta  El LGWR escribe los buffers del redo log
datos; sólo los presenta en forma diná- de una o más sentencias SQL, que deben en el disco.
mica. Se utilizan para simplificar la terminar con una instrucción commit o  El servidor indica al cliente que la ope-
visión del usuario sobre un conjunto de rollback. En ese instante, una nueva trans- ración ha sido completada de manera
tablas, haciendo transparente para él la acción dará comienzo y estará activa hasta satisfactoria.
forma de obtención de los datos. que se ejecute alguno de esos dos coman-  Se registra la terminación de la trans-
 Procedimientos y funciones: son blo- dos otra vez. acción en un registro redo log.
ques de código PL/SQL que se almace- Cabe destacar que una transacción no se  Se libera la información del rollback,
nan en el diccionario de datos y que considera confirmada hasta que ésta se pues ya no va a necesitarse.
pueden ser llamados desde una aplica- termina de escribir en el archivo de redo Si, a partir del paso 6, el usuario cancelara la
ción. Se ejecutan directamente desde la log. transacción (ROLLBACK), se podría utilizar la
base de datos, disminuyendo así el trá- Por ejemplo, supongamos que se desea información de rollback para restablecer el
fico de información a través de la red y hacer un UPDATE de una tabla. El ciclo de valor original. Por otra parte, si sucediese
mejorando el rendimiento de los proce- actualización sería el siguiente (ver figuras algo que impidiera que la transacción vali-
sos implementados mediante estos siguientes). dada por el usuario pueda llevarse a cabo (es
programas. Se agrupan en paquetes.  El proceso cliente pasa la sentencia SQL decir, el usuario lanza un COMMIT pero éste
 Trigger: es un procedimiento que se (en este caso, el UPDATE) al su proceso no puede ejecutarse), se puede utilizar la
ejecuta en forma inmediata cuando servidor y lo carga en la library caché información contenida en los registros redo
ocurre un evento especial. Estos even- del Shared Pool de la la SGA. log para rehacer la transacción (a partir del
tos sólo pueden ser la inserción, actua-  Los procesos del servidor buscan en el paso 6). Finalmente, el DBWR escribe en el
lización o eliminación de datos de una la library caché de SQL del Shared Pool archivo de datos la copia de los bloques de
tabla. una versión ejecutable de la sentencia. datos modificados que se encuentran en el
 Secuencias: se trata de un mecanismo database buffer cache.
de obtención de listas de números
secuenciales. El generador de secuencias Conclusión
de Oracle se utiliza para generar núme-
ros únicos y utilizarlos, por ejemplo, En este artículo se ha descrito la arquitec-
como claves de tablas. La principal ven- tura del sistema de gestión de bases de
taja es que libera al programador de datos Oracle, estudiando cuáles son sus
obtener números secuenciales que no se componentes básicos y cómo interaccionan
repitan con los que pueda generar otro entre ellos. En números posteriores se
usuario en un instante determinado. aprenderá cómo crear una base de datos
Para llevar a cabo el almacenamiento de un Oracle y configurarla adecuadamente y se
objeto en la base de datos, se contemplan Figura 30. Relación entre la base de datos, abordarán otros problemas de gestión y
las siguientes reglas: los tablespaces y los datafiles. diseño de bases de datos.

SOLO PROGRAMADORES nº 172 24 www.revistasprofesionales.com


25 Aimme:REDES-RSS Java 1 5/6/09 11:12 Página 25

ACTUALIDAD

Premio a la Empresa o Institución


dinamizadora del sector en el ámbito
de la Comunidad Valenciana
de 15 años, sobre difusión de las Tecnolo-
gías de la Información y la Comunicación
–TIC- en las empresas, precisamente,
según Mena, “porque en el entorno cerca-
no no había ningún agente que realizara
esa labor”.
Así, “desde la Dirección del Instituto se
decidió apostar firmemente por el cambio
que suponía el introducir las TIC en los
procesos de las empresas”.
Durante el evento, se hizo una especial
mención a los Proyectos METAL 2.0 y
MORFEO-FORMACIÓN que desarrolla el
Instituto, como nuevos escenarios de
futuro en los que están entrando paulati-
namente las empresas, derivadas del uso
de web 2.0 / redes sociales y software
libre, respectivamente. Las cerca de
20.000 descargas de los vídeos, los 700
participantes en el Experimento y los 420
asistentes al Evento demuestran el gran
interés despertado por METAL 2.0.
Asimismo, durante la entrega de premios,
el presidente de AIMME, quiso “trasladar
el galardón a las empresas del sector
metalmecánico, dado que son ellas las
verdaderas protagonistas del cambio que
se avecina derivado de la digitalización de
todos sus procesos y de la entrada en la
El Instituto Tecnológico Metalmecánico, La entrega de premios ha tenido lugar en nueva sociedad del conocimiento”.
AIMME, ha recibido el “Premio a la Empre- el marco de la sala Paraninfo de la Uni- La XI edición de los Premios y Noche de
sa o Institución dinamizadora del sector versidad Politécnica de Valencia, tras la las Telecomunicaciones Valencianas, den-
en el ámbito de la Comunidad Valenciana”. ponencia de Ícaro Moyano, fundador de la tro del proyecto “Sociedad de la Informa-
Este galardón representa una de las cate- red social Tuenti, y ha contado con la pre- ción 2009, se celebra con el objeto de
gorías reconocidas en la XI edición de los sencia de Alfonso Grau, concejal de Gran- despertar a la sociedad, ciudadanos,
Premios y Noche de las Telecomunicacio- des Proyectos del Ayuntamiento de empresarios e instituciones para identifi-
nes Valencianas que, bajo el lema “Teleco- Valencia, Daniel Moragues, director gene- car y aprovechar las oportunidades que se
municaciones para una Comunitat Valen- ral del Instituto de la Mediana y Pequeña presentan en este sector en la Comunidad
ciana 2.0”, promueve el Centro de Industria Valenciana –IMPIVA-, Sergio Valenciana, y gestionar el cambio hacia
Estrategias y Desarrollo del Ayuntamiento Riolobos, decano del Colegio Oficial de objetivos de mayor justicia social con un
de Valencia, el Colegio Oficial de Ingenie- Ingenieros de Telecomunicación de la enfoque 2.0 participativo, abierto, cons-
ros de Telecomunicación de la Comunidad Comunidad Valenciana y Juan Carlos tructivo y verde.
Valenciana, la Escuela Técnica Superior de Mena, presidente de AIMME, que ha sido
Ingenieros de Telecomunicación de la el encargado de recoger el galardón. Salvador Bresó Bolinches
UPV, el IMPIVA y la Secretaría Autonómi- El premio ha sido otorgado por la extensa Director
ca de Administraciones Públicas. labor iniciada por el Instituto, hace cerca AIMME-INSTITUTO TECNOLÓGICO METALMECÁNICO

www.revistasprofesionales.com 25 SOLO PROGRAMADORES nº 171


Danysoft:Portales Vocales 5/6/09 11:13 Página 26

BASES DE DATOS

Análisis de índices de SQL


Server 2005/2008
Dentro de las nuevas consultas que
PABLO F. DUEÑAS CAMPO Devuelve fundamentalmente las mejoras en
el rendimiento que podrían obtenerse

nos ofrece SQL Server 2005/2008,


implementando un grupo específico de

destacan las que sugieren nuevos


índices que faltan.
 sys.dm_db_missing_index_details:

índices. Son una mejora importante


Devuelve el nombre de la tabla en la que

para la optimación de un sistema de


falta el índice, así como las columnas y los

gestión de base de datos pues nos


tipos de columnas que se deberían crear.
 sys.dm_db_missing_index_columns:

permite encontrar cuellos de botella


Es
muy parecida a la anterior, pero con una fila

que afectan al rendimiento y


de datos para cada columna.

anticiparnos a posibles problemas. La


Antes de ver cada objeto, hay que señalar que

información que guarda el motor de


la característica de índices que faltan utiliza los
objetos de administración dinámica y los pla-

optimación de consultas nos da las


nes, para proporcionar información acerca de

sugerencias de índices así como


los índices que podrían mejorar el rendimiento.

estadísticas de la mejora teórica que


Es decir, como sabemos, cuando se pide ejecu-
tar una consulta, una de las fases es su opti-

tendríamos si se implementase. En
mación para generar el plan. Pues bien, en esta

esta primera parte vamos a analizar


fase no sólo se ve cuál es la mejor forma de

los objetos de administración


responder a la consulta en base a los objetos
que tiene actualmente la base de datos (tablas,

dinámica relacionados con la


índices, estadísticas, vistas materializadas, etc.),

creación de índices para luego ver


sino que además analiza cuáles son los mejores

qué consideraciones debemos tener a


índices para una condición de filtro concreta.
Si no existen dichos «mejores índices», los

la hora de su creación.
almacena en el plan y en una caché interna. La
característica de índices que faltan permite
tener acceso a esta información para poder
decidir qué índices deberían implementarse.
Introducción Consta, por lo tanto de dos componentes: Un
conjunto de objetos de administración dinámi-
En el presente artículo nos vamos a sumergir en ca que son los que vamos a ver en este artícu-
la nueva funcionalidad que tiene el motor de lo, y el elemento MissingIndexes en planes de
base de datos de SQL Server 2005/2008, que presentación XML, que dejamos para más
nos ayuda a encontrar índices que pueden ace- adelante.
lerar las consultas. No nos estamos refiriendo al
Database Engine Tuning Advisor (consejero de Grupos de índices
optimación del motor de base de datos), sino a
las vistas y funciones de administración diná- La información de índices faltantes no la orga-
mica relacionadas con la creación de índices. niza SQL Server 2005/2008 en índices aislados,
Son 4: sino en grupos de índices. Por esto, las demás
 sys.dm_db_missing_index_groups: Como vistas giran en torno a sys.dm_db_missing_
veremos, esta vista es la espina dorsal de la index_groups y se necesita para unirlas. Tiene
información que vamos a analizar. Devuelve dos columnas que identifican el grupo y los
los identificadores de los índices que faltan. índices que faltan. Se llaman respectivamente
 sys.dm_db_missing_index_group_stats: index_group_handle e index_handle.

SOLO PROGRAMADORES nº 172 26 www.revistasprofesionales.com


Danysoft:Portales Vocales 5/6/09 11:13 Página 27

BASES DE DATOS
Análisis de índices de SQL Server 2005/2008

pueden aparecer en uniones o filtros.


«INCLUDE» cuando el optimador deci-
de que es conveniente para cubrir la
consulta. Si no interviene esta colum-
na en la ordenación, suele devolver los
tipos en el orden expresado aquí.
Retengamos estos datos para la discusión
posterior –en el artículo sobre selectividad
y cardinalizad– sobre cómo crear el índice.

Detalles
Es la vista por antonomasia para obtener
la instrucción con la que crear el índice
(sys.dm_db_missing_index_details). Como
podemos apreciar en el apéndice, pode-
mos construir una consulta que nos de
hasta la instrucción CREATE INDEX. Las
columnas que tiene son:
 El identificador del índice (index_
handle). Es la clave de esta vista.
 El identificador de la base de datos
(database_id). Nos puede servir para
restringir los resultados a una base de
datos determinada: [Database_Id] =
Db_Id (‘AdventureWorks’).
 El identificador de la tabla a la que le
falta el índice (Object_Id). Lo podemos
añadir al filtro si nos interesa analizar
sólo una tabla: AND [Object_Id] =
Object_Id (‘[Person].[Address]’).
 Los tipos de columna según el uso que
les da la consulta (equality_columns,
En la práctica, en SQL Server 2005/2008 otras consultas mediante el operador inequality_columns e included_
cada grupo de índices sólo tiene un índice, CROSS APPLY. Devuelve tres informa- columns), que ya hemos visto en la
por lo que, aunque ambas columnas son la ciones que nos van a ser muy útiles parte anterior. Se pueden usar directa-
clave de cada índice, la realidad es que para la creación de los índices: mente para construir la consulta.
cada valor es único en su columna. A pesar  El identificador de la columna dentro  Como extra nos trae el nombre com-
de eso, interviene en las consultas porque de la tabla (column_id). Si nos fijamos pleto de la tabla sobre la que construir
las otras vistas se relacionan conceptual- en los índices que crea el Tuning el índice (statement), aunque el nom-
mente con un grupo de índices o con un Advisor, veremos que el nombre lo bre indique otra cosa. Por esto sólo
índice. construye usando estos identificado- hace falta usar database_id y
res. Así podemos saber si ya tenemos Object_Id en caso de que queramos
Columnas un índice parecido que podemos restringir los resultados, pero no para
mejorar y revisar, por ejemplo. traer el nombre de la base de datos,
Para obtener información individualizada  El nombre de la columna de la tabla esquema y tabla.
sobre las columnas de la tabla a la que le (column_name). Según Microsoft, para convertir la infor-
falta algún índice, tenemos que acudir a  El uso que la consulta da a la columna mación devuelta por esta vista en una ins-
sys.dm_db_missing_index_columns. A (column_usage). Nos devuelve tres trucción de creación de índice, se deben
diferencia de los otros objetos que vamos tipos, además en el siguiente orden: colocar las columnas de igualdad antes de
a ver, este es una función y necesita como «EQUALITY» cuando la columna está en las columnas de desigualdad, y juntas
parámetro el identificador del índice un predicado que expresa igualdad, deben formar la clave del índice. Las
(index_handle). bien sea en una unión (JOIN), en el fil- columnas incluidas se deben agregar a
 Por lo tanto la usaremos para obtener tro (WHERE) o en el orden (ORDER BY). dicha instrucción mediante la cláusula de
información de un índice una vez «INEQUALITY» en el caso de que se use inclusión nueva en SQL Server 2005/2008.
sabemos su identificador, o le aplica- cualquier operador distinto a la igual- Esto es la base, realmente hay que mirar
remos los identificadores obtenidos en dad; estas columnas, por tanto, sólo más cosas.

www.revistasprofesionales.com 27 SOLO PROGRAMADORES nº 172


Danysoft:Portales Vocales 5/6/09 11:13 Página 28

BASES DE DATOS

Estadísticas  A continuación hay una serie de De esta manera podemos evaluar tanto
columnas que nos dan la misma infor- consultas muy repetidas (User_Seeks), muy
Hasta aquí todo muy bien. Pero ¿cómo mación, pero para acciones iniciadas grandes (Avg_Total_User_Cost) o que se
sabemos la conveniencia de crear un índi- por el sistema, como pueden ser esta- beneficiarían mucho del índice
ce? Pues además, el motor de optimación dísticas. Como suelen ser valores (Avg_User_Impact). Es muy importante
de SQL Server nos hace un cálculo del pequeños, no son tan importantes. ponderar los tres valores y refrenar la ten-
ahorro que vamos a tener al crear el índi- dencia a crear índices por el mero hecho de
ce y nos lo muestra en la vista sys.dm_db_ Consulta que sean muy beneficiosos, cuando la reco-
missing_ index_group_stats. De esta mendación puede ser debida a una consul-
manera podemos saber la conveniencia de Aunque al ir explicando cada objeto y cada ta esporádica que no se va a volver a hacer
crear un índice. Veamos qué analizar en columna, hemos ido indicando cómo usar- o a consultas muy rápidas que no necesitan
esta información: las, vamos a ver un ejemplo práctico que realmente optimación.
 La primera columna no podía ser otra nos diga qué índices sería bueno crear y Como la vista de estadísticas tiene como
que un identificador (group_handle), que inclusive nos construya la consulta. clave un identificador de grupo y la de
pero en este caso es de un grupo de Lo primero es construir un ratio que nos detalles uno de índice, tendremos que unir-
índices, que, como ya hemos comenta- indique la conveniencia de crear el índice. las mediante la de grupos de índices.
do, se corresponde con un único índi- Para ello, vamos a coger las estadísticas En los filtros, podemos añadir una base de
ce en SQL Server. Por lo tanto, tendre- más relevantes y a resumirlas. Como las datos, una tabla, que no esté vacío el
mos que usar las vistas anteriores para búsquedas son bastante más importantes campo equality_columns, ver los índices
saber a qué índice en concreto se que los recorridos, se suelen usar éstas en principales, etc. El orden, obviamente, será
refieren las estadísticas. exclusiva para la fórmula. También se según el beneficio que nos de el índice.
 Un dato orientativo es el número de podrían usar ambas ponderando más las ¿Qué valores nos pueden indicar la necesi-
compilaciones y recompilaciones que se primeras (User_Seeks + User_Scans * dad de crear un índice? Bueno, lo primero
beneficiarían (unique_compiles). A esto 0.01), pero haría que los cálculos variasen es que depende de cuánto lleve la instancia
pueden contribuir consultas distintas marginalmente en la mayoría de los casos. funcionando (ver siguiente punto). Según
por lo que nos viene a decir cuántas Ya tenemos el número de veces que nos va van pasando los días y se ejecutan las con-
veces se ha sugerido este índice. a ser útil el índice. sultas, el ratio va aumentando –debido a
 El número de búsquedas (user_seeks) A continuación, habría que calcular la user_seeks–, por lo que habría que ver tam-
y de recorridos (user_scans) iniciadas ventaja que nos supone cada uso del índi- bién la velocidad de crecimiento. En todo
por consultas de usuario para las que ce. Es fácil ver que usaremos el coste caso, se suele recomendar que si el ratio
se podría haber utilizado el índice medio de las consultas multiplicado por el pasa de 5.000, se debería evaluar la crea-
recomendado. Como ya sabemos, hay beneficio (teniendo en cuenta que es un ción del índice y que si pasa de 10.000, se
que ponderar más las búsquedas que porcentaje): Avg_Total_User_Cost * tiene un índice que puede dar una mejora
los recorridos. (Avg_User_Impact * 0.01). importante en las operaciones de lectura.
 Fecha y hora de la última búsqueda
(last_user_seek) y del último recorrido
(last_user_scan) para el que podría Código de la Consulta
haber servido el índice recomendado. SELECT [Beneficio],
Es muy importante saber si el índice 'CREATE NONCLUSTERED INDEX IX_' + Replace(Replace(Replace([Statement],
sigue siendo útil o no. Puede que '[', ''), ']', ''), '.', '_')
+ '_' + Convert(VARCHAR, user_seeks) + '_' + Convert(VARCHAR,
algún cambio en la base de datos haya GROUP_HANDLE) + ' ON '
hecho que ya no lo siga recomendado + [Statement] + ' ( ' + IsNull(equality_columns, '')
+ CASE WHEN inequality_columns IS NULL THEN '' ELSE CASE WHEN
el motor de optimación y por lo tanto, equality_columns IS NULL THEN '' ELSE ',' END END
se nos indique que era (en pasado) útil. + IsNull(inequality_columns, '') + ' )'
 El costo medio de las consultas de
+ CASE WHEN included_columns IS NULL THEN '' ELSE ' INCLUDE ( '
+ included_columns + ' );'
usuario que podrían usar el índice del END AS [Instrucción]
grupo (avg_total_user_cost). Este cál- FROM (
SELECT Convert(DECIMAL(8, 2), User_Seeks * Avg_Total_User_Cost
culo es en segundos en un ordenador *
de referencia de Microsoft. En otros (Avg_User_Impact * 0.01)) AS [Beneficio],
Migs.*
ordenadores puede ser más o menos, FROM sys.dm_db_missing_index_group_stats Migs
pero nos sirve de orientación. ) AS Migs_Adv
 El beneficio porcentual medio que INNER JOIN sys.dm_db_missing_index_groups AS Mig
ON Migs_Adv.Group_Handle = Mig.Index_Group_Handle
podrían obtener las consultas de usuario INNER JOIN sys.dm_db_missing_index_details AS Mid
si se implementara este índice ON Mig.Index_Handle = Mid.Index_Handle
WHERE [Database_Id] = Db_Id('AdventureWorks')
(avg_user_ impact). Como es porcen- AND [Object_Id] = Object_Id('[Person].[Address]')
tual, en los cálculos se suele multiplicar ORDER BY [Beneficio] DESC;
por 0’01.

SOLO PROGRAMADORES nº 172 28 www.revistasprofesionales.com


Danysoft:Portales Vocales 5/6/09 11:13 Página 29

BASES DE DATOS
Análisis de índices de SQL Server 2005/2008

información mediante un acceso adi-


cional a la tabla (tenga o no índice
agrupado).
 A veces la característica sólo propor-
ciona información del uso de colum-
nas para columnas de inclusión. En
este caso, hay que usar una de las
columnas para crear el índice teniendo
en cuenta lo dicho en el punto ante-
rior y la selectividad de la columna.
 Puede devolver costos diferentes para
el mismo grupo de índices que faltan y
que aparecen varias veces en planes
de presentación XML. Es decir, en un
plan XML, puede aparecer el mismo
índice recomendado varias veces para
usos distintos, pero en las vistas sólo
aparece una vez el índice.
Como nota adicional, decir que esta carac-
terística sólo se puede deshabilitar si se
inicia una instancia de SQL Server emple-
ando el argumento –x, aunque no es reco-
mendable dada la ayuda que proporciona,
en especial con los nuevos informes de
SQL Server 2005/2008.

Conclusión
Como todo tiene un pero, veamos el para la Optimación del Motor de Base Como hemos visto, SQL Server nos ha rega-
siguiente punto (y los próximos artículos de Datos. lado con unas vistas que son de mucha
sobre optimación de índices y selectividad  No pueden reunir estadísticas de más ayuda para mejorar el rendimiento de nues-
y cardinalidad). de 500 grupos de índices que faltan, lo tro servidor de base de datos. Analizando
que puede enmascarar auténticas periódicamente los objetos de administra-
Habilitación y limitaciones mejoras en bases de datos grandes ción dinámica relacionados con índices
con muchas tablas y muchos tipos de podemos ver, no sólo los cuellos de botella
Por último, y para tener toda la informa- consultas, dado que SQL Server no que tiene el servidor, sino además cómo
ción, debemos conocer las limitaciones de permite filtrar qué sugerencias se aña- mejorar su rendimiento.
los objetos que hemos visto. La caracterís- den en base a la mejora. Este límite no Ningún Administrador de Base de Datos
tica de índices que faltan se activa de es un parámetro ajustable y no se puede pasar sin la revisión periódica de
forma predeterminada. No se proporciona puede cambiar. estos objetos ni sin echarles un vistazo en
ningún control para activar o desactivar la  No especifica un orden para las momentos de crisis: las estadísticas pueden
característica, ni para restablecer cual- columnas que se van a utilizar en un indicar que una tabla que antes no necesi-
quiera de las tablas devueltas cuando se índice: como veremos, esta es la limi- taba un índice, ahora le sea beneficioso, y su
consultan los objetos de administración tación más importante para la genera- carencia está haciendo que el servidor se
dinámica. Cuando se reinicia SQL Server, ción automática de índices. pare.
se quita toda la información sobre índices  En las consultas que implican sólo Pero, para determinar el orden efectivo para
que faltan. predicados de desigualdad, devuelve las columnas de igualdad, qué columnas
La característica de índices que faltan una información de costos menos pre- son las más importantes, si merece la pena
tiene las siguientes limitaciones: cisa, por lo tanto es conveniente no incluir columnas que cubren un índice, etc.
 Es una herramienta simple para ver generar índices basados sólo en des- podemos analizar más en profundidad estos
sugerencias de índices que podrían igualdades. objetos, lo que dejamos para otros artículos,
mejorar el rendimiento de una con-  Sólo devuelve columnas de inclusión que ya bastante hemos visto por hoy.
sulta, aunque no se pueden tomar para algunas consultas: esta es una En los Servicios Profesionales Danysoft
literalmente sus consejos, como, repi- limitación relativa pues siempre que se podéis obtener ayuda ya sea como forma-
to, veremos más adelante. crea un índice hay que ponderar si ción o como consultoría para ampliar el
Generalmente lo mejor, aunque merece la pena añadir columnas de tema, o podéis enviar vuestros comentarios
menos rápido, es usar el Asistente inclusión o es más rápido obtener la a sp@danysoft.com.

www.revistasprofesionales.com 29 SOLO PROGRAMADORES nº 172


XNA 4:XNA 4 5/6/09 11:26 Página 30

ALGORITMOS

XNA Framework 2.0 y 3.0:


DirectX y Direct3D en C#
para mortales (y IV)
MG. LIC. GASTÓN C. HILLAR

En la entrega anterior vimos cómo


gaston_hillar@hasa.com.ar Nivel 15: Extendiendo la tubería de contenidos

trabajar con modelos 3D con cierta


El mundo del desarrollo de las aplicaciones 3D

complejidad y brindarles
tiene algo mágico y trágico a la vez. Cuando pare-

movimiento e interacción,
ce que ya está todo bajo control y que solamente

combinando varios conocimientos


falta programar algunos detalles, esas pequeñeces
pueden llevar días.

necesarios que habíamos aprendido


Uno de los primeros inconvenientes es que XNA

en las primeras dos entregas.


Framework, como su nombre lo indica, es un
marco de trabajo (framework), que simplifica

Tomando como base los ejemplos


muchísimo el trabajo, como ya hemos visto. Pero,

presentados, se pueden desarrollar


no es un motor de juegos (game engine), sino que

aplicaciones 3D que visualicen y


permite montar o desarrollar sobre su marco de
trabajo un motor de juegos propio o de terceros.

faciliten la interactividad con


Entonces, cuando llega la hora de hacer ciertas

modelos 3D generados con


tareas, uno espera tener órdenes de alto nivel y

cualquiera de las herramientas de


clases especializadas, pero, no es tan completo
como un motor de juegos, por lo cual, varios

creación de contenidos digital.


aspectos son muy trabajosos.
Si bien pasar de 2D a 3D simplemente añade un
eje, se adicionan muchos elementos que entran en
Sin embargo, a la hora de juntar todas las piezas, juego al mismo tiempo en una aplicación 3D com-
aparecen nuevos detalles que se deben considerar, pleja. Por lo cual, muchas técnicas que en 2D son
sin los cuales, completar un juego con interacción bien sencillas, en el mundo 3D requieren de nue-
en 3D podría resultar una misión muy compleja. vos conceptos y de un buen manejo de matemáti-
Por lo tanto, en esta última entrega de esta serie, cas.
vamos a ahondar en ellos. Pero, por otro lado, como sucedía en el mundo 2D,
también se debe mantener un balance entre las
Introducción funcionalidades y el rendimiento. Y allí es donde
también el mundo 3D es más complejo, pues todo
Veremos cómo añadir el escenario, cómo ubicar y lleva más cálculos y las optimizaciones pueden ser
controlar a los personajes en éste. Detectaremos más críticas.
las colisiones entre los personajes y entre las pare- Por citar un ejemplo, en los códigos de ejemplo,
des, para generar un juego bastante completo. estamos utilizando foreach, pero, generalmente en
Todo, siguiendo en el fascinante mundo de las tres los juegos o cuando empleamos modelos 3D com-
dimensiones, con los ejes X, Y y Z, pero, sin dejar plejos, es más conveniente llevar a cabo los reco-
de lado a sus matrices y vectores. Seguiremos rridos utilizando lazos for. La razón es muy simple,
paso a paso, nivel por nivel (esta vez comenzando for es varias veces más veloz que foreach. Y, cuan-
en el nivel 15). Al finalizar, habremos dado do para producir cada cuadro se repiten muchos
muchos pasos para dejar de ver al mundo 3D lazos foreach recorriendo miles y miles de elemen-
como algo inaccesible en la programación moder- tos, la diferencia es notoria.
na. Quedará al alcance de las manos (que deben Tenemos que añadir el escenario, en nuestro caso
escribir código con C# y XNA Framework). el laberinto cuyo modelo habíamos presentado en

SOLO PROGRAMADORES nº 172 30 www.revistasprofesionales.com


XNA 4:XNA 4 5/6/09 11:26 Página 31

ALGORITMOS
XNA Framework 2.0 y 3.0:
DirectX y Direct3D en C# para mortales (y IV)

las entregas anteriores. A esta altura, añadir


un modelo 3D resulta sencillo y no debería
traer inconvenientes. Ahora bien, el problema
no es añadir el laberinto, que es un modelo
3D diseñado en este caso originalmente en la
herramienta de modelado 3D open source
(de código abierto) Blender. El inconveniente
radica en que, en primer lugar, los personajes
(los gatos y el ratón) deben recorrer las pare-
des del laberinto. Y, en segundo lugar, no
deben poder atravesar las paredes.
Eso que en una aplicación 2D y con algunos
conocimientos básicos de geometría es tan
simple de resolver, una detección de una coli-
sión entre dos figuras, en el mundo 3D se
torna mucho más complejo.
Existen soluciones más simples. Pero, justa-
mente la presencia del laberinto con sus
paredes añade un nivel de complejidad adi-
cional muy interesante para reutilizar en
otras clases de aplicaciones 3D.
Figura 1. Utilizando la plantilla Content Pipeline Extension Library de XNA Game
En el juego, el objetivo es que, modificando el Studio.
diseño del laberinto, se pueda reutilizar todo
TInput input, ContentProcessorContext
el código y no hay que realizar ningún cam- ofrece un modo sencillo para acceder a los
context)
bio para que así los nuevos niveles sean sen- vértices de los miles de triángulos que com-
{
cillos de generar. ponen a un modelo. Para ello, una de las
Los gatos y el ratón no son fantasmas. Por lo maneras más sencillas es crear nuestro pro- // PENDIENTE: procesar el objeto
tanto, no pueden atravesar paredes. Deben pio procesador de modelos utilizando una input y devolver los datos
detectar la presencia de las paredes y otros biblioteca de extensiones de la tubería de modificados.
elementos como la esfera, que conforman los contenidos (Content pipeline extension throw new NotImplemented
límites del laberinto. library). Ello es necesario porque únicamente Exception();
Una forma mucho más sencilla de conse- en el momento en el que se procesa el mode- }
guir el objetivo sería emplear las figuras lo, en nuestro caso FBX, podemos acceder a }
geométricas primitivas y programar para cierta información que nos va resultar útil en
que se vayan dibujando en pantalla las dife- otros momentos. El funcionamiento de los Sin embargo, lo que necesitamos no es un
rentes figuras que componen el laberinto. procesadores predeterminados lo hemos procesador de contenidos (ContentProcessor),
De ese modo, tendríamos acceso completo a analizado en las entregas anteriores, cuando sino procesador de modelo, es decir, una
sus vértices y sus transformaciones. Por lo importábamos los modelos en los diferentes nueva subclase de ModelProcessor. Por ello,
cual, podríamos detectar más fácilmente las formatos. tenemos que eliminar la línea que dice:
colisiones. Sin embargo, lo que ganamos Para conseguirlo, hay que crear un nuevo public class ContentProcessor1 :
por un lado lo perdemos por el otro. proyecto utilizando la plantilla Content ContentProcessor<TInput, TOutput>
En la mayoría de los juegos y aplicaciones 3D Pipeline Extension Library y añadirlo a la
no vamos a querer volvernos locos escribien- solución (ver la Figura 1) o bien dejarlo como Y debemos introducir el código que figura en
do código para colocar las figuras geométri- una biblioteca para luego agregar la referen- el Listado 1.
cas en el espacio. Vamos a diseñar los mode- cia correspondiente. Especifique el nombre El uso de este nuevo procesador de modelo
los con herramientas de contenido digital, ProcesadorPersonalizado como nombre del personalizado nos permitirá llevar a cabo lo
pues eso es lo más sencillo. Como desventa- proyecto. siguiente:
ja, nos complica la detección de las colisiones Visual Studio nos presentará el siguiente  Obtener una lista con todos los vértices
en las paredes y los otros elementos que código, dentro del espacio de nombres del modelo, utilizando un método recursi-
componen el laberinto. Ese es el problema de ProcesadorPersonalizado: vo que recorra a los nodos hijos.
muchos ejemplos cortos de temas relaciona- [ContentProcessor(DisplayName = “Procesador  Generar un volumen representativo del
dos con las aplicaciones 3D. Cuando un Personalizado.ContentProcessor1”)] modelo con forma de esfera
ejemplo es muy simple, no es representativo public class ContentProcessor1 :
(BoundingSphere), para luego tenerlo dis-
de la complejidad real cuando se busca la ponible para pruebas de colisiones.
 Generar un volumen representativo del
ContentProcessor<TInput, TOutput>
interacción de muchos modelos 3D comple-
{
jos, como en este caso. modelo con forma de caja (BoundingBox),
Lamentablemente, XNA Framework no nos public override TOutput Process( para luego tenerlo disponible para prue-

www.revistasprofesionales.com 31 SOLO PROGRAMADORES nº 172


XNA 4:XNA 4 5/6/09 11:26 Página 32

ALGORITMOS

Código de un procesador de modelo personalizado para obtener una


LISTADO 1 lista de vértices con sus posiciones, entre otras tareas.
[ContentProcessor(DisplayName = "ProcesadorPersonalizado.ProcesadorDeModelo")]
//comentamos esta línea porque no queremos generar un procesador de contenidos
//queremos generar un procesador de modelos (ModelProcessor)
//public class ContentProcessor1 : ContentProcessor<TInput, TOutput>
public class ProcesadorDeModelo : ModelProcessor
{
private List<Vector3> pavVertices = new List<Vector3>();

public override ModelContent Process(NodeContent input, ContentProcessorContext context)


{
// Buscar las posiciones de los vértices del objeto input
GenerarListaDeVertices(input);

// Procesar el modelo utilizando el procesador predeterminado


ModelContent lmModelo = base.Process(input, context);

// Generar los volúmenes representativos del modelo para las colisiones


BoundingBox loBoundingBoxModelo = BoundingBox.CreateFromPoints(pavVertices);
BoundingSphere loBoundingSphereModelo = BoundingSphere.CreateFromPoints(pavVertices);

// Crear un diccionario para que nos permita almacenar las instancias y listas adicionales
// y luego poder accederlas desde la propiedad general "Tag"
Dictionary<string, object> loDiccionario = new Dictionary<string, object>();

// Almacenar la caja delimitadora del modelo completo generada a partir de los vértices, en el diccionario bajo
la entrada "BoudingBoxModelo"
loDiccionario.Add("BoudingBoxModelo", loBoundingBoxModelo);
// Almacenar la esfera delimitadora del modelo completo generada a partir de los vértices, en el diccionario bajo
la entrada "BoudingSphereModelo"
loDiccionario.Add("BoudingSphereModelo", loBoundingSphereModelo);
// Almacenar la información sobre los vértices como un arreglo de Vector3, en el diccionario bajo la entrada "Vertices"
loDiccionario.Add("Vertices", pavVertices.ToArray());
// Asignar el diccionario a la propiedad Tag del modelo
lmModelo.Tag = loDiccionario;

// Devolver el modelo procesado


return lmModelo;
}

/// <summary>
/// Extrae la lista de todas las posiciones de vértices en un modelo (se llama en forma recursiva)
/// </summary>
void GenerarListaDeVertices(NodeContent poNodo)
{
MeshContent loMalla = poNodo as MeshContent;

if (loMalla != null)
{
// Es una malla
Matrix loTransformacionAbsoluta = loMalla.AbsoluteTransform;

// Recorro todas las piezas geométricas en la malla


foreach (GeometryContent loGeometria in loMalla.Geometry)
{
// Recorro todos los índices en la pieza de geometría (cada grupo de tres índices representa un triángulo)
foreach (int i in loGeometria.Indices)
{
// Tomo la posición del vértice
Vector3 lvVertice = loGeometria.Vertices.Positions[i];
// La transformo del espacio local al espacio del mundo (world)
lvVertice = Vector3.Transform(lvVertice, loTransformacionAbsoluta);
// Añadir el vértice a la lista (variable de instancia)
pavVertices.Add(lvVertice);
}
}
}

// Llamar al método GenerarListaDeVertices para cada hijo de este nodo


foreach (NodeContent child in poNodo.Children)
{
GenerarListaDeVertices(child);
}
}
}

SOLO PROGRAMADORES nº 172 32 www.revistasprofesionales.com


XNA 4:XNA 4 5/6/09 11:26 Página 33

ALGORITMOS
XNA Framework 2.0 y 3.0:
DirectX y Direct3D en C# para mortales (y IV)

bas de colisiones, que brinda una alterna-


tiva al uso de la forma de esfera.
Luego, veremos más en detalle para qué sir-
ven BoundingSphere y BoundingBox, y por
qué razón las creamos a partir de la lista de
vértices.
Ahora bien, como estamos en la clase que
procesa el modelo y no en la que lo represen-
ta, si agregáramos propiedades, no las vería-
mos en el código del juego. Pues, el método
Process devuelve una instancia de
ModelContent:
public override ModelContent Process(
NodeContent input, ContentProcessorContext
context)

Una de las maneras tradicionales y más sen-


cillas para añadir propiedades es encapsular-
las en un diccionario (Dictionary<string,
object>) y luego asignarlo a la polifuncional
propiedad Tag.
Figura 2. Añadiendo la referencia al procesador personalizado para que esté
De esa forma, añadimos las siguientes tres disponible como procesador de un modelo.
propiedades encapsuladas a la instancia de
ModelContent retornada: técnicas más simples para la detección de recursos disponibles. Para cambiar de nivel,
 “BoudingBoxModelo” colisiones, el objetivo es presentar una que se modificaba el color o el patrón que se
 “BoudingSphereModelo” nos servirá para muchas otras aplicaciones empleaba para dibujar el escenario o laberin-
 “Vertices” con objetos 3D complejos. to. En nuestro caso, tomamos un modelo que
El modelo se procesa empleando el procesa- Para que tengamos disponibles las propieda- emplea un material de un color anaranjado
dor predeterminado, en realidad lo que aña- des encapsuladas en la propiedad Tag del como base para que, en cada nivel, le apli-
dimos es la posibilidad de obtener los vértices modelo, debemos cambiar el procesador de quemos una textura diferente que será un
y las propiedades mencionadas a partir de contenidos que se utilizará para cada mode- fichero PNG.
esa lista. lo. Recordemos que éste se especifica utili- Entonces, a la hora de presentar el laberinto,
La llamada al procesador predeterminado se zando un cuadro de lista desplegable en la según el nivel, se podrá utilizar una textura
produce en la siguiente línea: propiedad Content Processor cuando lo diferente. Por supuesto que también busca-
ModelContent lmModelo = base.Process( seleccionamos en el Explorador de soluciones mos que la aplicación pueda adaptarse sin
input, context); (Solution Explorer). tener que cambiar una línea de código a nue-
Antes de que nos aparezca como opción vos laberintos que se puedan crear y expor-
El método GenerarListaDeVertices se encarga nuestro nuevo procesador de modelos, es tar al formato FBX, pues eso es lo bueno, que
de añadir a la lista privada todos los vértices necesario añadir una referencia a este pro- todo sea dinámico. Pero, con este ejemplo
de todas las piezas geométricas que hay en yecto, aún cuando forme parte de la solu- estamos mostrando cómo se puede tomar un
cada malla de un nodo (cada grupo de tres ción. Recordemos que esto se consigue modelo sin una textura y aplicársela median-
índices representa un triángulo). Antes de ello, seleccionando Project, Add Reference… te programación.
transforma los vértices del espacio local al (Proyecto, Añadir referencia) y escogiendo Lo primero que debemos hacer es añadir el
espacio del mundo (world). El método se llama ProcesadorPersonalizado en la solapa fichero FBX en la carpeta modelos, en la
en forma recursiva por cada nodo encontrado. Projects (Proyecots) de la caja de diálogo que tubería de contenidos. Pero luego, tenemos
Otra vez, si bien en el código del Listado 1 se aparece (ver la Figura 2). que acceder a sus propiedades y especificar
utilizaron varios foreach anidados, es más ProcesadorPersonalizado.ProcesadorDeMode
rápido empleando lazos for. Nivel 16: Añadiendo el escenario lo en la propiedad Content Processor (ver la
Una pregunta que puede surgir es por qué no (el laberinto) Figura 3). Este nombre es el que estaba defi-
accedemos a los vértices a través de una pro- nido para mostrar en la siguiente línea del
piedad existente, sin necesidad de tener que Llegó el momento de añadir el escenario, en Listado 1:
extender a la tubería de contenidos. La razón nuestro caso el laberinto con sus paredes y [ContentProcessor(DisplayName = “Procesador
es que no existe tal propiedad y que una de con su esfera. El laberinto completo está des- Personalizado.ProcesadorDeModelo”)]
las formas más sencillas de hacerlo es crean- arrollado en una herramienta de creación de
do nuestro propio procesador de modelos y contenido digital, sin embargo, vamos a Esta modificación en la propiedad Content
extendiéndolo. emplear una técnica clásica de los antiguos Processor la tenemos que llevar a cabo en los
Si bien es cierto que podemos utilizar otras juegos 2D en los cuales no había muchos otros modelos FBX que fuimos incorporando

www.revistasprofesionales.com 33 SOLO PROGRAMADORES nº 172


XNA 4:XNA 4 5/6/09 11:26 Página 34

ALGORITMOS

ríamos mucho más código y debemos man-


tener los casos de ejemplo dentro de un
espacio prudencial. El código se podrá mejo-
rar muchísimo.
A diferencia de los personajes, el laberinto no
se debe desplazar en el espacio 3D (puede
moverse la cámara, pero no el laberinto). Por
ello, vamos a añadir una variable protegida
del tipo bool que indique si el personaje tiene
o no movimiento. De esta manera, consul-
tando el valor de esa variable, responderá a
las teclas asignadas con movimientos o no.
En el Listado 2 se presenta el código añadido
a la clase Personaje (presentada en la entre-
ga anterior).
El código presente en el método
CargarPropiedadesEncapsuladasEnTag es el
que nos permite que cada modelo tenga su
BoundingBox y su BoundingSphere accesible
mediante las propiedades BoundingBoxModelo
y BoundingSphereModelo.
Figura 3. Especificando el procesador para el modelo del laberinto.
El procesador de modelos generado así
como la forma de obtener la BoundingBox y
a la tubería de contenidos. Queremos acceder y aplicárselas para darle más vida. la BoundingSphere de éstos son muy útiles
a las nuevas propiedades encapsuladas en Para simplificar el trabajo, si bien en un dise- para detección de colisiones en diferentes
todos ellos (gato y ratón). ño orientado a objetos prolijo, no debería ser clases de aplicaciones y juegos 3D. Por lo
Ahora, vamos a añadir dos ficheros PNG tex- así, vamos a crear una nueva clase Laberinto, tanto, se podrán reutilizar en muchos casos.
tura_laberinto_nivel_1.png y textu- como subclase de Personaje. Es verdad, debe- Para cada una de las subclases de Personaje,
ra_laberinto_nivel_2.png para comprobar lo ríamos crear una nueva clase Escenario y debemos realizar una modificación en el méto-
sencillo que es tomar un modelo sin texturas como subclase de ella Laberinto. Pero, añadi- do LoadContent y añadir una llamada al méto-

Código que se añade a la clase personaje, para almacenar los


LISTADO 2 valores de algunas de las propiedades encapsuladas en Tag.
protected BoundingBox poBoudingBoxModelo;
protected BoundingSphere poBoudingSphereModelo;
protected bool pbTieneMovimiento = true;

public BoundingBox BoundingBoxModelo


{
get
{
return poBoudingBoxModelo;
}
}

public BoundingSphere BoundingSphereModelo


{
get
{
return poBoudingSphereModelo;
}
}

protected void CargarPropiedadesEncapsuladasEnTag()


{
// Crear un diccionario para que nos permita acceder a las instancias almacenadas por el procesador de modelos en pro-
piedad general "Tag"
Dictionary<string, object> loDiccionario = (Dictionary<string, object>)pmModelo.Tag;
if (loDiccionario == null)
{
throw new InvalidOperationException("No se ha utilizado el procesador personalizado para cargar este modelo a la
tubería de contenidos.");
}

poBoudingBoxModelo = (BoundingBox)loDiccionario["BoudingBoxModelo"];
poBoudingSphereModelo = (BoundingSphere)loDiccionario["BoudingSphereModelo"];
}

SOLO PROGRAMADORES nº 172 34 www.revistasprofesionales.com


XNA 4:XNA 4 5/6/09 11:26 Página 35

ALGORITMOS
XNA Framework 2.0 y 3.0:
DirectX y Direct3D en C# para mortales (y IV)

La clase Laberinto, dibujándolo con una textura


LISTADO 3 personalizada, que podrá variar según el nivel.
public partial class Laberinto : Personaje
{
Texture2D poTextura;

public Laberinto(Game game)


: base(game)
{
pbTieneMovimiento = false;
}

protected override void LoadContent()


{
poTextura = poGame.Content.Load<Texture2D>("Texturas\\textura_laberinto_nivel_1");
// Cargo el modelo del laberinto
pmModelo = poGame.Content.Load<Model>("Modelos\\laberinto_nivel_1");

CargarPropiedadesEncapsuladasEnTag();

base.LoadContent();
}

public override void Draw(GameTime gameTime)


{
// Copio cualquier transformación
Matrix[] misTransformaciones = new Matrix[pmModelo.Bones.Count];
pmModelo.CopyAbsoluteBoneTransformsTo(misTransformaciones);

// Dibujar el modelo, malla por malla (mesh by mesh)


// Como los modelos generalmente están compuestos por muchas mallas, las recorro en un lazo
foreach (ModelMesh miMalla in pmModelo.Meshes)
{
// Para cada efecto, asigno la orientación de la malla, la de la cámara y la proyección
foreach (BasicEffect miEfecto in miMalla.Effects)
{
miEfecto.EnableDefaultLighting();

miEfecto.World = misTransformaciones[miMalla.ParentBone.Index] * Matrix.CreateRotationY(piRotacion)


* Matrix.CreateTranslation(pvPosicion); // *Matrix.CreateScale(1.5f);
miEfecto.View = Matrix.CreateLookAt(poGame.PosicionDeCamara, Vector3.Zero, Vector3.Up);
miEfecto.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
poGame.RelacionDeAspecto, 1.0f, 100000.0f);

// Asignar la textura para que se presente en todas las mallas del laberinto
miEfecto.Texture = poTextura;
miEfecto.TextureEnabled = true;
}
// Dibujo la malla, utilizando los efectos especificados
miMalla.Draw();
}
}
}

do CargarPropiedadesEncapsuladasEnTag LoadContent: aplicarle texturas a cada una de las partes del


antes de la línea base.LoadContent();. De esta poTextura = poGame.Content.Load<Texture modelo.
manera, tendrán disponibles las propiedades 2D>(“Texturas\\textura_laberinto_nivel_1”); Como Laberinto es una subclase de Personaje
para realizar correctamente la detección de y por ende de DrawableGameComponent,
colisiones que veremos más adelante. Y luego se aplica en las siguientes líneas: tenemos que hacer las modificaciones a la
Después de todo el esfuerzo, para presentar miEfecto.Texture = poTextura; clase principal del juego para que se presen-
el laberinto, creamos una subclase de miEfecto.TextureEnabled = true; te en pantalla.
Personaje, pero le asignamos el valor false Es el escenario del juego y es de gran impor-
(falso) a la variable de instancia Además de especificar un valor para la pro- tancia, por lo cual, vamos a añadir una pro-
pbTieneMovimiento, para indicar que será piedad Texture, es fundamental cambiar el piedad para que luego los personajes puedan
estático y redefiniremos los métodos valor a true (verdadero) de la propiedad acceder a éste a través de la instancia de la
LoadContent y Draw. Este último debido a TextureEnabled. Pues, en el caso del laberin- clase Game1. Por lo cual, se añade el siguien-
que queremos presentar al laberinto utilizan- to, no empleaban texturas, sino que tenía un te código a Game1:
do diferentes texturas y no queremos que se material únicamente basado en un color. public Laberinto Escenario
llame al método Draw de la clase base. El En modelos bien diseñados para que luego se {
código completo de la clase Laberinto se pre- puedan controlar todos sus detalles median-
get
senta en el Listado 3. te programación, todas sus figuras geométri-
{
La textura se carga en el método cas tienen nombres, por lo cual, es posible

www.revistasprofesionales.com 35 SOLO PROGRAMADORES nº 172


XNA 4:XNA 4 5/6/09 11:26 Página 36

ALGORITMOS

Figura 4. El laberinto, sin texturas, demasiado simple. Figura 5. El laberinto, con la textura del nivel 1 envolviendo sus
paredes. Mucho más vistoso.
return piPasoZ;
}
set
{
piPasoZ = value;
}
}
El eje Z lo vamos a utilizar como arriba y
abajo, por su similitud con un escenario en
2D. Si bien no es del todo correcto, es más
fácil de comprender. Vamos a reemplazar el
método Update de la clase Personaje por uno
más general y esta vez teniendo en cuenta si
el modelo tiene movimiento o no, para con-
siderar o no las teclas presionadas. En el
Figura 6. El laberinto, con la textura del nivel 2 envolviendo sus paredes. Listado 4 se presenta el código.
Diferenciándose con poco código. Utilizamos cuatro métodos para llevar a cabo
el movimiento:
 ProbarDesplazarIzquierda.
return poLaberinto;
coincide con la presentación del laberinto y
 ProbarDesplazarDerecha.
}
no conseguimos recorridos correctos. Esto se
} debe a que, en el mundo 3D se añade el eje Z  ProbarDesplazarArriba.
private Laberinto poLaberinto; y el laberinto está presentado de tal manera  ProbarDesplazarAbajo.
Y, en el constructor de Game1, el código para que los personajes se pueden mover dentro Estos métodos se llaman según la tecla pre-
añadir el componente para que se dibuje en de éste de izquierda a derecha y de mayor a sionada (lo cual vimos en detalle en la entre-
pantalla: menor profundidad. ga anterior).
poLaberinto = new Laberinto(this); Esto tiene que ver con la ubicación de la Los métodos llaman a la función
Components.Add(poLaberinto); cámara y cómo está presentado el laberinto. HayColisionConEscenario, que devuelve un
Si rotamos la cámara, los movimientos pue- bool indicando si el modelo colisiona con
poLaberinto.Rotacion = 0.0f;
den invertirse. Por un momento, vamos a alguna de las paredes del laberinto en la
poLaberinto.Posicion = new Vector3(0, 0, 0);
olvidarnos de las colisiones y de las paredes. nueva posición que adquiere y con la nueva
En las Figuras 4, 5 y 6 podemos ver los resul- Queremos que los personajes se muevan rotación. Si hay colisión, no se produce ni el
tados de la presentación del laberinto, sin los dentro del laberinto libremente. movimiento ni la rotación.
personajes, sin textura y con las texturas de Por lo tanto, hay que permitirles desplazarse La función HayColisionConEscenario la simu-
los niveles 1 y 2. en el eje Z añadiendo una variable y una pro- lamos inicialmente devolviendo un valor
piedad a la clase Personaje: false (falso), para que los personajes se pue-
Nivel 17: Desplazando los personajes protected float piPasoZ = 5.0f; dan desplazar libremente.
en el laberinto public float PasoZ Ahora, es necesario ubicar a los personajes en
ubicaciones que inicialmente no tengan coli-
{
Si empezamos a desplazar los personajes a siones con las paredes del laberinto, es decir,
get
través de los movimientos en los clásicos ejes que sean de libre circulación, por lo cual,
X e Y de las aplicaciones 2D, veremos que no { vamos a modificar la parte del constructor

SOLO PROGRAMADORES nº 172 36 www.revistasprofesionales.com


XNA 4:XNA 4 5/6/09 11:26 Página 37

ALGORITMOS
XNA Framework 2.0 y 3.0:
DirectX y Direct3D en C# para mortales (y IV)

Código añadido y reemplazado en la clase Personaje para lograr un desplazamiento que vaya
LISTADO 4 teniendo en cuenta las potenciales colisiones con las paredes del laberinto.
public override void Update(GameTime gameTime)
{
if (pbTieneMovimiento)
{
// Guardo el estado del teclado y luego analizo todas las posibilidades
KeyboardState miEstadoTeclado = Keyboard.GetState();
// Si presionó la flecha hacia la izquierda, muevo al modelo hacia la izquierda, -X
if (miEstadoTeclado.IsKeyDown(pkTeclaIzquierda))
{
ProbarDesplazarIzquierda();
}
// Si presionó la flecha hacia la derecha, muevo al modelo hacia la derecha, +X
if (miEstadoTeclado.IsKeyDown(pkTeclaDerecha))
{
ProbarDesplazarDerecha();
}
// Si presionó la flecha hacia arriba, muevo al modelo hacia arriba, -Y
if (miEstadoTeclado.IsKeyDown(pkTeclaArriba))
{
ProbarDesplazarArriba();
}
// Si presionó la flecha hacia abajo, muevo al modelo hacia abajo +Y
if (miEstadoTeclado.IsKeyDown(pkTeclaAbajo))
{
ProbarDesplazarAbajo();
}
}
base.Update(gameTime);
}
public bool ProbarDesplazarIzquierda()
{
// Guardo la posición anterior del personaje, para volver a ella si hay colisión
Vector3 lvPosicionAnterior = pvPosicion;
float liRotacionAnterior = piRotacion;
piRotacion = MathHelper.ToRadians(-90.0f);
// Muevo al modelo hacia la izquierda, -X
pvPosicion.X -= piPasoX;
if (HayColisionConEscenario())
{
// Hay colisión, falló el desplazamiento
pvPosicion = lvPosicionAnterior;
piRotacion = liRotacionAnterior;
return false;
}
return true;
}
public bool ProbarDesplazarDerecha()
{
// Guardo la posición anterior del personaje, para volver a ella si hay colisión
Vector3 lvPosicionAnterior = pvPosicion;
float liRotacionAnterior = piRotacion;
piRotacion = MathHelper.ToRadians(90.0f);
// Muevo al modelo hacia la derecha, +X
pvPosicion.X += piPasoX;
if (HayColisionConEscenario())
{
// Hay colisión, falló el desplazamiento
pvPosicion = lvPosicionAnterior;
piRotacion = liRotacionAnterior;
return false;
}
return true;
}
public bool ProbarDesplazarArriba()
{
// Guardo la posición anterior del personaje, para volver a ella si hay colisión
Vector3 lvPosicionAnterior = pvPosicion;
float liRotacionAnterior = piRotacion;
piRotacion = MathHelper.ToRadians(180.0f);
// Muevo al modelo hacia arriba, -Z
pvPosicion.Z -= piPasoZ;
if (HayColisionConEscenario())
{
// Hay colisión, falló el desplazamiento
pvPosicion = lvPosicionAnterior;
piRotacion = liRotacionAnterior;
return false;

www.revistasprofesionales.com 37 SOLO PROGRAMADORES nº 172


XNA 4:XNA 4 5/6/09 11:26 Página 38

ALGORITMOS

Código añadido y reemplazado en la clase Personaje para lograr un desplazamiento que vaya
LISTADO 4 teniendo en cuenta las potenciales colisiones con las paredes del laberinto. (continuación)
}
return true;
}

public bool ProbarDesplazarAbajo()


{
// Guardo la posición anterior del personaje, para volver a ella si hay colisión
Vector3 lvPosicionAnterior = pvPosicion;
float liRotacionAnterior = piRotacion;

piRotacion = MathHelper.ToRadians(0.0f);
// Muevo al modelo hacia abajo, +Z
pvPosicion.Z += piPasoZ;
if (HayColisionConEscenario())
{
// Hay colisión, falló el desplazamiento
pvPosicion = lvPosicionAnterior;
piRotacion = liRotacionAnterior;
return false;
}
return true;
}

public bool HayColisionConEscenario()


{
// Simulamos que nunca se colisiona con el escenario
return false;
}

Definiendo la posición inicial de los personajes.


Game1 que define a los personajes por la que
se presenta en el Listado 5. Tengamos en LISTADO 5
cuenta que ahora gestionamos los ejes X y Z poRatón = new Ratón(this);
Components.Add(poRatón);
y dejamos al Y en 0 (ver las Figuras 7 y 8). poRatón.Posicion = new Vector3(350, 0, 350);
Para brindar un juego más atractivo, se pue-
den tener varias posiciones predeterminadas poGato1 = new Gato(this);
Components.Add(poGato1);
y que se escojan en forma aleatoria. También poGato1.Posicion = new Vector3(1700, 0, 200);
se pude modificar el color o la textura de poGato1.TeclaAbajo = Keys.X;
poGato1.TeclaArriba = Keys.W;
ciertas mallas de los gatos. En fin, el límite es poGato1.TeclaIzquierda = Keys.S;
la imaginación en esta clase de aplicaciones. poGato1.TeclaDerecha = Keys.D;
poGato1.PasoX = 6.0f;
poGato1.PasoZ = 6.0f;
Nivel 18: Detectando colisiones entre
poGato2 = new Gato(this);
personajes Components.Add(poGato2);
poGato2.Posicion = new Vector3(-600, 0, -250);
La detección de colisiones es uno de los temas poGato2.TeclaAbajo = Keys.M;
poGato2.TeclaArriba = Keys.I;
más complejos dentro del desarrollo de aplica- poGato2.TeclaIzquierda = Keys.J;
ciones 3D. Justifica una obra entera por sí poGato2.TeclaDerecha = Keys.K;
mismo, por la cantidad de técnicas que existen. poGato2.PasoX = 7.0f;
poGato2.PasoZ = 7.0f;
Por lo tanto, vamos a aplicar un sistema de

Figura 7. El laberinto con los personajes ubicados correctamente Figura 8. Los personajes se pueden desplazar correctamente por
para poder desplazarse por sus caminos entre las paredes. el laberinto.

SOLO PROGRAMADORES nº 172 38 www.revistasprofesionales.com


XNA 4:XNA 4 5/6/09 11:26 Página 39

ALGORITMOS
XNA Framework 2.0 y 3.0:
DirectX y Direct3D en C# para mortales (y IV)

El código de la función HayColision


LISTADO 6 correspondiente a la clase Personaje.
public bool HayColision(Personaje paroOtroPersonaje)
{
bool lbHuboColision = false;

if ((poBoudingSphereModelo.Radius == 0) || (paroOtroPersonaje.poBoudingSphereModelo.Radius == 0))


{
return lbHuboColision;
}

BoundingSphere miBoundingSphere = poBoudingSphereModelo;


miBoundingSphere.Center += pvPosicion;

BoundingSphere suBoundingSphere = paroOtroPersonaje.poBoudingSphereModelo;


suBoundingSphere.Center += paroOtroPersonaje.pvPosicion;

lbHuboColision = (miBoundingSphere.Intersects(suBoundingSphere));

return lbHuboColision;
}

El código de la clase NoviaRatón. Un personaje estático.


detección de colisiones imperfecto, pero que
LISTADO 7
nos permitirá obtener un juego razonablemen-
public partial class NoviaRatón : Personaje
te sencillo desde el código y bastante funcional. {
En el Listado 6 podemos ver el código de la public NoviaRatón(Game game)
función HayColision que se añade a la clase : base(game)
{
Personaje para que retorne un valor del tipo pbTieneMovimiento = false;
bool indicando si el personaje que represen- }
ta su instancia en su posición actual colisio- protected override void LoadContent()
na con el que se recibe como parámetro. {
En este caso, se utiliza un volumen represen- // Cargo el modelo del gato
pmModelo = poGame.Content.Load<Model>("Modelos\\novia_raton");
tativo del modelo completo con forma de
esfera, conocido como BoundingSphere. Lo CargarPropiedadesEncapsuladasEnTag();
generamos en el procesador del modelo debi- base.LoadContent();
do a que allí teníamos disponible la lista de }
}
vértices y nos permite una mayor precisión.
Cada malla tiene su BoundingSphere, sin embar-
go, si no tenemos las posiciones de las mallas, de Como el modelo del laberinto es totalmente Primero, hay que añadir el modelo contenido
nada nos sirve su volumen representativo. dinámico y nos gustaría cambiarlo para en el fichero novia_raton.FBX. Recordemos
De esta manera, se traslada cada esfera otros niveles, una forma muy sencilla de que hay que utilizar el procesador personali-
representativa del volumen del modelo a la saber si el ratón alcanzó la meta es añadir a zado ya explicado.
posición actual de cada personaje y se llama su novia y verificar si colisionó con ella con En el Listado 7 podemos ver el código para la
al método Intersects (Hay intersección), que el método HayColision. Si lo hizo, gana y nueva clase que la representa.
devuelve un valor del tipo bool indicando si debe pasar de nivel. Debemos añadir una variable de instancia a
alguna parte de las dos esferas genera una Este mecanismo nos sirve para detectar coli- la clase Game1 para tener disponible a la
intersección con la otra. siones entre los personajes, pero no es útil a novia del ratón:
A simple vista, debería funcionar bien. Sin la hora de detectar colisiones con el escena- private NoviaRatón poNoviaRatón;
embargo, no es del todo preciso, pues en mode- rio, debido a que la esfera o la caja represen-
los complejos como es el caso del gato y del tarían a todo el laberinto y lo que queremos Y su posición inicial en el constructor de la
ratón, y especialmente cuando están rotados, se es ver si chocamos contra una pared o no. clase Game1:
pueden generar intersecciones en las esferas Para el laberinto, hay que aplicar otra técni- poNoviaRatón = new NoviaRatón(this);
cuando en realidad ese volumen no está ocu- ca, mucho más compleja, pero muy útil para Components.Add(poNoviaRatón);
pado por una malla. otras aplicaciones.
poNoviaRatón.Posicion = new Vector3(
También se puede utilizar la representación
-520, 0, 1550);
tipo caja para otros casos. Por eso la dejamos Nivel 17: Añadiendo a la novia del
poNoviaRatón.Rotacion = -10.0f;
disponible en el procesador del modelo. Sirve ratón (un personaje estático)
para experimentar en otros casos.
Lo ideal sería comprobar malla por malla, vér- Para facilitar la detección de la llegada del Nivel 18: Controlando la cámara con
tice por vértice, sin embargo, esto llevaría ratón a la salida del laberinto, vamos a tomar el ratón
mucho tiempo. Pues, tenemos que comprobar un atajo. Añadiremos a su novia esperándo-
si cada gato colisiona con el ratón y también lo, un personaje estático. Si colisiona con ella, Como vamos a detectar las colisiones basan-
debemos saber si el ratón alcanzó la meta. gana. do en cómo se está visualizando el modelo,

www.revistasprofesionales.com 39 SOLO PROGRAMADORES nº 172


XNA 4:XNA 4 5/6/09 11:26 Página 40

ALGORITMOS

LISTADO 8 El nuevo código para actualizar el juego de la clase Game1.


protected override void Update(GameTime gameTime)
{
// Permite salir del juego
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();

// Guardo el estado del teclado y luego analizo todas las posibilidades


KeyboardState miEstadoTeclado = Keyboard.GetState();

MouseState miEstadoRaton = Mouse.GetState();

// Si presionamos la tecla ESC, salimos del juego


if (miEstadoTeclado.IsKeyDown(Keys.Escape))
{
this.Exit();
}

// Si presionó el botón izquierdo del ratón, alejo al objeto modelo la cámara en +Z


if (miEstadoRaton.LeftButton == ButtonState.Pressed)
{
miPosicionDeCamaraZ += 5.0f;
}

// Si presionó el botón derecho del ratón, acerco al modelo moviendo la cámara en -Z


if (miEstadoRaton.RightButton == ButtonState.Pressed)
{
miPosicionDeCamaraZ -= 5.0f;
}

// Establezco el Z de la cámara en el Z que actualicé


miPosicionDeCamara.Z = miPosicionDeCamaraZ;

if ((poEstadoRatonAnterior.X != 0) || (poEstadoRatonAnterior.Y != 0))


{
miPosicionDeCamara.X += (miEstadoRaton.X - poEstadoRatonAnterior.X);
miPosicionDeCamara.Y += (miEstadoRaton.Y - poEstadoRatonAnterior.Y);
}
miPosicionDeCamara.Y += (miEstadoRaton.ScrollWheelValue - poEstadoRatonAnterior.ScrollWheelValue);

poEstadoRatonAnterior = miEstadoRaton;

if (poRatón.HayColision(poGato1))
{
this.Exit();
}
if (poRatón.HayColision(poGato2))
{
this.Exit();
}

if (poRatón.HayColision(poNoviaRatón))
{
this.Exit();
}

//poGato1.Desplazarse(poRatón);
//poGato2.Desplazarse(poRatón);

base.Update(gameTime);
}

private MouseState poEstadoRatonAnterior


podemos tener ciertos inconvenientes. Como debido a que la propiedad ScrollWheelValue
= new MouseState();
estamos generando un ejemplo simplificado, del estado del ratón almacena un valor acu-
permitiendo un mayor control de la cámara En el código del Listado 8 las dos líneas que mulativo. Por lo tanto, guardando el estado
con el ratón (el mouse, el periférico que nos llaman al futuro método Desplazarse de cada anterior del ratón y tomando la diferencia, se
permite desplazar el puntero), conseguire- instancia de la clase Gato están comentadas puede aplicar al eje Y de la cámara.
mos evadir esos problemas. Además, brinda- porque las pondremos en marcha más ade- Por otro lado, desplazando el ratón sin pre-
mos una mayor funcionalidad al juego. lante. sionar ningún botón, se cambia el eje X de la
Para ello, vamos a modificar el código del Antes, la cámara la podíamos acercar o alejar cámara, también por el delta entre la nueva
método Update de la clase Game1 por el que presionando los botones del ratón. Ahora, posición y la anterior.
se presenta en el Listado 8. Y, también vamos girando la rueda (wheel) se desplaza la posi- De este modo es posible lograr recorridos
a añadir la siguiente variable de instancia a la ción del eje Y de la cámara teniendo en cuen- muy interesantes por el laberinto mientras
clase Game1: ta el delta del movimiento. Esto es necesario transcurre el juego (ver las Figuras 9 y 10).

SOLO PROGRAMADORES nº 172 40 www.revistasprofesionales.com


XNA 4:XNA 4 5/6/09 11:27 Página 41

ALGORITMOS
XNA Framework 2.0 y 3.0:
DirectX y Direct3D en C# para mortales (y IV)

Esta es una de las posibilidades de gestión de


la cámara, por supuesto que existen muchí-
simas más opciones, bastará con utilizar los
conocimientos adquiridos en estas entregas
y experimentar.

Nivel 19: Detectando colisiones con


el escenario
¿Cómo hacemos para detectar si la esfera
que representa el volumen de uno de los per-
sonajes intersecta con uno de los bloques
que conforman los elementos del laberinto
(una pared)? No es para nada sencillo.
Una de las mejores opciones es verificar si un
rayo proyectado intersecta con el modelo. El
algoritmo es complejo y requiere acceder a
Figura 9. La novia esperando impaciente a su amado ratón vista desde cerca.
los vértices del modelo. Por eso anteriormen-
te añadimos esa información a través del
procesador personalizado del modelo.
Para conseguir este objetivo tomamos como
base el algoritmo desarrollado por Tomas
Akenine-Möller y Eric Haines para verificar si
un rayo intersecta con un triángulo, realizan-
do las transformaciones necesarias.
El código de los métodos que se añaden a la
clase Personaje para poder detectar la coli-
sión con cualquier punto del escenario se
presenta en el Listado 9.
El rayo será una proyección del punto central
que identifica a la posición del personaje (no
pretendemos una precisión total, sino sería
mucho más complejo).
Como estamos tomando la posición central
del modelo para ver si el rayo colisiona con
un elemento del laberinto, dependiendo la
posición de la cámara, tendremos resultados Figura 10. El movimiento de las cámaras en tiempo real es una de las grandes ventajas
de las aplicaciones 3D.
diferentes. Habrá momentos en los cuales
con un ángulo determinado los personajes
podrán avanzar o se quedarán trabados. La
solución a esto es utilizar mapas de los terre-
nos o de los escenarios, pero, son menos
interesantes para otras clases de aplicaciones
3D. En cambio, saber cómo detectar una coli-
sión por rayo a triángulo nos permite por
ejemplo, tomar las coordenadas del puntero
del ratón para poder seleccionar triángulos u
objetos de un modelo 3D presentado en pan-
talla, y por ejemplo, ofrecer un menú con
diferentes texturas.
Combinando las presentaciones, movimientos
de cámara y de elementos, cambios de textu-
ras y detección de colisiones que vimos hasta
este momento, se pueden desarrollar el 80%
de las aplicaciones 3D que se solicitan en el
Figura 11. El ratón puede colocar solamente una parte de su cabeza en la pared, después,
ya no logra avanzar más por el sistema de detección de colisiones implementado. mercado actual. Para juegos complejos, por

www.revistasprofesionales.com 41 SOLO PROGRAMADORES nº 172


XNA 4:XNA 4 5/6/09 11:27 Página 42

ALGORITMOS

El código para detección de colisiones con el escenario


LISTADO 9 que se añade a la clase Personaje.
/// <summary>
/// Determina si un rayo intersecta a un modelo
/// </summary>
static float? DistanciaPuntoInterseccionYModelo(Ray poRayo, Model pmModeloAVerificar, Matrix poTransformacionModelo, out
bool obDentroDeBoundingSphere, out Vector3 obVertice1, out Vector3 obVertice2, out Vector3 obVertice3)
{
obVertice1 = Vector3.Zero;
obVertice2 = Vector3.Zero;
obVertice3 = Vector3.Zero;
Matrix loTransformacionInversa = Matrix.Invert(poTransformacionModelo);
poRayo.Position = Vector3.Transform(poRayo.Position, loTransformacionInversa);
poRayo.Direction = Vector3.TransformNormal(poRayo.Direction, loTransformacionInversa);
Dictionary<string, object> loDiccionario = (Dictionary<string, object>)pmModeloAVerificar.Tag;
if (loDiccionario == null)
{
throw new InvalidOperationException("No se ha utilizado el procesador personalizado para cargar este modelo a la
tubería de contenidos.");
}
// Primero verificar si está dentro de la esfera
BoundingSphere loBoundingSphereModelo = (BoundingSphere)loDiccionario["BoudingSphereModelo"];
if (loBoundingSphereModelo.Intersects(poRayo) == null)
{
obDentroDeBoundingSphere = false;
return null;
}
else
{
obDentroDeBoundingSphere = true;
float? liInterseccionMasCercana = null;
Vector3[] lavVertices = (Vector3[])loDiccionario["Vertices"];
for (int i = 0; i < lavVertices.Length; i += 3)
{
float? liInterseccion;
IntersectaRayoAlTriangulo(ref poRayo, ref lavVertices[i], ref lavVertices[i + 1], ref lavVertices[i + 2], out liInterseccion);
if (liInterseccion != null)
{
if ((liInterseccionMasCercana == null) || (liInterseccion < liInterseccionMasCercana))
{
// Almacenar la distancia al triángulo
liInterseccionMasCercana = liInterseccion;
// Transformar las tres posiciones de vértices en el espacio del mundo
Vector3.Transform(ref lavVertices[i], ref poTransformacionModelo, out obVertice1);
Vector3.Transform(ref lavVertices[i + 1], ref poTransformacionModelo, out obVertice2);
Vector3.Transform(ref lavVertices[i + 2], ref poTransformacionModelo, out obVertice3);
}
}
}
return liInterseccionMasCercana;
}
}
/// <summary>
/// Verifica si un rayo intersecta a un triangulo
/// Se emplea el algoritmo desarrollado por Tomas Akenine-Möller y Ben Trumbore
/// </summary>
static void IntersectaRayoAlTriangulo(ref Ray poRayo, ref Vector3 pvVertice1, ref Vector3 pvVertice2, ref Vector3 pvVertice3,
out float? piResultado)
{
Vector3 lvEje1;
Vector3 lvEje2;
Vector3.Subtract(ref pvVertice2, ref pvVertice1, out lvEje1);
Vector3.Subtract(ref pvVertice3, ref pvVertice1, out lvEje2);
// Calcular el determinante
Vector3 lvDireccionDeCruceEje2;
Vector3.Cross(ref poRayo.Direction, ref lvEje2, out lvDireccionDeCruceEje2);
float liDeterminante;
Vector3.Dot(ref lvEje1, ref lvDireccionDeCruceEje2, out liDeterminante);
// El rayo es paralelo al plano del triángulo, por lo tanto no hay colisión
if (liDeterminante > -float.Epsilon && liDeterminante < float.Epsilon)
{
piResultado = null;
return;
}

SOLO PROGRAMADORES nº 172 42 www.revistasprofesionales.com


XNA 4:XNA 4 5/6/09 11:27 Página 43

ALGORITMOS
XNA Framework 2.0 y 3.0:
DirectX y Direct3D en C# para mortales (y IV)

El código para detección de colisiones con el escenario


LISTADO 9 que se añade a la clase Personaje. (continuación)
float liDeterminanteInverso = 1.0f / liDeterminante;
Vector3 lvVectorDeDistancia;
Vector3.Subtract(ref poRayo.Position, ref pvVertice1, out lvVectorDeDistancia);
float liTrianguloU;
Vector3.Dot(ref lvVectorDeDistancia, ref lvDireccionDeCruceEje2, out liTrianguloU);
liTrianguloU *= liDeterminanteInverso;
if (liTrianguloU < 0 || liTrianguloU > 1)
{
piResultado = null;
return;
}
Vector3 lvDistanciaDeCruceEje1;
Vector3.Cross(ref lvVectorDeDistancia, ref lvEje1, out lvDistanciaDeCruceEje1);
float liTrianguloV;
Vector3.Dot(ref poRayo.Direction, ref lvDistanciaDeCruceEje1, out liTrianguloV);
liTrianguloV *= liDeterminanteInverso;
if (liTrianguloV < 0 || liTrianguloU + liTrianguloV > 1)
{
piResultado = null;
return;
}
// Calcular la distencia a lo largo del rayo hacia el triángulo
float liDistanciaDelRayo;
Vector3.Dot(ref lvEje2, ref lvDistanciaDeCruceEje1, out liDistanciaDelRayo);
liDistanciaDelRayo *= liDeterminanteInverso;
if (liDistanciaDelRayo < 0)
{
piResultado = null;
return;
}
// El resultado es la distancia del rayo si pasó todas las pruebas, colisiona
piResultado = liDistanciaDelRayo;
}
/// <summary>
/// Determina si el personaje, en su posición actual, colisiona con alguna pared o elemento del laberinto
/// </summary>
public bool HayColisionConEscenario()
{
bool lbHuboColision = false;
Matrix loMatrizProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f), poGame.RelacionDeAspecto, 1.0f, 100000.0f);
Matrix loMatrizView = Matrix.CreateLookAt(poGame.PosicionDeCamara, Vector3.Zero, Vector3.Up);
Matrix loMatrizWorld = Matrix.CreateTranslation(0, 0, 0);
Vector3 lvFuenteCercana = GraphicsDevice.Viewport.Project(pvPosicion, loMatrizProjection, loMatrizView, loMatrizWorld);
lvFuenteCercana.Z = 0f;
Vector3 lvFuenteLejana = GraphicsDevice.Viewport.Project(pvPosicion, loMatrizProjection, loMatrizView, loMatrizWorld);
lvFuenteLejana.Z = 1f;
Vector3 lvPuntoCercano = GraphicsDevice.Viewport.Unproject(lvFuenteCercana, loMatrizProjection, loMatrizView, Matrix.Identity);
Vector3 lvPuntoLejano = GraphicsDevice.Viewport.Unproject(lvFuenteLejana, loMatrizProjection, loMatrizView, Matrix.Identity);
// Buscar la dirección del vector que va desde el punto cercano al lejano y normalizarla
Vector3 lvDireccionLejanoACercano = lvPuntoLejano - lvPuntoCercano;
lvDireccionLejanoACercano.Normalize();
// Crear un nuevo rayo utilizando el punto cercano como fuente
Ray loRay = new Ray(lvPuntoCercano, lvDireccionLejanoACercano);
Vector3 vertex1, vertex2, vertex3;
bool insideBoundingSphere;
// El rayo es el punto central del modelo
// El escenario del cual se va a verificar triángulo por triángulo es el laberinto con sus paredes
// Llevar a cabo la verificación de existencia de intersección entre el rayo (punto central del modelo) y el laberinto
float? intersection = DistanciaPuntoInterseccionYModelo(loRay, poGame.Escenario.pmModelo,
Matrix.CreateTranslation(Vector3.Zero),
out insideBoundingSphere, out vertex1, out vertex2, out vertex3);
lbHuboColision = (intersection != null);
return lbHuboColision;
}

www.revistasprofesionales.com 43 SOLO PROGRAMADORES nº 172


XNA 4:XNA 4 5/6/09 11:27 Página 44

ALGORITMOS

El código que se añade a la clase Gato para conseguir que


LISTADO 10 se desplacen buscando al ratón o intentando hacerlo.
protected void DesplazarseAlMejorX(Vector3 pvDistancia, ref int liLlamadas)
{
liLlamadas++;
// Pasaron 2 llamadas y no se pudo desplazar
if (liLlamadas == 2)
{
DesplazarAleatorio();
}
else
{
// El gato está más lejos en el eje X del ratón, trato de acercarme a él
if (pvDistancia.X > 0)
{
// Muevo al modelo hacia la izquierda, -X
if (!ProbarDesplazarIzquierda())
{
DesplazarseAlMejorZ(pvDistancia, ref liLlamadas);
}
}
else
{
// El gato está más lejos en el eje Z del ratón, trato de acercarme a él
if (!ProbarDesplazarDerecha())
{
DesplazarseAlMejorZ(pvDistancia, ref liLlamadas);
}
}
}
}
protected void DesplazarAleatorio()
{
Random loRandom = new Random();
switch (loRandom.Next(1, 4))
{
case 1:
ProbarDesplazarAbajo();
break;
case 2:
ProbarDesplazarArriba();
break;
case 3:
ProbarDesplazarIzquierda();
break;
case 4:
ProbarDesplazarDerecha();
break;
}
}
protected void DesplazarseAlMejorZ(Vector3 pvDistancia, ref int liLlamadas)
{
liLlamadas++;
// Pasaron 2 llamadas y no se pudo desplazar
if (liLlamadas == 2)
{
DesplazarAleatorio();
return;
}
// El gato está más cerca en el eje Z del ratón, trato de acercarme a él
if (pvDistancia.Z > 0)
{
// Muevo al modelo hacia arriba
if (!ProbarDesplazarArriba())
{
DesplazarseAlMejorX(pvDistancia, ref liLlamadas);
}
}
else
{
// El gato está más cerca en el eje Z del ratón
// Muevo al modelo hacia abajo
if (!ProbarDesplazarAbajo())
{
DesplazarseAlMejorX(pvDistancia, ref liLlamadas);
}
}
}
public void Desplazarse(Ratón poRaton)
{
int liLlamadas = 0;
Vector3 lvDistancia = (pvPosicion - poRaton.Posicion);
if ((Math.Abs(lvDistancia.X)) > (Math.Abs(lvDistancia.Y)))
{
DesplazarseAlMejorX(lvDistancia, ref liLlamadas);
}
else
{
DesplazarseAlMejorZ(lvDistancia, ref liLlamadas);
}
}

SOLO PROGRAMADORES nº 172 44 www.revistasprofesionales.com


XNA 4:XNA 4 5/6/09 11:27 Página 45

ALGORITMOS
XNA Framework 2.0 y 3.0:
DirectX y Direct3D en C# para mortales (y IV)

Figura 11.

supuesto que hay que investigar mucho más, Es importante aclarar que no se buscó un Nivel 21: Añadiendo lógica
pero, sin dudas, será un muy buen punto de algoritmo perfecto de búsqueda al ratón,
partida para arrancar (ver la Figura 11). pues recordemos que los gatos tienen Resta añadir la lógica para que cuando se
mayor velocidad de desplazamiento. Eso se detecta la colisión entre los personajes,
Nivel 20: Conduciendo automáticamente iría mejorando en futuros niveles. suceda algo en el juego. Por ejemplo, la
a los gatos Si no se logra desplazar en la dirección que cámara podría tomar un primer plano del
más le conviene, busca en la otra dirección, ratón y su novia añadiendo un corazón y
No vamos a añadir una inteligencia artifi- pero si no lo logra en varias pasadas, toma bailando juntos.
cial sofisticada, que sería lo ideal. Pero, una decisión aleatoria (ver la Figura 12). Los gatos podrían desaparecer, cambiar el
queremos que los gatos intenten, de un Como la rotación de los personajes no es per- color de fondo, pasar de nivel dibujando un
modo sencillo y no muy elaborado, perse- fecta, se pueden notar efectos como que el nuevo escenario con diferentes texturas y
guir al ratón para que el juego tenga senti- gato da vueltas una y otra vez. Esto se debe nuevos personajes.
do. Con sus limitaciones por tratarse de un a que buscar una rotación perfecta de los En el Listado 11 podemos ver el código que
caso de ejemplo y por razones de espacio, personajes implicaría modelos más comple- añade simplemente llamadas a métodos en el
pero atractivo al fin. jos y mayor cantidad de código. método Update de la clase Game1 para veri-
Para ello, vamos a añadir el código que se
Las últimas líneas del código del método
Update de la clase Game1.
muestra en el Listado 10 a la clase Gato.
Luego, hay que eliminar el comentario para LISTADO 11
las dos líneas que figuraban comentadas en if (poRatón.HayColision(poGato1))
{
el método Update de la clase Game1: // El gato 1 se comió al ratón
poGato1.Desplazarse(poRatón); this.Exit();
}
poGato2.Desplazarse(poRatón); if (poRatón.HayColision(poGato2))
{
El método desplazarse recibe como pará- // El gato 2 se comió al ratón
this.Exit();
metro el personaje objetivo, que en ambos }
casos es la instancia que representa al
if (poRatón.HayColision(poNoviaRatón))
ratón. {
Según la distancia que hay entre el gato y // El ratón alcanzó la salida del laberinto
el ratón en los 2 ejes (X y Z) que se tienen this.Exit();
}
en cuenta en el juego, buscará desplazarse
al mejor X o al mejor Z. Las paredes hacen poGato1.Desplazarse(poRatón);
poGato2.Desplazarse(poRatón);
su juego y se pueden interponer, volviendo
loco al gato. base.Update(gameTime);

www.revistasprofesionales.com 45 SOLO PROGRAMADORES nº 172


XNA 4:XNA 4 5/6/09 11:27 Página 46

ALGORITMOS

Figura 12. ¡El ratón está en aprietos!

ficar las colisiones y tomar acciones en base a Y, por qué no, añadir un perro que busque a nes típicas para conseguir aprovechar las
ello. Se muestran las últimas líneas que se los gatos en un laberinto mucho más grande capacidades de DirectX y Direct3D.
añaden y que reemplazan a las anteriores. y con cámaras que se van desplazando a Es verdad que hay muchas más técnicas y
En este caso, solamente se sale del juego sea medida que el personaje activo se escape de complejidades en esta clase de aplicacio-
ganador o perdedor el ratón. la vista de la cámara. Es muy sencillo aplican- nes. Pero, combinando las capacidades de
do todos los patrones aprendidos. El método las herramientas de creación de contenido
Nivel 21: Selección de personajes y para Desplazarse programado para el gato digital con XNA Framework y con mucha
presentación recibe como parámetro el personaje objetivo. experimentación, prueba y error, se pueden
Se pueden generar grandes laberintos donde conseguir resultados sorprendentes en
La típica selección de personajes los presenta todos se corren y las novias los pueden espe- poco tiempo.
rotando. Es muy sencillo conseguirlo con rar en cada salida posible. Con estas entregas se buscó presentar casos
todos los conocimientos adquiridos. Sabemos Más allá del juego, con la aparición de la típicos para juegos y otras aplicaciones 3D
cómo presentar un modelo 3D y cómo cam- versión definitiva de XNA Game Studio 3.0, que tanta demanda tienen en los tiempos que
biarle texturas. Como utilizamos código orien- este marco de trabajo se está convirtiendo corren y que seguirán vigentes por muchos
tado a objetos, es muy sencillo añadir nuevos en el estándar para el desarrollo de aplica- años más.
personajes. Hay que trabajar un poco en la lógi- ciones 3D y 2D con aceleración con gran Vale la pena seguir experimentando. El
ca de presentación y en los estados del juego. velocidad para el mundo de las PC, Xbox mundo de las aplicaciones 3D es complejo,
360 y Zune. pero a la vez apasionante y extremadamente
Nivel 22: Añadiendo niveles entretenido. Una vez que se empieza, no se
Conclusión puede abandonar.
En la clase Game1 se mantiene toda la lógica
de funcionamiento del juego. Cambiando A lo largo de estas entregas hemos presen- Más información
colores de fondo, texturas y escenarios, es tado muchas de las características ofreci- Real-Time Rendering; Tomas Akenine-Möller y
muy sencillo gestionar los niveles del juego, das por XNA Game Studio en sus diferentes Eric Haines, AK Peters Ltd, 2nd edition, July 2002.
así como ir incrementando la velocidad de versiones 2.0 y 3.0. Presentando el ejemplo Presenta excelentes algoritmos que se pueden
los adversarios del pobre ratón. de un juego vimos muchas de las operacio- aplicar a aplicaciones 3D complejas.

SOLO PROGRAMADORES nº 172 46 www.revistasprofesionales.com


Super Oferta Solop:Super Oferta Solop 14/1/09 11:55 Página 1

SÚPER OFERTA
¡Aprovecha la ocasión
y suscríbete ya!

66 €
SUSCRIPCION A
SOLO PROGRAMADORES
FORMATO PAPEL
+ FORMATO DIGITAL

Para nuevas suscripciones y renovaciones de


suscripción tanto en papel como digital a la
revista “Solo Programadores” ofrecemos
una oferta única y sin precedentes.
Ahora es posible la suscripción en
papel + la suscripción digital, por
solo 66 € para España, resto de
paises consultar en la web.
De esta forma, tendrás las ventajas
de ambas modalidades: con la
suscripción en papel la posibilidad
de leer la revista en cualquier lugar y
disponer de los contenidos incluidos
en el CD de regalo.
Por otra parte, con la opción digital
podrás acceder a los contenidos de la revista
15 días antes de que la versión en papel esté
disponible, además, podrás disfrutar de los contenidos
no disponibles en la versión papel (cursos, etc.) con la
ventaja adicional de ahorro de espacio físico.

Suscríbete en
www.revistasprofesionales.com
Curso C++ (V):Curso C++ (II) 5/6/09 11:33 Página 48

ALGORITMOS

Programación orientada
a objetos con C++ (V)
Primeramente se declara una variable s que es de
ADOLFO ALADRO GARCÍA

La librería estándar de C++


tipo string, y que inicialmente guarda la cadena
vacía. La función showStringInfo, también

proporciona un gran número de


implementada en el fichero main.cpp, muestra

clases, funciones y procedimientos


por la salida estándar la cadena de texto y tres de

para llevar a cabo todo tipo de


sus atributos principales:
void showStringInfo(const string& s) {

tareas. Implementar todo tipo de


cout << s << “\n”;

clases es un excelente ejercicio


cout << “...length = “ << s.length() << “\n”;

durante la fase de aprendizaje de


cout << “...capacity = “ << s.capacity()

C++. Después, antes de hacer


<< “\n”;

cualquier desarrollo hay que tener en


cout << “...max_size = “ << s.max_size()
<< “\n\n”;

cuenta la librería estándar, porque es


};

muy probable que ya esté resuelto.


El método length devuelve el número de carac-

En esta entrega se verá un resumen


teres. El método capacity devuelve la capacidad
máxima que en ese momento tiene el objeto

de algunas de las librerías más


para almacenar caracteres. Finalmente el méto-

comunes.
do max_size devuelve el número máximo de
caracteres que un objeto de tipo string puede
guardar. Volviendo al código principal del ejem-
plo, cuando se llama a showStringInfo la prime-
CADENAS DE TEXTO: LA CLASE string ra vez el resultado que aparece en la consola de
salida es el siguiente:
En la entrega anterior se comenzó con un ejerci- ...length = 0
cio que consistía en la creación de una clase que ...capacity = 0
implementara cadenas de texto, y que interna-
...max_size = 1073741820
mente trabajara con char*, el tipo estándar de C.
En realidad todo esto está ya resuelto en la libre- La cadena de texto representada por la variable s
ría estándar <string> (Y algunas otras que per- es la cadena vacía así que la primera línea está
miten realizar toda clase de tareas con las cade- vacía. Lógicamente el tamaño de la cadena es 0.
nas de texto). En el fichero main.cpp se encuen- La capacidad de la cadena en ese momento es
tran algunos ejemplos que ilustran el uso de la también 0. En último lugar, el número máximo
clase string. El primero de ellos está en la función de caracteres que puede almacenar un objeto de
main1. Es muy sencillo y consiste únicamente en tipo string es 1.073.741.820 caracteres. Después
mostrar algunos atributos básicos de objeto de se concatena la cadena de texto SPP utilizando el
tipo string: operador + y al volver a mostrar la información
void main1() { la consola muestra:
string s = “”; SPP
showStringInfo(s); ...length = 3
s = s + “SPP”; ...capacity = 3
showStringInfo(s); ...max_size = 1073741820
s.reserve(1024); La cadena es ahora SPP y así se muestra. El
showStringInfo(s); tamaño y la capacidad han tomado el valor 3. El
}; número máximo de caracteres que puede alma-

SOLO PROGRAMADORES nº 172 48 www.revistasprofesionales.com


Curso C++ (V):Curso C++ (II) 5/6/09 11:33 Página 49

ALGORITMOS
Programación orientada a objetos con C++ (V)

cenar un objeto de tipo string no ha varia-


do, como era de esperar. Seguidamente se
llama al método reserve con el valor 1024.
Este método prepara al objeto para que
tenga una capacidad determinada. Aunque
un objeto de tipo string puede crecer diná-
micamente, si se conoce de antemano el
tamaño de caracteres que va a almacenar,
es más eficiente que anticipadamente se
dote al objeto con una capacidad suficien-
te. Cuando se muestra por la consola de
nuevo la información sobre la cadena se
observa que el tamaño no ha variado, pero
la capacidad es ahora mucho mayor:
SPP
...length = 3
...capacity = 1123
...max_size = 1073741820 Resumen de las librerías estándar más importantes (1 de 2).
Como no podía ser de otro modo, la clase Los nombres de los métodos son bastantes con una longitud determinada, el segundo
string cuenta con los típicos métodos para descriptivos. El método find intenta buscar parámetro:
localizar subcadenas de texto y extraerlas si una cadena desde el principio y devuelve un string v = s.substr(s.find(“orientada”),
es preciso. En la función main2 se ven algu- valor numérico indicando la posición. El 9);
nos ejemplos sencillos que lo ilustran. Se método rfind realiza lo mismo pero la bús-
comienza creando una cadena: queda comienza desde el final de la cadena. Otras de last areas típicas que se hacen con
string s = “Programación orientada El método find_first_of intenta encontrar la cadenas de texto es compararlas con otras
a objetos con C++”; primera posición en la que aparece alguno cadenas. En C++, con la clase estándar
de los caracteres que recibe como paráme- string, esto puede realizarse de diversas
tro en forma de cadena texto. El método formas. La más directa consiste simple-
Seguidamente se emplea una batería de find_first_not_of hace la operación inver- mente en utilizar el método compare. Así,
métodos para localizar distintas subcade- sa: intenta encontrar el primero de los en la función main3 se puede observar un
nas: caracteres que no pertenece a ninguno de ejemplo:
cout << s.find(“orientada”) << “\n”; la cadena pasada. Los métodos find_last_of string s1 = “SPP”;
cout << s.rfind(“orientada”) << “\n”; y find_last_not_of son similares pero string s2 = “spp”;
empiezan a buscar por el final de la cadena.
cout << s.find_first_of(“o”) << “\n”; cout << s1 << “ = “ << s2 << “ :
En ese mismo ejemplo se encuentra un uso
cout << s.find_first_not_of(“o”) << “\n”; “ << s1.compare(s2) << “\n”;
del método substr, que se emplea para
cout << s.find_last_of(“o”) << “\n”; extraer cadenas de texto, desde una Otra manera de hacer comparaciones con-
cout << s.find_last_not_of(“o”) << “\n\n”; posición dada, el primer parámetro, y siste en utilizar la librería estándar de algo-
ritmos <algorithm>. Para ello antes hay
que definir dos funciones que comparen
caracteres simples. En main.cpp se han
definido dos: una para hacer comparacio-
nes simples, y otra para no diferenciar entre
mayúsculas y minúsculas:
bool caseInsensitiveCharCompare
(char c1, char c2) {
return(toupper(c1) == toupper(c2));
};
bool caseSensitiveCharCompare
(char c1, char c2) {
return(c1 == c2);
};

Partiendo de las funciones anteriores se


Resumen de las librerías estándar más importantes (2 de 2). han creado otras dos funciones que son las

www.revistasprofesionales.com 49 SOLO PROGRAMADORES nº 172


Curso C++ (V):Curso C++ (II) 5/6/09 11:33 Página 50

ALGORITMOS

que realmente comparan las cadenas. La


función estándar equal recibe el comienzo
y el final de la primera cadena, el comienzo
de la segunda y una referencia a la función
que se encarga de comparar los caracteres:
bool caseInsensitiveStringCompare
(const string& s1, const string& s2) {
return s1.size() == s2.size()
&& equal(s1.begin(), s1.end(), s2.begin(),
caseInsensitiveCharCompare);
};
bool caseSensitiveStringCompare
(const string& s1, const string& s2) {
return s1.size() == s2.size() &&
equal(s1.begin(), s1.end(), s2.begin(),
caseSensitiveCharCompare);
};
La utilización de las funciones recién crea-
das es muy sencilla como puede verse en el
ejemplo:
cout << s1 << “ = “ << s2 << “ :
Resultado de ejecutar la función main1 que ilustra el empleo de la clase string.
“ << caseInsensitiveStringCompare(s1,s2)
<< “\n”; co, se sigue; en otro caso se sale del bucle tareas de reserva y liberación dinámica de
cout << s1 << “ = “ << s2 << “ : “ <<
con la sentencia break: memoria ocurren de forma transparente al
for (unsigned int i=0; i<s.length(); programador.
caseSensitiveStringCompare(s1,s2) << “\n”; i++) {
char c = *it;
ARRAY DINÁMICOS: LA CLASE vector
El último ejemplo que se va a ver con res-
if (c == ‘ ‘ || c == ‘\n’ || c == ‘\r’
pecto a las cadenas de texto es cómo hacer También en las entregas anteriores se des-
|| c == ‘\t’) {
una función trim que quite los espacios en arrolló a modo de ejercicio una clase para
blanco a la izquierda y derecha. Con este it++; crear array dinámicos. Pero esta funciona-
ejercicio se puede comprobar que la clase } else { lidad ya está recogida en la librería están-
string también proporciona una forma de break; dar, a través de la clase vector. El ejemplo
recorrer los caracteres uno a uno. Además } main5 ilustra un caso simple de programa-
también es posible eliminar trozos de de } ción con la clase vector. Cuando se crea un
una cadena dinámicamente. La función contenedor de este tipo debe especificarse
trim, definida en el fichero main.cpp, recibe El último paso consiste en eliminar de la explícitamente el tipo de datos que va a
como parámetro la cadena que se quiere cadena los blancos encontrados. El método guardar. Así en el ejemplo se crea un vector
“limpiar” de espacios en blanco. El primer erase recibe dos iteradores. El primero es el cuyo propósito es almacenar objetos de
paso consiste en determinar si la cadena comienzo de la cadena. El segundo es el ite- tipo string, es decir, cadenas de texto:
está vacía, en cuyo caso no hay que hacer rador que se ha estado manejando en el vector<string> vecStr;
nada: bucle anterior y que por lo tanto está apun-
if (s.empty()) return; tando al primer carácter válido de la cadena: Para este caso se han definido tres cadenas
s.erase(s.begin(), it); de texto, recogidas en las variables s1, s2 y
Seguidamente se comienza con la elimina- s3:
ción de los blancos en la parte izquierda de La eliminación de blancos por la derecha es string s1 = “Revista”;
la cadena. Con el método begin se obtiene muy similar, con la salvedad de que se string s2 = “Sólo”;
un iterador que apunta al comienzo de la explora la cadena por la derecha, desde el
string s3 = “Programadores”;
cadena. final hasta el principio, tal y como puede
string::iterator it = s.begin(); verse en el código fuente de la función. El método push_back de la clase vector es
Hasta aquí se han visto algunos ejemplos la forma principal de añadir elementos al
La cadena puede recorrerse de muchas for- muy simples de utilización de la clase contenedor. Los elementos se van guardan-
mas pero una de ellas consiste en hacer un string. Como es de esperar, existen muchos do al final:
bucle simple teniendo en cuenta la longi- otros métodos. La clase string encapsula vecStr.push_ck(s1);
tud. En cada iteración del bucle el carácter mayor parte de las funcionalidades que vecStr.push_back(s2);
se obtiene utilizando el operador * sobre el pueda necesitar un programador a la hora
vecStr.push_back(s3);
iterador. Si el carácter resulta ser un blan- de trabajar con cadenas de texto. Todas las

SOLO PROGRAMADORES nº 172 50 www.revistasprofesionales.com


Curso C++ (V):Curso C++ (II) 5/6/09 11:34 Página 51

ALGORITMOS
Programación orientada a objetos con C++ (V)

Los vectores se pueden recorrer de dos for- El vector se declara de la misma forma, memoria dinámica de aquello que almace-
mas distintas. La primera es la más sencilla aunque ahora el tipo es string*: na, en este caso lo que almacena son direc-
y obvia. El tamaño del vector se obtiene con vector<string*> vecStr; ciones de memoria. Por lo tanto, la clase
el método size. La clase vector sobrescribe vector podría liberar el espacio dedicado a
el operador [] de tal forma que se puede La inserción de elementos es similar. Debe guardar esas direcciones, pero no el espacio
acceder a los elementos utilizando un índi- recordarse en todo momento que en reali- utilizado por los datos almacenados en esas
ca de la misma forma que se haría con un dad el vector no está almacenando las cade- direcciones. De nuevo aparece la doble
array de C: nas de texto, sino las direcciones de memo- indirección. Si se quieren eliminar las cade-
for (vector<string>::size_type i=0; ria donde dinámicamente esas cadenas han nas de texto de verdad, primero hay que
i<vecStr.size(); i++) { sido almacenadas con el operador new: recorrer el vector y con el método delete
cout << “[“ << i << “]=” << vecStr[i] vecStr.push_back(s1); borrar una a una las cadenas:
<< “\n”; vecStr.push_back(s2); for (vector<string*>::iterator
vecStr.push_back(s3); it=vecStr.begin(); it!=vecStr.end();
}
it++) {
La otra forma consiste en utilizar iterado- Para recorrer el vector se puede emplear la delete *it;
res. Como ya puede apreciar por lo visto misma técnica de los iteradores. Ahora
}
hasta el momento, los iteradores son unos bien, como ya se sabe un iterador es un
de los elementos más comunes que se puntero a un elemento. Es decir, la direc- Posteriormente, con el método clear se lim-
emplean para recorrer todo tipo de conte- ción de memoria del elemento. Pero en este pia el vector y con ello se evita que esas
nedores de datos. El método begin de la caso el elemento, que es de tipo string*, es posiciones sean utilizadas:
clase vector devuelve un iterador que también otro puntero. Por consiguiente, vecStr.clear();
apunta a la primera posición del vector. El hay una doble indirección y para mostrar el
método end hace lo propio, pero el iterador dato real, la cadena de caracteres, hay que LA CLASE map
devuelto apunta al final de la colección de aplicar el operador * dos veces:
datos. Con un bucle for resulta muy senci- for (vector<string*>::iterator Otro clásico entre los contenedores son los
llo recorrer todos los elementos. No hay it=vecStr.begin(); it!=vecStr.end(); mapas. Los mapas permiten crear pares de
que olvidar que un iterador es un puntero it++) { datos o diccionarios. La clase map de la
con lo que el acceso al elemento “real” se string* s = *it;
librería <map> proporciona esta funciona-
produce con el operador *: lidad. En la función main7 puede verse un
cout << *s << “\n”;
for (vector<string>::iterator caso muy sencillo. Al igual que ocurría con
} la clase vector, al declarar un mapa es
it=vecStr.begin(); it!=vecStr.end();
Uno de los aspectos más delicados es la necesario indicar los tipos de datos de los
it++) {
liberación de la memoria obtenida dinámi- pares. El primer tipo corresponde a las cla-
cout << *it << “\n”;
camente con el operador new. Aunque la ves. El segundo corresponde a los valores
} clase vector gestiona por sí misma la de esas claves:
Un caso que suscita bastantes problemas es
cuando los contenedores almacenan no
datos, si no punteros a datos (o si se prefie-
re, direcciones de memoria donde se
encuentran realmente los datos). Ya se ha
estudiado este caso en las entregas ante-
riores cuando se creaban clases de este
tipo. Clases como vector, y otras tantas de
la librería estándar, presentan los mismos
problemas. Aunque en realidad no hay tales
problemas sino que más bien es la mala
práctica la que puede originarlos. En ejem-
plo main6 se ilustra el uso de la clase vec-
tor, pero a diferencia del caso anterior en
este se almacenan punteros a objetos de
tipo string. De hecho las cadenas se crear
dinámicamente usando el operador new:
string* s1 = new string(“Revista”);
string* s2 = new string(“Sólo”);
string* s3 =
new string(“Programadores”); Código correspondiente a la función trim que elimina los espacios en blanco por la
derecha de la cadena de texto.

www.revistasprofesionales.com 51 SOLO PROGRAMADORES nº 172


Curso C++ (V):Curso C++ (II) 5/6/09 11:34 Página 52

ALGORITMOS

La forma de recorrer el vector es la que se ha


visto en los ejemplos anteriores. Con los ite-
radores devueltos por begin y end se va
accediendo a los elementos del vector, desde
el primero hasta el último, por lo tanto
siguiendo el orden de inserción. Como un
iterador es un puntero a un elemento, con el
operador * se accede al elemento:
for (vector<string>::iterator
it=vecStr.begin(); it!=vecStr.end();
it++) {
cout << *it << “ “;
}
cout << “\n”;
El método random_shuffle se emplea para
ordenar de forma aleatoria los elementos
Resultado de ejecutar la función main5 que ilustra el funcionamiento básico de la clase vector. de un contenedor. Recibe dos parámetros
que son iteradores. En este ejemplo los
map<string,int> mapMonths;
ALGORITMOS interadores son los devueltos por los méto-
En el ejemplo se ha hecho un mapa simple dos begin y end:
que relaciona los nombres de los meses con La librería estándar cuenta con varios proce- random_shuffle(vecStr.begin(),
su número. Como el operador [] está dimientos y funciones que permiten tratar vecStr.end());
sobrescrito, introducir datos en el mapa es contenedores (vectores, listas, mapas, etc.) de
muy fácil, como puede verse seguidamente: forma común. Uno de los casos clásicos con- Con el método sort se puede ordenar todo
siste en ordenar los elementos que se alma- tipo de contenedores de datos. Recibe dos
mapMonths[“enero”] = 1; cenan en un contenedor. La función main8 iteradores. En este caso se emplean los ite-
mapMonths[“febrero”] = 2; muestra un ejemplo sencillo. Primeramente radores devueltos por begin y end, pero
se crean unas cadenas de texto simples: podrían utilizarse otros, de modo que sort
···
string s1 = “a”; no sólo sirve para ordenar todos los datos
mapMonths[“diciembre”] = 12;
··· de un contenedor sino que puede emplear-
Una de las características fundamentales se para ordenar rangos de datos dentro de
string s5 = “u”;
de un mapa es que permite acceder a los un contenedor:
valores de forma directa utilizando las cla- Seguidamente se crea un vector para guar- sort(vecStr.begin(), vecStr.end());
ves. Esta funcionalidad está recogida por el dar las cadenas, y se insertan:
método find. Éste devuelve un iterador que vector<string> vecStr; El resultado que se muestra en la consola es
permite acceder al par, de forma que en el vecStr.push_back(s1); el esperado. La primera línea muestra las
atributo first está la clave y en el atributo cadenas de texto en el orden en el que se
···
second el valor. Como hay que acceder a los insertaron en el vector. La segunda línea
vecStr.push_back(s5);
atributos mediante un puntero, el que muestra las cadenas de texto en un orden
representa el iterador, es necesario utilizar
el operador ->:
cout << mapMonths.find(“septiembre”)
->second << “\n”;

Para recorrer un mapa pueden emplearse


los iteradores devueltos por los métodos
begin y end. El orden en el que se muestran
los pares no tiene por qué coincidir con el
orden de inserción:
for (map<string,int>::iterator it =
mapMonths.begin(); it!=mapMonths.end();
it++) {
cout << it->first << “=” << it->second
<< “\n”;
} Resultado de ejecutar la función main7 que muestra el funcionamiento de la clase map.

SOLO PROGRAMADORES nº 172 52 www.revistasprofesionales.com


Curso C++ (V):Curso C++ (II) 5/6/09 11:34 Página 53

ALGORITMOS
Programación orientada a objetos con C++ (V)

casos. Al realizar las comparaciones con


equal, en main10 resulta que los vectores
son iguales y en main11 son diferentes, a
pesar de que las cadenas son iguales. Esto
ocurre porque simplemente en main11 lo que
se compara en realidad son las direcciones de
memoria donde están almacenadas las cade-
nas, no las cadenas mismas. De nuevo de
trata de la situación que se produce cuando
se utilizan las clases como vector para alma-
cenar punteros a datos y no los datos mis-
mos. Es preciso insistir en que hacer esto no
tiene nada de malo, de hecho es muy útil en
muchas ocasiones. Simplemente hay que
tener cuidado a lo hora de tratar estos con-
Ejemplo de utilización de las funciones de la librería estándar algorithm.
tenedores para evitar resultados inesperados.
aleatorio. Por último la tercera línea mues- if (lexicographical_compare
tra las cadenas de texto ordenadas: (vecStr1.begin(), CONCLUSIÓN
a e i o u vecStr1.end(), vecStr2.begin(),
u e o i a vecStr2.end())) { Clases como string, vector o map, soportadas
cout << “Iguales\n”; por la librería estándar de C++, cubren buena
a e i o u
parte de las necesidades que todo programa-
} else {
Al comienzo de este artículo se estudió un dor tiene cuando desarrolla una aplicación.
cout << “Diferentes\n”;
ejemplo de utilización de la función equal Hacer una descripción detallada de todas las
para comparar cadenas de texto. Pues bien, } librerías, con sus clases, funciones y procedi-
la gran potencia y versatilidad del API En este caso el resultado arrojado es que los mientos, excede con mucho la extensión de
estándar en lo que a los algoritmos se refie- vectores son diferentes ya que la función estos artículos. Aquí sólo se ha querido mos-
re es que sus funciones y procedimientos diferencia entre mayúsculas y minúsculas. Es trar el uso de alguno de los casos más comu-
pueden emplearse en todo tipo de clases importante observar que en todos estos nes. Familiarizarse con el API estándar es una
que actúan como contenedores de datos. casos se están comparando vectores que de las tareas que todo desarrollador tiene
En la función main9 puede verse un ejem- almacenan cadenas, o dicho con propiedad, que ponerse como meta si quiere aprender a
plo en el que se comparan dos vectores que rangos de elementos dentro de esos vectores. programar en C++ con cierta soltura. En
almacenan cadenas de texto. Las cadenas Finalmente es muy interesante estudiar las Internet hay multitud de referencias comple-
se declaran como es habitual: diferencias entre los ejemplos expuestos en tas con ejemplos fáciles de seguir. En la
string s11 = “Solo”; las funciones de ejemplo main10 y main11, entrega que queda se estudiará la parte de la
string s12 = “Programadores”; que utilizan la técnica anterior para compa- librería que se refiere a la entrada/salida. Las
rar vectores. En main10 los vectores almace- clases específicas de entrada/salida tienen
string s21 = “SOLO”;
nan datos de tipo string. En main11 los vec- sus propias características, bien diferenciadas
string s22 = “PROGRAMADORES”;
tores almacenan datos de tipo string*. Las de otras clases string o vector, que son con-
El método equal recibe los iteradores que cadenas de texto son idénticas en todos los tenedores de datos.
devuelven los métodos begin y end del vec-
tor, y utiliza la función caseInsensitive
StringCompare para realizar la comparación:
if (equal(vecStr1.begin(),
vecStr1.end(), vecStr2.begin(),
caseInsensitiveStringCompare)) {
cout << “Iguales\n”;
} else {
cout << “Diferentes\n”;
}
El resultado que muestra la consola des-
pués del ejecutar el código anterior es el
esperado: los vectores comparados son
iguales. Existe otra función denominada
lexicographical_compare que permite tam- En la función main11 se utiliza la clase vector para almacenar punteros a datos de tipo
bién hacer este tipo de comparaciones: string.

www.revistasprofesionales.com 53 SOLO PROGRAMADORES nº 172


Cookies:REDES-RSS Java 1 5/6/09 11:35 Página 54

REDES

Cookies en el navegador
y en el servidor (II)
ADOLFO ALADRO GARCÍA detalles de la sintaxis, en casi todas las tecnolo-

Después de haber visto el tratamiento


Ingeniero superior de informática. gías es parecido. Las cookies están almacenadas
en las cabeceras de los mensajes HTTP. Todas

y gestión de las cookies en el


estas librerías lo único que hacen es interpretar

navegador, es el momento de hacer lo


esas cabeceras y hacerlas más accesibles al pro-

propio para el servidor. Todas las


gramador; o escribirlas, también facilitando el
trabajo del programador. Los ejemplos que van a

tecnologías de servidor (Java, Perl,


mostrarse en este artículo están hechos en Java.

ASP, PHP, etc.) poseen librerías muy


Lo cierto es que no es relevante. Puede extrapo-

parecidas para leer y escribir cookies.


larse fácilmente a cualquier otro lenguaje.

La visión completa cliente-servidor


LEER COOKIES

permitirá introducir aspectos más


En Java se leen las cookies con el método

avanzados como las restricciones de


getCookies del objeto HttpServletRequest.
Devuelve un array de objetos Cookie. Si el array

seguridad con los dominios y los


es distinto de null y el valor de la propiedad

problemas de la codificación de los


length es mayor que 0, entonces significa que la

caracteres.
petición llegada al servidor contiene cookies:
Cookie[] arrCookie = req.getCookies();
if (arrCookie==null ||
arrCookie.length==0) {
EN EL SERVIDOR ···
} else {
Dependiendo del lenguaje de programación
empleado, la forma de leer y escribir las cookies ···
en el servidor, cambia. Sin embargo salvando los }

Documentación de la clase Cookie del API estándar de Java.

SOLO PROGRAMADORES nº 172 54 www.revistasprofesionales.com


Cookies:REDES-RSS Java 1 5/6/09 11:35 Página 55

REDES
Cookies en el navegador y en el servidor (II)

El array de objetos Cookie puede recorrerse


con un bucle for muy sencillo:
for(Cookie cookie : arrCookie) {···}

Cada objeto Cookie almacena toda la infor-


mación relativa a una cookie. El API proce-
sa por el programador las cabeceras HTTP
de la petición y en lo que a las cookies res-
pecta, crea esta estructura de datos para
facilitar el trabajo. La clase Cookie cuenta
con varios métodos de lectura entre los que
destacan:
 String getDomain()
Devuelve el dominio.
 int getMaxAge()
Devuelve un valor numérico que indi-
ca el máximo tiempo de duración de la
Fragmento de código, perteneciente al servlet responsible de la página cookies.html, que lee las
cookie en segundos. Cuando devuelve cookies.
-1 significa que es una cookie de
sesión, es decir, que desaparecerá
cuando el usuario cierre el navegador.
 String getName()
Devuelve el nombre de la cookie.
 String getPath()
Devuelve la ruta (path) de la cookie.
 String getValue()
Devuelve el valor de la cookie.
El siguiente ejemplo resumido, recogido en la
clase SCookies de los ejemplos, ilustra de
forma muy simple cómo es posible generar
dinámicamente un fragmento de una página
HTML con las cookies leídas en el servidor:
bw.write(“<table border=\”0\”
cellpadding=\”0\”cellspacing=\”0\”>”);
for(final Cookie cookie : arrCookie) {
bw.write(“<tr><td>”);
bw.write(cookie.getName()); El servlet llamado SSetCookie devuelve una cadena de texto plano y establece una cookie
llamada date4.
bw.write(“</td><td>”);
···
bw.write(URLDecoder.decode la cookie: dominio, ruta, etc. El paso último
(cookie.getValue(), “UTF-8”)); consiste en “añadir” la cookie a la respues- bw = new BufferedWriter

bw.write(“</td></tr>”); ta con el método addCookie del objeto new OutputStreamWriter

} HttpServletResponse. Al igual que sucede (res.getOutputStream(),


con el establecimiento de las cabeceras Charset.forName(“UTF-8”)));
bw.write(“</table>”);
HTTP de la respuesta, es de vital importan-
ESCRIBIR COOKIES cia que la llamada a addCookie se haga Los métodos setXXX de la clase Cookie prin-
En el ejemplo, el servlet SSetCookie está siempre antes de acceder al canal de escri- cipales son:
disponible en la URL http://www.revistas tura con getOutputStream:  void setDomain(String s)
profesionales.com/SSetCookie. Devuelve Cookie cookie = new Cookie(“date4”, Establece el dominio. Si se intenta
una cadena de texto plana (text/plain) con URLEncoder.encode(simpleDateFormat. establecer un dominio que no es váli-
un OK. Además presenta un ejemplo de format(new Date()), “UTF-8”));
do, no se produce ningún error.
cómo se establecer las cookies con Java en Simplemente se genera la correspon-
cookie.setDomain(“.revistas
el servidor. El constructor de la clase Cookie diente cabecera HTTP y cuando ésta
profesionales.com”);
recibe dos parámetros. El primero es el llega al navegador, es rechazada.
nombre de la cookie y el segundo es el cookie.setPath(“/”);  void setMaxAge(int i)
valor. Seguidamente se emplean los méto- cookie.setMaxAge(60*60*24); Establece la caducidad de la cookie. Un
dos setXXX para establecer los atributos de res.addCookie(cookie); valor positivo indica que la cookie

www.revistasprofesionales.com 55 SOLO PROGRAMADORES nº 172


Cookies:REDES-RSS Java 1 5/6/09 11:35 Página 56

REDES

nes %xx. La función decodeURIComponent


hace el proceso contrario.
En el servidor, en el ejemplo en Java, se han
empleado las siguientes expresiones para
codificar y decodificar el valor de las
cookies:
URLEncoder.encode(···, “UTF-8”)
URLDecoder.decode(···, “UTF-8”)

El método encode de la clase URLEncoder


sirve para convertir una cadena de texto en
un formato compatible con application/x-
www-form-urlencoded. Los caracteres
alfanuméricos, de la ‘a’ a la ‘z’, de la ‘A’ a la
‘Z’ y del ‘0’ al ‘9’, no te modifican. Los carac-
teres ‘.’, ‘-’, ‘*’ y ‘_’ tabién se mantienen. El
espacio en blanco se sustituye por el sím-
Página cookies.html que se muestra en el dominio www.revistasprofesionales.com, antes de bolo ‘+’. El resto de los caracteres se con-
establecer ninguna cookie. vierten a uno o varios bytes en función del
esquema de codificación, que en el ejemplo
es UTF-8. Y a partir de ahí se obtienen las
expresiones %xx de la misma forma que
con encodeURIComponent en el navegador.
Cuando una aplicación Web lee y escribe
cookies siempre en el lado del servidor, o
siempre en el lado del navegador, no hay
problemas. El problema de la codificación
viene cuando una aplicación Web lee y
escribe cookies indistintamente en el nave-
gador y en el servidor. La razón es que las
funciones para codificar y decodificar no
son exactamente iguales, como se puede
comprobar por la descripción anterior. No
existe una solución simple para este pro-
blema y depende en buena medida de la
funcionalidad misma de la aplicación Web.
En cada caso habrá que estudiar que tipo
Página cookies.html que se muestra en el dominio www.revistasprofesionales.com, después de
establecer las cookies. de datos se guardan exactamente en las
cookies y como es el flujo de la información
caducará cuando pase ese número de decodificar los valores de las cookies son entre el servidor y el navegador.
segundos a partir del momento del respectivamente encodeURIComponent y
establecimiento. Un valor igual a 0 decodeURIComponent. La función encode COOKIES Y LAS LLAMADAS AJAX
indica que la cookie ha de eliminarse, o URIComponent codifica las cadenas de
lo que es lo mismo, que caduca inme- texto de forma que los caracteres ASCII, Hoy en día las llamadas AJAX forman parte,
diatamente. Por último un valor nega- letras y dígitos, no se tocan, lo mismo que en mayor o menor medida, de casi todas las
tivo indica que se trata de una cookie los siguientes caracteres: aplicaciones Web. Las cookies también pue-
de sesión, por lo que desaparecerá - _ . ! ~ * ‘ ( ) den jugar un papel importante en este tipo
cuando el usuario cierre el navegador. de desarrollos. Además existe un vínculo
 void setPath(String s) El resto de los caracteres (incluyendo ‘/’,‘:’, y entre ambas tecnologías en el sentido de
Establece la ruta (path) de la cookie. ‘#’, que son propios de las URL) se sustitu- que están sujetas a restricciones de seguri-
 void setValue(String s) yen por los códigos de escape en hexadeci- dad muy parecidas en lo que respecta a los
Establece el valor. mal que se construyen de la siguiente dominios. Por todo ello las llamadas AJAX
forma: dado un carácter se convierte a UTF- no pueden usarse como “truco” para com-
PROBLEMAS DE LA CODIFICACIÓN DE 8 y los bytes resultantes se codifican con partir cookies entre distintos dominios que
CARACTERES una expresión %xx en hexadecimal. ni siquiera comparten la misma raíz, como
En el navegador las funciones estándar de Dependiendo de la conversión a UTF-8 pue- se analizará en la siguiente entrega.
Javascript que se emplean para codificar y den ser necesarias una, dos o tres expresio- No es el propósito de este artículo profun-

SOLO PROGRAMADORES nº 172 56 www.revistasprofesionales.com


Cookies:REDES-RSS Java 1 5/6/09 11:35 Página 57

REDES
Cookies en el navegador y en el servidor (II)

dizar en la implementación de las llamadas


AJAX cross-browser (válidas para todos los
navegadores), pero para ilustrar el uso de
las cookies va a proponerse un modelo muy
simple. En el fichero cookies.js se ha creado
un objeto HttpRequestUtil con un método
estático createHttpRequest:
var HttpRequestUtil = {
createHttpRequest: function() {
···
}
};
El método intenta crear un objeto
XmlHttpRequest de dos formas distintas. La
primera es usando tecnología ActiveX y la
segunda empleando un objeto nativo:
Página cookies.html que se muestra en el dominio cookies.revistasprofesionales.com, después de
var oXmlHttpReq = null; establecer las cookies.
if (window.ActiveXObject && !
window.XMLHttpRequest) {
···
} else {
···
}
return oXmlHttpReq;

Cuando el objeto window cuenta con la


propiedad ActiveXObject y además no
cuenta con la propiedad XMLHttpRequest,
se intenta crear una instancia del objeto
ActiveX de versión más moderna:
var arrMSXML = new
Array(“MSXML2.XMLHTTP.5.0”,···,
“MICROSOFT.XMLHTTP”);
Página después de que se haya establecido la cookie llamada date4 mediante una llamada
var iArrMSXMLLength = arrMSXML.length; AJAX.
for (var i=0; oXmlHttpReq==null &&
Cuando se hace una llamada AJAX desde un es necesario hacer nada de esto. El objeto
i<iArrMSXMLLength; i++) {
navegador, ésta está sujeta a las mismas XMLHttpRequest se encarga de leer las
try { reglas del protocolo HTTP que las páginas cabeceras Set-Cookie y establecer las coo-
oXmlHttpReq = Web “normales”. En este sentido las cabece- kies que sean precisas en cada caso.
new ActiveXObject(arrMSXML[i]); ras HTTP de petición y respuesta se trans- var oXmlHttpReq =
} catch (e) { miten de la misma forma, son las mismas, y HttpRequestUtil.createHttpRequest();
oXmlHttpReq = null; con ello también las cabeceras relativas a oXmlHttpReq.onreadystatechange =
}
las cookies. Así por ejemplo en la página function() {
Web de ejemplo cookies.html se puede aña-
} if (oXmlHttpReq.readyState == 4) {
dir una llamada AJAX en el evento onload
En otro caso, como el navegador imple- con la típica expresión window.onload = if (oXmlHttpReq.status == 200) {
menta de forma nativa el objeto function() {···}. El objeto necesario para alert(oXmlHttpReq.getAllResponse
XMLHttpRequest, simplemente se crea la hacer la llamada asíncrona se crea con el Headers());
instancia con la palabra reservada new: objeto que acaba de describirse. Al configu- }
try { rar el evento onreadystatechange, cuando }
oXmlHttpReq = new XMLHttpRequest(); llamada concluye con éxito (readyState=4 };
y status=200) se muestra en una ventana
} catch (e) {
de alerta todas las cabeceras HTTP recibi- Después de haber configurado el procesa-
oXmlHttpReq = null;
das. Éstas se obtienen con el método están- miento de la respuesta asíncrona, hay que
} dar getAllResponseHeaders. En realidad no hacer la llamada propiamente. El método

www.revistasprofesionales.com 57 SOLO PROGRAMADORES nº 172


Cookies:REDES-RSS Java 1 5/6/09 11:36 Página 58

REDES

open recibe tres parámetros. El primero es


una cadena de texto con el método. El
segundo es la URL a la que se llama. El últi-
mo parámetro es true lo que indica que la
llamada no es síncrona. Seguidamente se
establecen cabeceras HTTP para evitar la
caché con setRequestHeader. Por último
con el método send se lanza la llamada. El
parámetro empleado es null porque el
método es GET, es decir, no se envía infor-
mación alguna al servidor a parte de la que
pueda contener la propia URL. Como la lla-
mada es asíncrona el método send no blo-
quea el flujo de ejecución, que continua
inmediatamente después:
oXmlHttpReq.open(“GET”,
“/SSetCookie”, true);
oXmlHttpReq.setRequestHeader
(“Cache-Control”, “no-cache”);
oXmlHttpReq.setRequestHeader
(“Pragma”, “no-cache”); Llamada AJAX que se hace en el onload de la página .
oXmlHttpReq.send(null); a intentar establecer una cookie en ese final Cookie[] arrCookie =
La cabecera de respuesta del mensaje HTTP mismo servlet con los siguientes datos: req.getCookies();
que envía el servlet SSetCookie es la que se Cookie cookie2 = if (arrCookie!=null &&
muestra seguidamente: new Cookie(“date5”,···); arrCookie.length>0) {
Server: Resin/3.0.18 cookie2.setDomain(“.xxx.com”); for(final Cookie cookie : arrCookie) {
Expires: Wed, 31 Dec 1969 23:59:59 GMT cookie2.setPath(“/”); System.err.println(cookie.getName()
Cache-Control: no-cache cookie2.setMaxAge(60*60*24); + “=” + cookie.getValue());
Pragma: no-cache res.addCookie(cookie2); }
Set-Cookie: date4=05+mar El dominio es ahora .xxx.com. Hay que }
+2009+10%3A16%3A44+GMT; recordar que la URL desde la que se sirve Observando el log del servidor se comprue-
domain=.revistasprofesionales.com; ese servlet es .revistasprofesionales.com. La ba que las cookies llegan al servidor, es
path=/; expires=Fri, 06-Mar-2009 cabecera HTTP que recibe el navegador es la decir, que los objetos que se emplean en el
10:16:44 GMT siguiente: navegador para hacer las llamadas AJAX
Content-Type: text/plain; charset= Set-Cookie: también se encargar de leer las cookies a
ISO-8859-1 date5=05+mar+2009+11%3A52%3A01+GMT; las que tienen acceso, y las envían en cada
Transfer-Encoding: chunked domain=.xxx.com; path=/; expires=Fri, llamada. Hay que recordar que aunque el
Date: Thu, 05 Mar 2009 10:16:44 GMT 06-Mar-2009 11:52:01 GMT segundo parámetro del método open sea
una URL relativa, es el navegador el que
200 OK
El navegador cuando recibe esa cabecera la decide qué cookies mandar de todas cuan-
La cabecera Set-Cookie establece la cookie ignora porque no viola el esquema de segu- tas tiene almacenadas.
llamada date4 para el dominio .revistaspro- ridad. Por lo tanto, la cookie no se estable-
fesionales.com. Cuando el objeto que ce. Este comportamiento no se traduce en RESTRICCIONES DE SEGURIDAD CON
soporta la llamada AJAX recibe esta cabece- algún tipo de error “visible”, ni en el nave- LOS DOMINIOS
ra, el navegador establece la cookie tenien- gador ni en el servidor. Esta es la razón por
do en cuenta los parámetros domain, path, la que muchas aplicaciones Web fallan, Para comenzar a ilustrar los problemas que
etc., todo de forma transparente al progra- muchas veces sin que sus desarrolladores plantean las cookies en las aplicaciones Web
mador. De nuevo aquí se aplican las reglas comprendan exactamente el motivo, ya que que utilizan distintos dominios (o subdomi-
mencionadas con respecto al estableci- no funcionan y al mismo tiempo tampoco nios) se han puesto los ejemplos desarrollados
miento de cookies para dominios distintos. salen errores por las consolas. hasta el momento en dos dominios distintos:
El campo domain de la cabecera Set-Cookie Por último, en el servlet SSetCookie tam- cookies.revistasprofesionales.com
puede contener cualquier dato. El navega- bién se ha colocado el código necesario www.revistasprofesionales.com
dor sólo aceptará aquellas cookies que para mostrar por la consola del servidor de
entienda que respetan las restricciones de aplicaciones Web qué cookies recibe en las El caso anterior se da con bastante fre-
seguridad. Así por ejemplo, se puede probar llamadas: cuencia en las aplicaciones “reales”. Como

SOLO PROGRAMADORES nº 172 58 www.revistasprofesionales.com


Cookies:REDES-RSS Java 1 5/6/09 11:36 Página 59

REDES
Cookies en el navegador y en el servidor (II)

se verá más adelante es también uno de los


casos que presenta menos problemas ya
que ambos dominios comparten la misma
raíz, .revistasprofesionales.com. En la pági-
na HTML se han creado tres botones que,
utilizando la librería Javascript creada,
ponen tres cookies de distinta manera. La
primera, de nombre date1, se establece con
el dominio Cookies.DEFAULT_DOMAIN, es
decir, con .revistasprofesionales.com. El
valor de la cookie es la fecha. Realmente no
tiene importancia para lo que se quiere
ilustrar. Igualmente la ruta y la fecha de
caducidad tampoco son relevantes para el
ejemplo:
Cookies.add(‘date1’, new
Date().toGMTString(),
Cookies.DEFAULT_PATH, Resultado que devuelve getAllResponseHeaders en las llamadas AJAX.
Cookies.DEFAULT_DOMAIN, new Date
(new Date().getTime()+1000*60*60*24)) en cookies.revistasprofesionales.com. Por gador. En la parte de la página que se
último la cookie llamada date3 sólo se ve muestran las cookies con tecnología de
El siguiente botón establece una cookie lla- en cookies.revistasprofesionales.com y no cliente (con Javascript en el navegador) lo
mada date2. En esta ocasión se establece en www.revistasprofesionales.com. que se muestra es:
un dominio explícitamente, www. revistas- Obsérvese que con independencia del date4 05+mar+2009+09:32:33+GMT
profesionales.com: dominio donde esté viéndose la página, los
Cookies.add(‘date2’, clic de los botones no producen error algu- Sin embargo en la parte de la página donde
new Date().toGMTString(), no. Simplemente cuando se intenta esta- se muestran las cookies con tecnología de
blecer una cookie en un dominio para el servidor (con Java en el servidor de aplica-
Cookies.DEFAULT_PATH,
que no hay permisos, el navegador lo igno- ciones Web) lo que se muestra es:
‘www.revistasprofesionales.com’,
ra. date4 05 mar 2009 09:32:33 GMT
newDate(new Date().getTime() La conclusión a la que se llega es que en
+1000*60*60*24)) este tipo de aplicaciones, en las que todos Los distintos esquemas de codificación
El ultimo de los botones establece la cookie los dominios implicados comparten la entre el navegador y el servidor propician
llamada date3, con el dominio coo- misma raíz, en general parece una buena este tipo de problemas, especialmente con
kies.revistasprofesionales.com: idea hacer que las cookies se establezcan caracteres conflictivos como los espacios
Cookies.add(‘date3’, para dicha raíz, que es lo menos restrictivo. en blanco o los signos de puntuación.
newDate().toGMTString(), De esa forma desde cualquier página en
‘cookies.revistasprofesionales.com’,
cualquier dominio se podrán gestionar las CONCLUSIÓN
new Date(new Date().getTime()
cookies.
+1000*60*60*24))
La última prueba que va a realizarse consis- El problema expuesto con las cookies y los
te en añadir al evento onload de la página dominios en esta entrega es el más sencillo
La misma página Web va a mostrarse en los una llamada AJAX al servlet SSetCookie. de los casos. Cuando los dominios son
dos dominios, con las URL: Este servlet devuelve una cadena de texto completamente distintos, y no comparten
http://www.revistasprofesionales.com/ plano simple y además establece una coo- raíz común, resulta bastante más complica-
cookies.html kie denominada date4. El dominio para el do mantener una gestión unificada de las
http://cookies.revistasprofesionales.
que se establece es .revistasprofesiona- cookies. En la siguiente entrega se verán
com/cookies.html
les.com. ¿Qué es lo que ocurre? Como ya se algunas técnicas que permiten soslayar,
acaba de explicar al establecerse para la raíz que no ignorar, las restricciones al respecto.
En los dos casos se hará clic en los tres compartida, la cookie date4 se lee tanto En general la idea que subyace en todas
botones y se recargará la página, de forma desde www.revistasprofesionales.com estas técnicas es que las cookies viajan en
que pueda observarse qué cookies se mues- como desde cookies.revistas profesiona- todas las comunicaciones HTTP. En general
tran, tanto desde el servidor como desde el les.com. Ahora bien, este caso ilustra otro se tiene a pensar que eso sólo tiene que ver
navegador. El resultado es el esperado. La de los problemas mencionados anterior- con las páginas Web, pero en realidad es
cookie llamada date1 se ve en los dos mente en este artículo: el problema con la válido para las imágenes, los ficheros .css,
dominios ya que la terminación de ambos codificación de los valores de las cookies, los ficheros .js, los FRAME o IFRAME, etc., es
es la misma. La cookie llamada date2 se ve especialmente cuando se leen y escriben decir, todo aquello que se carga dinámica-
en www.revistasprofesionales.com pero no indistintamente desde el servidor y el nave- mente y tiene una URL.

www.revistasprofesionales.com 59 SOLO PROGRAMADORES nº 172


Dudas:Dudas 5/6/09 11:37 Página 60

DUDAS

Preguntas y respuestas
ADOLFO ALADRO GARCÍA cabe señalar que Content-Type y Content- La lectura de la respuesta del servidor
Length son bastante importantes. La pri- comienza con la apertura del canal de lectu-
Estoy creando una aplicación J2ME para mera indica el tipo de datos, como ya se ha ra. El método openInputStream permite obte-
móviles. En un momento dado la aplica- indicado anteriormente. La segunda es un ner el correspondiente canal InputStream:
ción se tiene que conectar a Internet valor numérico que indica el númeto de is = httpCon.openInputStream();
para mandar el usuario y la contraseña bytes que se van a tranferir:
introducida por el usuario. En el servidor httpCon.setRequestProperty(“User- Agent”, En toda comunicación basada en el protoco-
se comprueba el login y si es correcto se “Profile/MIDP-2.0 Configuration/CLDC-1.0”); lo HTTP antes de pasar a leer la respuesta del
devuelve OK o en caso contrario KO. httpCon.setRequestProperty(“Content-
servidor siempre hay que verificar el código
Además de mandar esos datos también Type”, “application/octec-stream”);
de respuesta. El método getResponseCode
necesito poder mandar una foto que devuelve ese valor:
httpCon.setRequestProperty(“Content-
tenga el usuario en el móvil. ¿Cómo se final int iResponseCode = httpCon.
Length”, Long.toString(lContentLength));
puede hacer? getResponseCode();
Teniendo en cuenta que los datos que se httpCon.setRequestProperty(“Cache-control”,
desean mandar son heterogéneos, una de “no-cache”); Si el código de respuesta es distinto de 200
las opciones más interesantes consiste en httpCon.setRequestProperty(“Pragma”, OK (lo que en el API viene definido por la
hacer una petición POST de forma que el “no-cache”); variable HttpConnection.HTTP_OK) entonces
Content-Type de la petición, y de la res- httpCon.setRequestProperty(“Accept”, de lanza una excepción. En otro caso se
puesta, sea application/octec-stream. Este “application/octet-stream”); puede comenzar a leer los datos:
tipo de datos indica al servidor que la infor- httpCon.setRequestProperty(“Connection”, if (iResponseCode != HttpConnection
mación transmitida es simplemente un “close”); .HTTP_OK) {
flujo bytes al que el programador puede dar throw new IOException(“HTTP response
el formato que más le interese. Una vez que las cabeceras HTTP se han esta-
code: “ + iResponseCode);
En un móvil, una conexión HTTP se abre con blecido, se escriben los dos empleando el
el método estático open de la clase canal de escritura: }
Connector. El parámetro que recibe es una os.write(···); Finalmente cabe hacer hincapié en un dato
cadena de texto conteniendo la URL. El valor que resulta de vital importancia. Una aplica-
os.flush();
devuelto debe convertirse explícitamente en ción J2ME que hace una llamada HTTP siem-
un objeto de tipo HttpConnection:
httpCon = (HttpConnection)Connector.
open(sUrl);

Inmediatamente después de abrir la cone-


xión se acceder al canal de escritura de datos
con el método openOutputStream:
os = httpCon.openOutputStream();

Después se establece el método de la lla-


mada con setRequestMethod. Como no
podía ser de otro modo, éste tiene que ser
POST:
httpCon.setRequestMethod(HttpConnection
.POST);

En el siguiente paso se establecen las cabe-


ceras HTTP de la llamada. El método
setRequestProperty recibe dos parámetros.
El primero es una cadena de texto con el
nombre de la propiedad. El segundo es otra
cadena de texto con el valor. De entre todas
las cabeceras que se pueden establecer, Página principal de JavaME (java.sun.com/javame/index.jsp).

SOLO PROGRAMADORES nº 166 60 www.revistasprofesionales.com


Dudas:Dudas 5/6/09 11:37 Página 61

DUDAS
Preguntas y Respuestas

pre debe ejecutar dicha llamada en un thre-


ad distinto al de la aplicación. Si esto no se
hace así, la llamada puede bloquear la apli-
cación hasta que resuelve, dejándola total-
mente colgada. En realidad en bastante sen-
cillo hacerlo así en Java. Basta con crear un
nuevo objeto Thread de forma que todo el
código explicado anteriormente se ejecute
dentro del método run:
thSend = new Thread(
new Runnable() {
public final void run() {···}
}
);
thSend.start();

Programando en C++ me he dado cuen-


ta de que existen muchas clases de las
librerías estándar que pueden mostrarse
directamente por el cout. El caso más
obvio es la clase string. Cuando yo hago
mi propia clase, ¿cómo puedo hacer para
que se pueda usar directamente con el Código fuente de Dimension.cpp.
operador << y la salida estándar cout?
Sí existe una forma bastante sencilla de En el área pública se encuentran el construc- return ostr;
hacer que los objetos de una clase dada pue- tor, el destructor y los típicos métodos };
dan mostrarse por la consola de salida getXXX para acceder a los valores w y h:
estándar (cout) con el operador también public: El operador sobrescrito es un método de la
estándar <<. Para ello es preciso sobrescribir clase que se declara como “amigo” (friend).
Dimension(int w, int h);
dicho operador. Seguidamente se va a mos- Al hacerlo así puede acceder a los atributos
trar un ejemplo muy sencillo que ilustra virtual ~Dimension(); privados. Recibe como parámetros el canal
cómo puede hacerse. int getWidth(); de escritura estándar así como el propio
La clase Dimension va a representar, como int getHeight(); objeto Dimension que se quiere mostrar
su propio nombre indica, un vector de por la consola. El código es bastante direc-
dimensión (anchura y altura). La definición Teniendo la clase definida anteriormente to: simplemente se encapsula lo que antes
de la clase contenida en un fichero resulta muy sencillo hacer en una aplicación se hacía explícitamente con getWidth y
Dimension.h presenta el siguiente esqueleto: lo siguiente: getHeight.
#ifndef DIMENSION_H_ Dimension d1(320, 200); Si se vuelve a compilar el programa se ve
que se pueden emplear sin problemas
#define DIMENSION_H_ cout << d1.getWidth() << “x” << d1.
expresiones como la que se muestra a con-
#include <iostream> getHeight() << “\n”;
tinuación:
using namespace std; El resultado que muestra la consola es la Dimension* d3;
class Dimension { cadena 320x200. Ahora bien, lo que se desea
d3 = new Dimension(1024, 728);
hacer en realidad es más bien:
··· cout << *d3 << “\n”;
Dimension d2(640, 400);
}; delete d3;
cout << d2 << “\n”;
#endif /*DIMENSION_H_*/
Es decir, se quiere mostrar el objeto por la En este último ejemplo se crea una instancia
La clase cuenta con dos atributos o propie- consola directamente con el operador <<. de Dimension que se aloja dinámicamente en
dades privadas, que se corresponden respec- Para ello hay que modificar la definición de la memoria. En realidad no hay diferencia
tivamente con la anchura y altura: la clase, Dimension.h, de forma que se con respecto a los ejemplos anterior.
private: sobrescriba el operador correspondiente: Simplemente se emplea el operador asterisco
friend ostream& operator<< (ostream& (*) para acceder al objeto Dimension a partir
int w;
ostr, const Dimension& d) { de su dirección de memoria, y tal cual se
int h; puede mostrar por la consola estándar.
ostr << d.w << “x” << d.h;

www.revistasprofesionales.com 61 SOLO PROGRAMADORES nº 166


opinion:OPINION 5/6/09 11:39 Página 62

OPINIÓN

La virtualización de la amistad
Las Redes Sociales han surgido de
NICOLÁS VELASQUEZ
dustries.com/introvertster) o Isolatr (isolatr.com)

la explosión del modelo 2.0 y se


que tienen como objetivo paradójico la creación El becario
de comunidades antisociales con la premisa de

alimentan de la interacción social,


Kevin
que “nadie te moleste cuando estás conectado”. Colvin fue

esto es, del intercambio dinámico


pillado por
Una forma satírica de lucha cibernética. sus jefes de

entre personas, grupos e


No obstante, la mayor desconfianza se asocia a esta guisa
los sistemas de recopilación de información per- en

instituciones. Pero hay que ser cauto


MySpace.
sonal y de preservación de la privacidad. Y es

ya que no es oro todo lo que reluce.


que inscribirse en ellas exige normalmente ceder
muchos datos personales que quedan en manos
extrañas, cuando no se hace necesario aceptar consecuencias que esto puede llegar a suponer
condiciones confusas. Muchos usuarios del y que sólo ocurre en la red (la gente no suele
La Redes Sociales se han convertido en lugares popular portal Facebook, seguramente la Red ofrecer sus datos personales a desconocidos en
perfectos para encuentros entre internautas. En Social más popular del mundo (no por nada la calle, ¿verdad?). Un verdadero filón de datos
ellas podrás ligar, hacer negocios, compartir afi- suma ya 175 millones de usuarios) se han que- para usuarios maliciosos que ahonden en técni-
ciones, reencontrarte con familiares. Hay cientos jado sobre lo difícil que puede llegar a ser darse cas de robos de identidad (phising). ¿De qué sir-
de sitios web, aunque probablemente los más de baja del sitio, bien sea porque las instruccio- ven un cortafuegos y un antivirus actualizados
conocidos sean Facebook, MySpace y, más orien- nes no son claras y fáciles de seguir o por que si son los propios usuarios los que proporcionan
tado al mercado español, Tuenti. Recientemente los datos de los usuarios no se eliminan del todo. información personal a quien quiera leerla?
se ha hablado mucho de esta última por ser la Esto provocó en su momento una gran polémi- Como curiosidad, en la página MySpace Killers
red que utilizaba Marta del Castillo, la joven ase- ca que reavivó las sospechas de que Facebook (http://myspacekillers.com) se ofrece informa-
sinada en Sevilla, con sus amigos, entre los que era un instrumento de la CIA para guardar la ción sobre todo tipo de hechos delictivos rela-
se encontraba el supuesto asesino. información de sus millones de usuarios. Algo cionados con la Red Social MySpace.
Esto da una idea de lo integradas que están ya paranoico, también hay que reconocer. Pero sin irnos tan lejos las redes sociales pueden
la Redes Sociales entre los jóvenes de nuestra Recientemente saltaba la noticia de Facebook jugar en nuestra contra si no sabemos mane-
sociedad, que ya las utilizan de forma habitual había cambiado sus términos de uso, es decir, las jarlas. La prueba más palpable tiene su explica-
para comunicarse con sus amigos, y desde eda- condiciones para utilizar su servicio. Ahora se ción en que se ha puesto de moda que los
des muy tempranas. especificaba que Facebook tenía el derecho de departamentos de recursos humanos busquen
Sin embargo, con la popularización de estas usar libremente todo lo publicado por sus miem- allí información sobre posibles candidatos a
redes virtuales, también han arreciado las críti- bros, ¡incluso si éstos ya se habían dado de baja! determinados puestos de trabajo. Y es que no
cas (al margen de su necesidad, utilidad y fun- Los cambios habían pasado desapercibidos hay currículum que valga si en tu Facebook
cionalidad que muchos ponen aún en duda) hasta que desde el blog estadounidense apareces en actitudes obscenas o consumiendo
sobre la amenaza que puede suponer para la Consumerist los hizo públicos. Al día siguiente algo ilegal. Esto es precisamente lo que le ocu-
intimidad de sus propios usuarios, cuando no ya se habían formado varios grupos de protes- rrió a Kevin Colvin, un becario del banco Anglo
directamente al acoso que pueden llegar s sufrir ta con miles de miembros y muchos usuarios Irlandés que pidió el día libre por un asunto
debido al bombardeo para aceptar amigos o decidieron darse de baja o retirar información familiar. A la mañana siguiente sus superiores
extraños. En este caso y como curiosidad, hay privada. Pocas horas después la empresa recu- encontraron en su perfil de Facebook las fotos
que destacar webs como Introverster (airbagin- laba, anunciando que se volvía a los antiguos de una fiesta de disfraces a la que Kevin había
términos legales. asistido de hada madrina. Una noche mágica…
Pero el manejo de la información no es lo único Un informe del diario británico The Times con-
con lo que hay que tener cuidado. También está cluía que uno de cada cinco empleadores utili-
el peligro de la suplantación de personalidad y el zó redes como Facebook para verificar los ante-
hecho de que las redes sociales están convirtién- cedentes de candidatos a puestos de trabajo.
dose en un vehículo ideal para los delincuentes Según el diario, hasta el 75% de los que hicie-
tecnológicos debido, entre otras cosas a la vul- ron uso de este tipo de búsquedas reconoció
nerabilidad inherente de su propia naturaleza: que su decisión final de contratar o no a la per-
una red social genera una falsa confianza que sona se vio influenciada directamente por esta
favorece el que los usuarios faciliten datos per- consulta. El mejor consejo en este caso podría
sonales (por ejemplo durante la creación de un ser entonces: “no pongas nada en tu perfil que
Las empresas revisan cada vez más los
perfiles en la red de aspirantes a un trabajo. perfil en la web) sin cuestionarse realmente las no querrías que viera tu madre”.

SOLO PROGRAMADORES nº 172 62 www.revistasprofesionales.com


Archivadores Solop:Archivadores Solop2005 11/12/08 14:57 Página 1

¿Luchas
contra
el caos?
…ahora puedes solucionarlo !!

Consigue por sólo 6 euros un archivador de revistas valorado en 5,41 euros


y un archivador de cd’s valorado en 4,20 euros.
Haz tu pedido llamando al teléfono 91 304 87 64, por fax al 91 327 13 03
o por correo electrónico a rpsuscripciones@revistasprofesionales.com,
indicando tus datos personales y la forma de pago (giro postal, domiciliación bancaria,
tarjeta de crédito o contrareembolso*).
REVISTAS PROFESIONALES - C/ Valentín Beato, 42 - 3ª plta. - 28037 Madrid
*en opción contrareembolso se cobrará un suplemento de 5 euros por gastos de envío
En opción domiciliación bancaria, se ruega aporten los datos completos de la entidad bancaria (nombre, dirección y número de cuenta completo)
Videocurso6:Videocurso6 5/6/09 11:40 Página 64

VIDEOCURSO

Actualización a Visual Studio


2008: LinQ con
Visual Basic 9.0 (VI)
de consulta en el lenguaje SQL. Muy importan-

En esta sexta entrega se incluyen los


te para afinar el rendimiento.

capítulos 12 y 13.
LinQ to SQL, no solo ofrece funcionalidades
para consultar bases de datos SQL, si no que
también permite modificar datos del servidor
12.- LinQ to SQL II. utilizando la propia sintaxis de LinQ.
-La traducción a SQL. Cuando se modifican datos en una base de
-Modificar datos con LinQ to SQL. datos es muy importante tener presente todos
-Concurrencia y LinQ to SQL. los aspectos relacionados con la concurrencia
-Ejecutar Procedimientos Alamacenados. de la información. LinQ ofrece herramientas
para garantizar la coherencia de la informa-
13.- LinQ to SQL III. ción cuando se trabaja en escenarios desco-
-Transacciones. nectados.
-Consultas de sólo lectura. LinQ to SQL permite también ejecutar
-Cargas de datos completas. Procedimientos Almacenados, programados
-Definir límites de datos. previamente en el servidor.
-Agregar lógica empresarial con métodos partial.
-Consultar vistas y funciones Capítulo 13. LinQ to SQL III.
Capítulo 12. LinQ to SQL II.
Este es el segundo módulo que dedicamos a
LinQ to SQL.
En este módulo continuamos con las caracte-
rísticas del acceso a servidores SQL utilizando
LinQ.
Entre otras cosas, se presta una especial aten-
ción al proceso de traducción a SQL. Esto es
muy importante, pues según la sintaxis que
utilicemos en LinQ, obtendremos un tipo u otro

Este es el último módulo que dedicamos a LinQ


to SQL.
En este módulo aprenderemos a configurar las
transacciones con LinQ to SQL.
También veremos algunas características aña-
didas que nos ofrece LinQ to SQL como:
Consultas de solo lectura, Cargas de datos
completas, Definir límites de datos, Agregar
lógica empresarial utilizando métodos partial y
realizar consultas a Vistas y Funciones progra-
madas en el servidor SQL.

SOLO PROGRAMADORES nº 172 64 www.revistasprofesionales.com


65 atrasados:atrasados 4/6/09 09:07 Página 1

NÚMEROS ATRASADOS
171 - Mayo 2009 LA PRIMERA REVISTA DE PROGRAMACIÓN EN CASTELLANO
170 - Abril 2009

M
OE
-R UY
D CL
C IN
Una de las partes esenciales del API NIO es la relativa a la Lascookiessirvenparaalmacenarlainformacióndeformaqueelpro-
entrada y salida con ficheros. En la programación orientada a tocoloHTTPconellasadquiereunafuncionalidaddelaquecarecepor
objetos tiene tanta importancia el propio lenguaje como la Precio: 6 € (España) (IVA incluido) • AÑO XVI. 2.ª ÉPOCA • Nº 170 • UNA PUBLICACIÓN DE: REVISTAS PROFESIONALES S.L. su definición: la persistencia. En Java, como en cualquier otro len-
metodología. Cuando se habla de navegación a través de los 170

El ordenador guaje, las operaciones de entrada y salida son de vital importancia. La


Fuentes
 Curso C++ (III)
 XNA (III) (I)
con Java NIO
 Entrada y salida
 Cookies en el
navegador

Podcast javaHispano
– 035 036 037
JavaHispano Podcast

sobre
Vídeo-Curso a Visual
REVISTAS SL

Actualización
P ROFESIONALES

LinQ con
42 3 ª

Studio 2008: 0 (IV)


VALENTÍN BEATO
28037 MADRID

9
Visual Basic
M 26827 1994

contenidos de un portal, suele pensarse en usuarios conectados gestión dinámica de la memoria es probablemente uno de los aspec-
DEPÓSITO LEGAL 4792
ISSN 1134

Cuántico
Y además…
ores 168
Solo Programad
en formato pdf

a Internet a través de un ordenador, una PDA o Set-Top-Box. INCLUYE


“LinQ con
tosmásimportantesdelaprogramaciónenC++.Enlasentregasante-
Visual Basic 9.0 (IV)”
Este es el segundo artículo de una serie de dos sobre Maven, Solo Programadores
número 168
en formato pdf
riores ya se han adelantado los principios básicos. En esta entrega
una tecnología destinada a la gestión del ciclo de vida del soft- JAVAHISPANO
Actualidad Java
veremos cómo trabajar con las cámaras, la lógica y el comportamien-
ware. Este artículo trata sobre las novedades que trae consigo REDES
Entrada y salida avanzada con Java NIO (I) Videocurso
to para desplazar a los diferentes actores en un laberinto, detectando
la primera beta pública del nuevo sistema operativo de Cookies en el navegador y en el servidor (I) Actualización a
Visual Studio 2008 -
las colisiones entre ellos y esquivando las paredes. La miniaturización
ALGORITMOS LinQ con Visual
Microsoft, Windows 7. Continuamos repasando las interiorida- Programación orientada a objetos
con C++ (III)
Basic 9.0 (4ª parte)
de componentes electrónicos ya ha alcanzado el nivel atómico en el
des de lo que está llamado a ser la tecnología del futuro: el ACTUALIDAD
El Ordenador Cuántico (I)
que las leyes de la física clásica dejan paso al universo cuántico. En
ordenador cuántico. Gestión de la configuración del software
en equipos Agile
La Reutilización del Software en el éxito
estenuevoescenariodestacaeldesarrollodelordenadorcuántico,una
del negocio
máquina que parece sacada de un relato de ciencia ficción, capaz de
Noticias, Dudas, CD resolver problemas que llevarían años a los ordenadores actuales, y
mucho más real de lo que algunos piensan.
169 - Marzo 2009 168 - Febrero 2009
El objetivo de este capítulo es enseñar a diseñar interfaces gráfi- En este número, abordaremos el framework de Collections de
cas de usuario empleando para ello la librería Swing. En esta Java. C++ sigue siendo el lenguaje elegido cuando se desean
entregaseveránlosfundamentosdelaherenciaysecomenzarán crear aplicaciones rápidas y robustas. La infraestructura .NET ver-
a trabajar con ejemplos simples de clases que extienden a otras sión 3.5 ofrece un conjunto de mejoras en los lenguajes, que
clases,clasesabstractas,sobrescriturademétodosyalgunosotros venían siendo solicitados por los desarrolladores. La programa-
conceptos cardinales en todo lenguaje orientado a objetos. En ción en DirectX y Direct3D (al igual que en OpenGL) ha sido por
esta entrega veremos cómo incorporar código C# que nos ayude muchos años un objeto de deseo por muchos desarrolladores.
a controlar la lógica y el comportamiento. En este artículo se da Con Google App Engine, se presenta una buena solución para la
unavisióngeneraldelmundodelStreaming,lasposibilidadesque puesta en producción y alojamiento de nuestras aplicaciones
aporta y las diferentes soluciones comerciales que nos ofrece el Web. Proponemos un pequeño módulo C++ para facilitar la inte-
mercado. En este artículo se van a explorar las facilidades que gración de Python en proyectos C++.
ofrece ASP.NET a la hora de crear aplicaciones multiidioma.

Si te falta algún número de la


167 - Enero 2009

temporada, ahora tienes la


Hemos cubierto lo básico de la sintaxis de Java, esto no quiere
decir que podamos dar por terminada esta serie de artículos. El

oportunidad de conseguirlo
tratamiento y generación de gráficos SVG con Javascript es
una opción muy interesante. Tras haber repasado los funda-

Precio Oferta descuento


mentos de XML es el momento de estudiar los elementos más
importantes. Plantearse procesar XML con Java, podría causar-
Precio por ejemplar: 6€
nosdolordecabeza.Seexplicaendetallelamanipulación,cre-

1 a 10 = 10% dto. / 11 a 20 = 20% dto.


ación y control de bases de datos relacionales utilizando SQL.

21 a 30 = 30% dto. / 31 a 40 = 40% dto.


Hastahacepoco,undesarrolladorquereparabaunaaplicación

+40 = 50%
confiaba en ejecutar nuevamente el código y llevar adelante
unas pocas pruebas para verificar que su cambio no corrompía
nada de lo existente.

BOLETÍN DE PEDIDO
Rellene o fotocopie el cupón y envielo a REVISTAS PROFESIONALES, S.L.
(Revista SÓLO PROGRAMADORES) C/ Valentín Beato, 42 - 3ª Planta - 28037 MADRID
Tel.: 91 304 87 64 - Fax: 91 327 13 03 - www.revistasprofesionales.com - rpsuscripciones@revistasprofesionales.com
Deseo me envíen los número/s: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
NOMBRE Y APELLIDOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .EDAD . . . . . . . . TELÉFONO . . . . . . . . . . . . . . . .
DOMICILIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .C.P.: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
CIUDAD . . . . . . . . . . . . . . . . . .PROVINCIA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

FORMAS DE PAGO
 Talon Bancario a nombre de REVISTAS PROFESIONALES S.L.
 Domiciliación Bancaria
Banco . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Domicilio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Firma:
Numero de cuenta: _ _ _ _/ _ _ _ _/ _ _ / _ _ _ _ _ _ _ _ _ _ _ _
Titular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 Tarjeta de crédito _ _ _ _/ _ _ _ _/ _ _ _ _/ _ _ _ _/ Fecha de caducidad:
Extranjero: Gastos de envio 5€ por paquete. Unica forma de pago tarjeta de crédito (VISA, Mastercard, American Express,...)
66 CD ROM:Layout 2 3/6/09 09:19 Página 66

CD-ROM

Contenido del CD-ROM 172 Fuentes

Podcast javaHisp
ano
Fuentes • Empresa referencia de Autentia que imple- REVISTAS
PROFESIONALES,
VALENTÍN BEATO . .
SL
JavaHispan
o Podcast – 043,
045, 046, 047, 048
044,
, 42 - 3.ª
28037 MADRID
menta IceFaces. Vídeo-Curso sobr
e
DEPÓSITO LEGAL:
M-26827- 1994
Actualización a Visu
ISSN: 1134-4792

Studio 2008: LinQ al


Curso C++ (VI) • Estadistica de uso de IceFaces. Visual Basic 9.0 con
(VI)

La librería estándar de C++ proporciona un gran • IceScrum.


número de clases, funciones y procedimientos Y además…
Solo Programadores
170
JavaHispano Podcast - 044 -
en formato pdf
para llevar a cabo todo tipo de tareas. Imple-
mentar todo tipo de clases es un excelente ejer- Dudas del foro Abril (a)
cicio durante la fase de aprendizaje de C++.
Publicado un nuevo número del podcast de ja-
Cookies en el navegador y en el servidor (II) vaHispano. En este número Rubén Egiluz y Rugi iteraciones con tareas más pequeñas.
Todas las tecnologías de servidor (Java, Perl, ASP, hablarán de los hilos publicados en el foro. Los Finalmente realizaremos una invitación a partici-
PHP, etc.) poseen librerías muy parecidas para leer hilos serán: par en Agile-Spain y apuntarse a su lista de co-
y escribir cookies. La visión completa cliente-ser- • Tips JDeveloper rreo para participar o aprender.
vidor permitirá introducir aspectos más avanza- • File en una aplicacion JEE Webs de interés:
dos como las restricciones de seguridad con los • Cambiar mi URL • Agile-Spain. Portal orientado al desarrollo ágil.
dominios y los problemas de la codificación de • Mostrar etiqueta en control propio con NetBe- • Manifiesto ágil en español.
los caracteres. ans • Portal de Extreme Programming.
• Configuracion hibernate • Foro Ágiles (Lista de correo sobre agilismo en
XNA Framework 2.0 y 3.0: DirectX y Di- • Problemas con las transacciones en JDBC español)
rect3D en C# para mortales (y IV) • JavaCup: Version estable del framework Cooperativa Agilar. Cooperativa para programa-
En la entrega anterior vimos cómo trabajar con A continuación ponemos los link de interés que se dores independientes de desarrollo ágil. Actual-
modelos 3D con cierta complejidad y brindarles comentan en el podcast: mente ejerciendo en Argentina y Bélgica y con
movimiento e interacción, combinando varios • Web JavaCup. Video promocional. futura proyección en España y Estados Unidos.
conocimientos necesarios que habíamos apren- • Pagina de tutoriales para JDeveloper.
dido en las primeras dos entregas. Tomando • Tips JDeveloper. En español JavaHispano Podcast - 046 -
como base los ejemplos presentados, se pueden • Breve Screencast para la creación de un com- Informes con JasperReports
desarrollar aplicaciones 3D que visualicen y faci- ponente Swing en NetBeans.
liten la interactividad con modelos 3D generados • Configuración Hibernate Publicado un nuevo número del podcast de ja-
con cualquiera de las herramientas de creación • Manual Rewrite vaHispano. En este número realizamos una ter-
de contenidos digital. tulia con Marioko y JorgeRubira en la que
JavaHispano Podcast - 045 - hablarán de la creación de informes y JasperRe-
JavaHispano Podcast - 043 - Principios de agilidad ports. En dicha tertulia se explicarán herramien-
Programación con ICEFaces (Entrevista a Agile-Spain) tas que se pueden complementar con
JasperReports como iReports o DinamicJasper.
Publicado un nuevo número del podcast de ja- Publicado un nuevo número del podcast de java- Además se hablará de buenas prácticas para ela-
vaHispano. En esta ocasión realizaremos una ter- Hispano. Este número estará dedicado al desarro- borar un informe y para su presentación.
tulia para hablar de IceFaces donde Marioko de la llo ágil donde entrevistaremos a tres miembros de Links de interés:
comunidad de javaHispano y Ivan Zaera de la Agile-Spain. En la entrevista participarán Jose Ma- • Web oficial de JasperForge
empresa Autentia, empresa responsable de la nuel Beas autor del blog Se hace camino al andar..., • Descarga de JasperReports
web AdictosAlTrabajo, explicarán para que sirve Xavier Quesada autor del Blog de Visual Manage- • Descarga de iReports
este framework y hablarán de sus experiencias. ment y Xavi Albaladejo autor del portal • Descarga de DynamicJasper
Durante la entrevista hablaremos de JSF, Facelets, http://www.proyectosagiles.org una base de co- • Descarga de JFreeChart
Server Push, validación de campos y algunas re- nocimientos de Scrum. Durante la entrevista se
comendaciones para desarrollo web con este fra- hablará del manifiesto del desarrollo ágil y reali- Vídeo-Curso sobre Actualización
mework. zarán una introducción de esta forma de trabajo. a Visual Studio 2008: LinQ
A continuación ponemos algunos links de interés Entre estos principios destacaremos la importan- con Visual Basic 9.0
que se explican durante el podcast: cia del valor de las personas, incrementar la co-
• Web oficial de ICEFaces. municación y la confianza entre los miembros del Sexta parte de un completo curso de 7 entregas.
• Tecnología AjaxPush grupo de trabajo entre estos y con el cliente, la
• Configuración de Facelets. disciplina de los trabajadores, automatizar las ta- Además …
• Articulo de Facelets. reas lo más posible y evitar la realización de gran-
• Framework de la empresa Autentia. des tareas con largos plazos creando más Solo Programadores 170 en formato pdf

SOLO PROGRAMADORES nº 172 66 www.revistasprofesionales.com


Anuncio Videocursos:Anuncio Videocursos 14/1/09 11:54 Página 1
Proyecto1:Layout 1 9/6/09 08:50 Página 1

Potrebbero piacerti anche