Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Administrador De Recursos

Iniciado por Pogacha, 25 de Septiembre de 2005, 09:04:24 PM

« anterior - próximo »

Pogacha

 Que tal ... estoy por cambiar mi sistema de capsulas de recursos a un sistema mas automatizado y me gustaría sugerencias pues es la primera vez que lo hago y me resultó por demas sencillo, entonces le desconfio, todavia no lo he compilado pues tendria que cambiar muchas cosas y antes de cambiar todo me gustaria asegurarme de no estar haciendo una chorrada.

AdministradorDeRecursos.h
#ifndef __ADMINISTRADOR_DE_RECURSOS__H__
#define __ADMINISTRADOR_DE_RECURSOS__H__

//*****************************
// Recurso
//*****************************

class TRecurso
{
friend class TAdministradorDeRecursos;

 protected:

TAdministradorDeRecursos *Administrador;
TRecurso *Siguiente, *Anterior;
int Uso;
char *Nombre;

virtual ~TRecurso();

 public:

TRecurso();

const char* Tomar_Nombre();
void Liberar();
};

//*****************************
// Administrador de recursos
//*****************************

class TAdministradorDeRecursos
{
typedef TRecurso* TRecursoPtr;
 
int n_Recursos;
   TRecursoPtr *Recursos; // es una tabla de hashing

int Calcular_Hash(const char *t);

 protected:

TAdministradorDeRecursos(int n_recursos);
~TAdministradorDeRecursos();

void Agregar(TRecurso *r);
void Quitar(TRecurso *r);
TRecurso *Tomar(const char *Nombre);
};

//*****************************
// Ejemplo de uso
//*****************************

