Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





¿qué Pasa Con Los Programadores?

Iniciado por Haddd, 12 de Abril de 2005, 05:34:19 PM

« anterior - próximo »

zupervaca

 
Cita de: "ethernet"Aja, entiendo lo que dices pero no me refiero a eso. Lo que quiero es hacer lo mismo que estaba haciendo, más o menos con el mismo sistema pero o necesitar saber la clase que he serializado, me explico, vieniendo una ristra de bytes sé que son una derivada de una clase base y quiero exactamente hacer lo siguiente, pero bien hecho (de forma elegante ):



Base* MiClaseBase::serialize(int* data)
{
     int type = *data++;Ç
     switch(type)
    {
       case CLASE1:  
           Clase1* p  = new Clase1;
           p->serialize(data);
           return p;
        case CLASE2:
....
    }
}

ahora entiendo lo que dices claramente (eso espero  :lol:), la solucion que existe es esta:

// Incluir cabeceras
#include <stdio.h>
#include <conio.h>
#include <memory.h>

// Clase de pruebas
class ca
{
public:
void pruebasa( int a1, int a2 )
{
 this->a1 = a1;
 this->a2 = a2;
};
int a1, a2;
ca()
{
 printf( "\r\nconstructor" );
}
~ca()
{
 printf( "destructor" );
}
};

void main()
{
// Guardar la clase en un buffer
ca a;
a.pruebasa( 10, 20 );
int sizeclasea = sizeof(ca);
char *datos = new char[sizeclasea] +2;
datos[0] = 1; // Por si quieres saber que clase es en algun momento
datos[1] = sizeclasea; // Tamaño de la clase
memcpy( &datos[2], &a, datos[1] );

// Recuperar la clase de un buffer
sizeclasea = datos[1];
char *clase = new char[sizeclasea];
memcpy( clase, datos +2, sizeclasea );
ca *aclase = (ca*)clase;

// Hacer pijadines con ella
char sz[256];

// Mostrar los valores originales desde datos
printf( "\r\ncomienzan las pruebas\r\n" );
sprintf( sz, "datos-> a1: %i, a2: %i\r\n", aclase->a1, aclase->a2 );
printf( sz );

// Modificar los valores de la clase
aclase->pruebasa( 11, 21 );
sprintf( sz, "modificada-> a1: %i, a2: %i\r\n", aclase->a1, aclase->a2 );
printf( sz );

// Finiquitar el percal
delete aclase;
getch();
}


con esto lo haces de forma automatica, te lo he puesto en plan ejemplo cutre para que lo veas rapidamente y no liarte con chorradas, ademas la ventaja de este sistema es que no llama al constructor de la clase con lo que te ahorras la doble inicializacion de valores  ;), este sistema es el que utilizaba yo hace mucho tiempo en ms-dos para guardar clases del tiron y ahorrarme mucho tiempo de programacion

saludos y espero acertar esta vez  :rolleyes:  

ethernet

 No es un método muy ortodoxo y tiene problemas pero por ahí irán los tiros. Me leeré los artículos de AK47 aunque me temo que se meten en terrenos que no me quiero meter. Es posible resolverlo con una factory y templates de forma elegante, pero eso no me interesa ahora ya que no es mi objetivo principal hacer un serializer de pánico, solo quiero usarlo.

gracias

Haddd

 Newton es mucho Newton  :D  Bueno, ahora cuando tenga dudas con cosas de Newton, ya sé a quien preguntar  ;)

Por cierto, el foto de Newton está muy muy bien. El propio desarrollador de la librería suele responder a todas las preguntas...

zupervaca

 si quieres otra solucion sin usar clases derivadas, pero que te tocara implentar cada una, en vez de cases usa punteros a funciones, asi lo dejarias sin comprobaciones en cada serialize, en efecto el fallo mas gordo del sistema que te pongo es que tienen que ser tipos de datos que se encuentren dentro de la clase, si tienes un dato tipo puntero no funcionara, tambien tienes otro sistema que se usa mucho para generar indices automaticos para busquedas, el sistema consiste en que cada tipo de clase tiene un "class declarator", si has usado directx (me parez que es el caso) conoceras el vertex declaration, pues basicamente es lo mismo, es almacenar los tipos de datos, posiciones y tamaños de una clase para luego guardarlas y leerlas automaticamente con una funcion, otra forma de enterlo por si no has visto el vertex declaration es como cuando enviamos comandos por la red, un comando por decirlo tendria su tipo de comando, su longitud y despues su contenido y asi se envia y recibe sin saber lo que es ese comando

si aun no has probado a sobrecargar el operador new para hacer algun truco te recomiendo un no ya que es una locura y en muchos compiladores revienta todo  :(  

Astat

 Aqui teneis un video (ojo 5 megas!) de un tema relacionado con la arquitectura en el que estoy metido.

Por ahora esta pensado para que carge en equipos antiguos asin que no hay materiales molones ni iluminacion chachi pilongui, pero todo se andara  ;)

