rai finanzas opengl common-lisp

opengl - finanzas - Administrar recursos externos(similar a RAII en C++?)



rai finanzas (1)

Si desea manejar un alcance de extensión dinámica, use UNWIND-PROTECT . Si el programa abandona ese ámbito, normalmente o por error, se llama al formulario de limpieza. Simplemente desasigna o haz lo que quieras.

A veces Lisps utiliza algún tipo de mecanismo de "recursos" para realizar un seguimiento de los objetos usados ​​y no utilizados. Dicha biblioteca proporciona una asignación rápida desde un grupo, asignación, inicialización, desasignación, asignación de objetos con recursos. CLIM define una versión primitiva: Recursos . CCL tiene una versión primitiva similar.

En un Lisp con ''temporizadores'', puede ejecutar una función periódicamente que busca ''objetos'' para desasignar. En CCL puede usar un hilo que duerme durante un cierto tiempo utilizando PROCESS-WAIT .

Un poco sobre tu estilo de codificación:

  • FORMAT puede enviar directamente a una secuencia, no se necesita IMPRIMIR
  • (defmethod foo ((e bar)) (if e ...)) : el IF no tiene sentido. e siempre será un objeto.
  • muchos PROGN no son necesarios. Donde sea necesario, podría eliminarse cuando IF sea ​​reemplazado por WHEN .

En el ceceo común, ¿cuál es la forma preferida de administrar recursos externos (sockets, manejadores de sistemas de archivos, etc.)?

Estoy tratando de hacer un juego de plataformas opengl 2D simple en lisp común. El problema es que no estoy muy seguro de cómo rastrear las texturas de OpenGL (debe eliminarse con glDeleteTextures cuando ya no sean necesarias).

En C ++, preferí usar el siguiente esquema:

  1. Hacer clase de textura
  2. Haga punteros inteligentes / débiles para esa clase de textura
  3. Almacene texturas en el mapa (diccionario / hashtable) que asigna nombres de archivo a punteros débiles para texturas.
  4. Cuando se solicitan nuevas texturas, busque en el mapa y vea si hay un puntero débil no nulo (nulo) disponible. Si está disponible, devuelve el objeto existente; de ​​lo contrario, carga una nueva textura.

Sin embargo, no estoy muy seguro de cómo portar este esquema al ceceo común, porque:

  1. No hay destructores
  2. Hay un recolector de basura, y parece que mi implementación (clozureCL en la plataforma de Windows) admite finalizadores, pero hasta donde puedo decir, no se recomienda usar finalizadores con ceceo común porque no son deterministas.
  3. La forma preferida de administrar los recursos usando (with-* no parece adecuada allí, porque los recursos pueden ser compartidos, y cargados / descargados en el medio de la llamada a la función.

Por lo que puedo decir, hay varios enfoques disponibles:

  1. Renunciar a la administración automática de recursos, y hacerlo manualmente.
  2. Implemente algo similar a C ++ RAII, weakpointer y smartpointer usando macros (este código probablemente no funcione):

    (defclass destructible () ()) (defmethod destroy ((obj destructible)) (print (format nil "destroy: ~A" obj))) (defparameter *destructible-classes-list* nil) (defmethod initialize-instance :after ((obj destructible) &key) (progn (push *destructible-classes-list* obj) (print (format nil "init-instance: ~A" obj)))) (defmacro with-cleanup (&rest body) `(let ((*destructible-classes-list* nil)) (progn ,@body (mapcar (lambda (x) (destroy x)) *destructible-classes-list*)))) (defclass refdata (destructible) ((value :accessor refdata-value :initform nil) (ref :accessor refdata-ref :initform 0) (weakrefcount :accessor refdata-weakref :initform 0))) (defmethod incref ((ref refdata)) (if ref (incf (refdata-ref ref)))) (defmethod decref ((ref refdata)) (if ref (progn (decf (refdata-ref ref)) (if (<= (refdata-ref ref) 0) (progn (destroy (refdata-value ref)) (setf (refdata-value ref) nil)))))) (defmethod incweakref ((ref refdata)) (if ref (incf (refdata-weakref ref)))) (defmethod decweakref ((ref refdata)) (if ref (decf (refdata-weakref ref)))) (defclass refbase (destructible) ((data :accessor refbase-data :initform nil))) (defmethod deref ((ref refbase)) (if (and (refbase-data ref) (refdata-value (refbase-data ref))) (refdata-value (refbase-data ref)) nil)) (defclass strongref (refbase) ()) (defclass weakref (refbase) ()) (defmethod destroy :before ((obj strongref)) (decref (refbase-data obj))) (defmethod destroy :before ((obj weakref)) (decweakref (refbase-data obj))) (defmethod initialize-instance :after ((obj strongref) &key) (incref (refbase-data obj))) (defmethod initialize-instance :after ((obj weakref) &key) (incweakref (refbase-data obj)))

Hay una mejor manera de hacerlo?

Conceptos de C ++ Explicación: ¿Qué es un puntero inteligente y cuándo debo usar uno?