/*
#include "AdministradorDeRecursos.h"
#include "Pantalla.h"
#include "Superficies.h"

class TAdministradorDeSuperficies : public TAdministradorDeRecursos
{
 TPantalla *pantalla;
  public:
 TAdministradorDeSuperficies(TPantalla *pantalla) : TAdministradorDeRecursos(2048)
 {
    Pantalla = pantalla;
 };

 TSuperficie *Tomar(const char *Nombre)
 {
 // no estoy seguro de que este casting funcione ...
 TSuperficie *s= (TSuperficie *) TAdministradorDeRecursos::Tomar(Nombre);
 if(!s)
 {
  s = Pantalla->Cargar_Superficie(Nombre);
  if(s) Agregar(s);
 }
 return s;
 }
};

#endif


AdministradorDeRecursos.cpp#include <String.h> // para stricmp

#include "Sistema.h" // para definicion de TError
#include "AdministradorDeRecursos.h"

//*****************************
// Recursos
//*****************************

TRecurso::~TRecurso()
{
if(Uso>0) throw new TError(TError::RECURSO, "Used resource destruction: %s - usage: %d",Nombre, Uso);
if(Nombre) delete Nombre;
}

TRecurso::TRecurso()
{
Uso=0;
Siguiente=Anterior=NULL;
}

const char* TRecurso::Tomar_Nombre()
{
return Nombre;
}

void TRecurso::Liberar()
{
Uso--;
if(!Uso) Administrador->Quitar(r);
}

//*****************************
// Administrador de recursos
//*****************************


TAdministradorDeRecursos::TAdministradorDeRecursos(int n_recursos)
{
n_Recursos = n_recursos;
Recursos = new TRecursoPtr[n_Recursos];
for(int i=0; i<n_Recursos; i++) Recursos[i]=NULL;
};

TAdministradorDeRecursos::~TAdministradorDeRecursos()
{
for(int i=0; i<n_Recursos; i++)
  while(Recursos[i])
  {
   TRecurso *s=Recursos[i]->Siguiente;
   delete Recursos[i];
   Recursos[i]=s;
  }
delete Recursos;
};

int TAdministradorDeRecursos::Calcular_Hash(const char *t)
{
   int h=0;
   static int desplazamientos[8] = { 0, 5, 4, 1, 2, 3, 8, 7 };

   for(int i=0; t[i]; i++) h^= int(t[i]) << desplazamientos[i & 7];

   return h % n_Recursos;
};

void TAdministradorDeRecursos::Agregar(TRecurso *r)
{
int h=Calcular_Hash(r->Nombre) % n_Recursos;
Recursos[h]->Anterior=r;
   r->Siguiente=Recursos[h];
r->Anterior=NULL;
r->Administrador=this;
r->Uso++;
Recursos[h]=r;
}

void TAdministradorDeRecursos::Quitar(TRecurso *r)
{
int h=Calcular_Hash(r->Nombre) % n_Recursos;
if(r->Siguiente) r->Siguiente->Anterior=r->Anterior; // el rey de la lista enlazada!
if(r->Anterior) r->Anterior->Siguiente=r->Siguiente;
if(Recursos[h] == r) Recursos[h]=r->Siguiente;
delete r;
}

TRecurso *TAdministradorDeRecursos::Tomar(const char *Nombre)
{
int h=Calcular_Hash(Nombre) % n_Recursos;
TRecurso *r = Recursos[h];
while(r)
{
 if(!stricmp(r->Nombre, Nombre))
 {
  r->Uso++; // si lo pediste tenes que liberarlo
  return r;
 }
 r=r->Siguiente;
}
return NULL;
};


Alguna sugerencia? (En conceptos principalmente, puede que halla errores de escritura o codificación pero mas que nada requiero confirmar la idea).

Depaso cañaso:
Como funciona el up-casting? Es necesario usar dynamic cast?

Saludos.

CoLSoN2

 Primero de todo, vale que escribas el código en español (aunque me de repelús), pero cosas como "Tomar_Nombre();" deberían estar penadas con la silla eléctrica.

#1 - STL existe y está muy probada. ¡Úsala!
- std::string en vez de char*
- std::list para listas
- std::map para tablas hash. Hay otras templates pero creo que esta es la más estándar.

#2 - Mantén coherencia en el formateo / nomenclatura. ¿Qué significa el prefijo "n_" de TAdministradorDeRecursos::n_Recursos?

#3 - ¿Porqué no templatizas la clase TAdministradorDeRecursos? De este modo para hacer las subclases no tendrías que estar downcasteando continuamente a tu clase específica.
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

CoLSoN2

 
CitarComo funciona el up-casting? Es necesario usar dynamic cast?
Siempre es recomendable utilizar los métodos de casting propios de C++ (*_cast<>) y no los de C ((tipo)variable). Por cierto, un upcast siempre es seguro, pero aquí estás haciendo lo contrario, downcast de tu clase base (TRecurso) a una derivada (TSuperficie).
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

Pogacha

 
CitarPrimero de todo, vale que escribas el código en español (aunque me de repelús), pero cosas como "Tomar_Nombre();" deberían estar penadas con la silla eléctrica.
Jajaja! tampoco me gustaba al principio pero me acostumbré y despues de un rato se empieza a ver bien ... en casi dos horas de pensar e investigar decidí usar esta forma (cambie todo el codigo a español puro).

Citar#1 - STL existe y está muy probada. ¡Úsala!
- std::string en vez de char*
- std::list para listas
- std::map para tablas hash. Hay otras templates pero creo que esta es la más estándar.
Esto seria lo mejor, pero me da miedo ... una vez lo descargue, lo mire, lo mire ... pero no entendí nada, no sabia como usarlo, que costo tendría y tener que leer todo el codigo y entenderlo lo supuse mas caro que hacer mis algoritmos de listas y esas cosas que me salen tan bien ;) y no me cuestan nada. De todas formas deberia usarlas pero me suena a un balde de agua fría, alguna recomendación?.

Citar#2 - Mantén coherencia en el formateo / nomenclatura. ¿Qué significa el prefijo "n_" de TAdministradorDeRecursos::n_Recursos?
Es nomenglatura de estructuras de C para codificación veloz, muy util para escribir algoritmos como una parva, un hash, un ordenamiento, listas enlazadas y esas cosas, yo uso esta nomenglatura para todo.
Lo que es una clase o estructura tiene el prefijo T, los objetos en mayuscula, los parametros de una función en minuscula y el prefijo n_ a toda cantidad que defina el numero de items de la complejidad  (el n de la o(n)). No es la mejor pero es facil de aprender y evita muchas confusiones y un analisis de complejidad instantaneo  :P, una vez que te acostumbras al n_ no te lo podras quitar de encima nunca mas. Esto viene de cuando entrenaba en el equipo olimpico de Argentina para las IOI ... ahí habia que escribir una parva sin errores en 5 minutos como mucho ...

Citar#3 - ¿Porqué no templatizas la clase TAdministradorDeRecursos? De este modo para hacer las subclases no tendrías que estar downcasteando continuamente a tu clase específica.
Esta me gusta mucho, voy a hacer mis pruebas ...


CitarSiempre es recomendable utilizar los métodos de casting propios de C++ (*_cast<>) y no los de C ((tipo)variable). Por cierto, un upcast siempre es seguro, pero aquí estás haciendo lo contrario, downcast de tu clase base (TRecurso) a una derivada (TSuperficie).
Toda la razón del mundo, a lo que le desconfio es al downcast.
Pero suponiendo que ponga un static_cast me lo tomará aquí?, el dynamic es para polimorficas tan solo verdad?

Te agradezco un monton, era el tipo de respuesta que esperaba, perdon por la demora en contestar.
Saludos.

ajmendoza

 Viva programar en español coño! que pa eso es nuestra lengua!. Y el codigo lo vamos a ver nosotros y nuestra madre..
(ale, ya me he quedao tranquilo)

CoLSoN2

 
CitarDe todas formas deberia usarlas pero me suena a un balde de agua fría, alguna recomendación?.
Sí, que aprendas a usarla y la uses. No se que compilador estás usando pero debería venirte incluída en él de serie pues forma parte de la librería estándar de C++ y como tal deberías aprender a usarla.

Citarel dynamic es para polimorficas tan solo verdad?
No estoy muy puesto en el tema pero creo que el dynamic_cast se usa entre casteos de punteros a clases (upcast/downcast) mientras que static_cast se usa para casteos estáticos, como su propio nombre indica. Por ejemplo, para castear un enum a int o viceversa.
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

AK47

 Mirate los Thinking in C++ volumen 1 y 2 (sobretodo el 2) para aprenderte el uso de las STL. Buscalos en google que estan gratis para bajarlos ;)

Pogacha

 
CitarSí, que aprendas a usarla y la uses. No se que compilador estás usando pero debería venirte incluída en él de serie pues forma parte de la librería estándar de C++ y como tal deberías aprender a usarla.
MSVC 6.0 sin ningún service pack y de eso no hay nada.

CitarMirate los Thinking in C++ volumen 1 y 2 (sobretodo el 2) para aprenderte el uso de las STL. Buscalos en google que estan gratis para bajarlos 
Ok ...

Gracias

CoLSoN2

 
CitarMSVC 6.0 sin ningún service pack y de eso no hay nada.
Dudo que la STL no viniera de serie en VC6, aún sin service packs. Por cierto, ya tiene delito seguir usando VC6 como para encima hacerlo sin ningún SP...

En todo caso, te sugiero que o cambies de compilador o uses otra implementación de STL como STLporto la de SGI, porque la que lleva el VC6 es una mierda.
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor






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.