PD: He estado hechando un ojo a Newton ese y me parece bastante mas lento que ODE la verdad (version 0.5), aunque si es cierto que la API es mas clara.

Zaelsius

 Yo estoy haciendo un port de un juego BREW a PC/Mac con PTK.


PD: He probado tambien las Newton en el Mac, y la verdad es que van muy justas de rendimiento, al menos en mi máquina.

DraKKaR

 Yo he estado un tiempo desarrollando una herramienta de simplificación poligonal. Ahora estoy investigando unas cosillas, relacionadas con gráficos. Ya hacía tiempo que no tocaba nada del motor, pero esto último me ha "obligado" (más bien ha sido la excusa perfecta) para implementar un renderer de iluminación por píxel para mi motor.

No sabía muy bien como gestionar el tema de los shaders y al final lo he hecho de una forma que me gusta bastante: los shaders se generan  en tiempo de ejecución según las necesidades de lo que se vaya a dibujar. Es decir, necesito dibujar un objeto con iluminación, textura y un mapa de normales. El renderer mira si ya se ha creado anteriormente un shader que cumpla esas carácterísticas. Si es así, se utiliza, si no, se genera y se guarda para ser reutilizado.

No se si esta es la forma habitual de hacer estas cosas pero a mí me gusta. También es posible que el usuario asigne un shader para una malla en particular (esto tiene preferencia a los shaders automáticos).

Si teneis curiosidad podeis ver el código fuente en el espacio web de sourceforge de mi motor, utilizando el WebCVS. Se trata del módulo 'renderogl_sm1'.

Pogacha

 zupervaca ese codigo no tiene ninguna posibilidad de funcionar ... si la clase tiene metodos virtuales en  (vtable*)(&ca)-1 se guarda el puntero a la vtable y si no tiene metodos virtuales no se si estara protegida esa posicion de memoria ... si ademas agrego rtti no tengo idea de como se distribuira la memoria en ese compilador ...

La verdad es que no es solución para nada ... incluso mi clase es:

class CA {
 int *a;
 CA(Stream f) { a=new int[100]; for(i; i<100; i++) f>>a[i]; }
 virtual ~CA() { delete a; }
};


tu memcpy fracasa ...

Me vuelan por la cabeza metodos del tipo :

Constructor(Stream Deserializando) : Miembro1(Deserializando) : Miembro2(Deserializando);

Pero ni siquiera voy a probar, yo seguire con mi switch y punteros void *

Saludos



BeRSeRKeR

 
Cita de: "DraKKaR"No sabía muy bien como gestionar el tema de los shaders y al final lo he hecho de una forma que me gusta bastante: los shaders se generan  en tiempo de ejecución según las necesidades de lo que se vaya a dibujar. Es decir, necesito dibujar un objeto con iluminación, textura y un mapa de normales. El renderer mira si ya se ha creado anteriormente un shader que cumpla esas carácterísticas. Si es así, se utiliza, si no, se genera y se guarda para ser reutilizado.
Más o menos ese es el sistema que tenemos en el motor C# aunque tendríamos que llevarlo un poco más allá e implementar un sistema similar al que Shawn Hargreaves describe en este documento. La verdad es que es la única forma (que yo contemple) en la que puedes crear múltiples combinaciones de shaders de forma flexible y sin volverte loco. :D

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

zxs

 pues yo pertenezco al grupo de los sufridores, hasta hace poco: vb6, mucho acess y sobretodo, una base
de datos que no usa nadie pero su programación es genial: mezcla pascal + ensamblador y te sale ... no querais saber lo que sale... ni el doctor Menguele!!!! (grrr)

ahora que he cambiao de currelo, pues he vuelto al C/C++ y, claro, yo refrescandome despues de 3 años
sin picar codigo orientado a objetos y me saltais
Citarsobrecargar el operador new
casi me da un yuyu, lo bueno, que como estoy metiendo caña al C++, pues me podré poner !por fin! con ganas con el directx, que deje aparcado hace unos mesecitos, vamos, deje una nave por el espacio disparando a lo loco  (nooo) )


zupervaca

Cita de: "Pogacha"zupervaca ese codigo no tiene ninguna posibilidad de funcionar ... si la clase tiene metodos virtuales en  (vtable*)(&ca)-1 se guarda el puntero a la vtable y si no tiene metodos virtuales no se si estara protegida esa posicion de memoria ... si ademas agrego rtti no tengo idea de como se distribuira la memoria en ese compilador ...

La verdad es que no es solución para nada ... incluso mi clase es:

class CA {
 int *a;
 CA(Stream f) { a=new int[100]; for(i; i<100; i++) f>>a[i]; }
 virtual ~CA() { delete a; }
};


tu memcpy fracasa ...

Me vuelan por la cabeza metodos del tipo :

Constructor(Stream Deserializando) : Miembro1(Deserializando) : Miembro2(Deserializando);

Pero ni siquiera voy a probar, yo seguire con mi switch y punteros void *

Saludos
sigo diciendo lo mismo hay que leer antes de postear, esa clase es normal que no funciona ya que trabajas con punteros dentro de la clase, la clase esta en una posicion de memoria y el puntero de la clase en otra, si lees mas abajo ethernet dice que tiene fallos y yo le indica que efectivamente solo funciona con valores que esten dentro de la clase, cosa que los punteros no estan, si coges mi ejemplo cutre y lo compilas veras como funciona correctamente

saludos

pd: antes de usar switch usa punteros a funciones

Pogacha

 Pido disculpas por no argumentar adecuadamente mi criterio:

En realidad el problema principal es que quiebras el paradigma de la POO:

1- Accedes a miembros privados o protegidos y a todo.
2- Si al compilador se le canto meter entre medio de esta clase otra cosa en memoria tambien lo estas destruyendo con memcpy  ...
3- El archivo servirá solo para esta compilación ... cualquier cambio haría imposible la recontrucción ...
4- El metodo es externo y para acceder a miembros privados deberias llamar a una función para obtener estos resultados, lo cual implica que las clases bases debieran conocer a sus hijos o mas bien a todos ...

Sin animos de ofender, concluyo que como metodo general resuelve solo casos aislados y no sirve como automatización, pues para cualquier singularidad requiere solución particular.

Sobre los punteros a funciones, ganaria velocidad a costo de complicarme? ... no creo que me interese la velocidad si estoy leyendo de disco, supongo que lo decias como alternativa, la cual es buena en un switch con muchos casos.

Saludos.

vincent

 bueno, finalmente ya tengo tuneado el tema de las colisiones. Al final las colisiones del personaje con el mundo las he echo a mano. La newton seguramente si que la utilizaré para los solidos rigidos.

Lo que no me funcionava ahora es que creava mal el kdtree que uso para las coliisones. no tenia en cuenta todos los casos en que un triangulo puede estar dentre de la bounding box del nodo.

Ahora ya funciona todo bien y muy rapido.

Hasta luego!
Desarrollo en .Net y metodologías http://devnettips.blogspot.com

nostromo

 Buenas,

Para enriquecer un poco la discusión sobre serializar objetos en C++:

Esta claro que cualquier implementación sobre el lenguaje o no es limpia o tienes que decirle que campos guardar, o no sabe nada de referencias, clases derivadas etc....

Por abrir otro frente de ataque al problema os propongo que le echeis un vistazo a OpenC++:

http://opencxx.sourceforge.net/

Se trata de programar los programas de C++, es decir metaprogramación... con esta herramienta podemos generar un compilador de C++ que añada funcionalidad a nuestras clases, y con esto se podria solucionar el tema de la serialización de una manera limpia y potente ....
y muchos otros temas como la reflexión que no tiene el C++ y que hace que en Java y C# sea "facil" serializar puesto que la reflexión como algunos sabeis hace que las clases se puedan conocer a si mismas.

En fin, yo no tengo tiempo para profundizar en esta herramienta pero aunque esta incompleta muestra un futuro prometedor.

Un saludo

zupervaca

Cita de: "Pogacha"Pido disculpas por no argumentar adecuadamente mi criterio:

En realidad el problema principal es que quiebras el paradigma de la POO:

1- Accedes a miembros privados o protegidos y a todo.
2- Si al compilador se le canto meter entre medio de esta clase otra cosa en memoria tambien lo estas destruyendo con memcpy  ...
3- El archivo servirá solo para esta compilación ... cualquier cambio haría imposible la recontrucción ...
4- El metodo es externo y para acceder a miembros privados deberias llamar a una función para obtener estos resultados, lo cual implica que las clases bases debieran conocer a sus hijos o mas bien a todos ...

Sin animos de ofender, concluyo que como metodo general resuelve solo casos aislados y no sirve como automatización, pues para cualquier singularidad requiere solución particular.

Sobre los punteros a funciones, ganaria velocidad a costo de complicarme? ... no creo que me interese la velocidad si estoy leyendo de disco, supongo que lo decias como alternativa, la cual es buena en un switch con muchos casos.

Saludos.
la quiebro sencillamente por que ethernet no quiere derivar de una clase, ese ejemplo cutre es para evitar que ethernet lo haga, yo en ningun caso lo haria asi

pido que leais los post antes de contestar, seguir el hilo y enteraos un poco de lo que se habla antes de escribir por favor

saludos






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.