Preserve auto-place nil and objects in connection-data

This commit is contained in:
David Botton 2024-06-19 23:08:41 -04:00
parent 540d9aab5a
commit 519cadddd4
3 changed files with 21 additions and 44 deletions

View file

@ -104,12 +104,6 @@
"Object.entries(clog).forEach(function(c,i,a)
{if ((c[1] !== null) && (typeof c[1] === 'object') && (c[1].nodeType===1))
{if (c[1].isConnected===false) {$(clog['body']).trigger('gc', c[0])}}})"))
(when *browser-clean-on-ping*
;; run browser clean
(execute connection-id
"Object.entries(clog).forEach(function(c,i,a)
{if ((c[1] !== null) && (typeof c[1] === 'object') && (c[1].nodeType===1))
{if (c[1].isConnected===false) {delete clog[c[0]]}}})"))
(when *verbose-output*
(format t "Connection ~A Ping~%" connection-id)))
((equal (first ml) "E")

View file

@ -36,7 +36,6 @@ script."
(*verbose-output* variable)
(*browser-gc-on-ping* variable)
(*browser-clean-on-ping* variable)
(*break-on-error* variable)
(*disable-clog-debugging* variable)
@ -86,7 +85,6 @@ script."
(defvar *verbose-output* nil "Verbose server output (default false)")
(defvar *browser-gc-on-ping* nil "Run a browser-gc on every ping")
(defvar *browser-clean-on-ping* nil "Run a browser-clean on every ping")
(defvar *break-on-error* t "Allow invoking debugger (default true)")
(defvar *disable-clog-debugging* nil "When true turns off debug hooks")

View file

@ -11,7 +11,8 @@
(defvar *store-new-objects* nil
"Dynamic variable that when true every create-* or attach-* will also
create a connection-data-item keyed by the html-id")
create a connection-data-item keyed by the html-id. Any object stored
will not be garbage collected on the browser side or lisp side.")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Implementation - clog-element
@ -114,8 +115,8 @@ possible tag and keywords."))
(:documentation "Create a new CLOG-ELEMENT or sub-type of CLOG-TYPE from HTML
as child of CLOG-OBJ and if :AUTO-PLACE (default t) place-inside-bottom-of
CLOG-OBJ, you can also set auto-place to :bottom or :top. If HTML-ID is nil one
will be generated. If auto-place is nil, note that if browser-clean is called
or clog-connect:*browser-clean-on-ping* is t the browser side will be destroyed."))
will be generated. If auto-place is nil the object is stored in the connection-data
and not subject to browser-gc requests."))
(defmethod create-child ((obj clog-obj) html &key (html-id nil)
(auto-place t)
@ -129,7 +130,8 @@ or clog-connect:*browser-clean-on-ping* is t the browser side will be destroyed.
(:bottom (place-inside-bottom-of obj child))
(:top (place-inside-top-of obj child))
(t (place-inside-bottom-of obj child)))
child)))
(setf (connection-data-item obj html-id) obj))
child))
;;;;;;;;;;;;;;;;;;;;;
;; attach-as-child ;;
@ -2244,7 +2246,8 @@ is set to :table-cell or for labels on form elements."))
;;;;;;;;;;;;;;;;;;;;;
(defgeneric remove-from-dom (clog-element)
(:documentation "Remove CLOG-Element from the DOM."))
(:documentation "Remove CLOG-Element from the DOM. If object
is not stored in connection-data will become subject to browser-gc requests."))
(defmethod remove-from-dom ((obj clog-element))
(jquery-execute obj "remove()"))
@ -2260,8 +2263,8 @@ is set to :table-cell or for labels on form elements."))
(let ((s (format nil "^~A\\:" (html-id obj))))
(maphash (lambda (k v)
(declare (ignore v))
(when (ppcre:scan s k)
(remhash k (connection-data obj))))
(when (ppcre:scan s (format nil "~A" k))
(remove-connection-data-item obj k)))
(connection-data obj)))
(remove-connection-data-item obj (html-id obj))
(js-execute obj (format nil "~A=null;" (script-id obj))))
@ -2283,21 +2286,22 @@ on browser."))
;;;;;;;;;;;;;;;;
(defmethod perform-gc (obj id)
;; check if pinned
(let ((s (format nil "^~A\\:" id)))
(maphash (lambda (k v)
(declare (ignore v))
(when (ppcre:scan s k)
(remhash k (connection-data obj))))
(connection-data obj)))
(remove-connection-data-item obj id)
(js-execute obj (format nil "clog['~A']=null;" id)))
"Called by gc events from browser (internal)"
(unless (connection-data-item obj id)
(let ((s (format nil "^~A\\:" id)))
(maphash (lambda (k v)
(declare (ignore v))
(when (ppcre:scan s (format nil "~A" k))
(remove-connection-data-item obj k)))
(connection-data obj)))
(js-execute obj (format nil "clog['~A']=null;" id))))
(defgeneric browser-gc (clog-element)
(:documentation "Finalize any clog cache items on browser not in DOM.
If clog-connect:*browser-gc-on-ping* is set this is done during websocket pings.
The main use is when clearing out large amounts of DOM objects not using CLOG
destroy."))
destroy. Any object stored in the connection-data will not be garbage collected
on the browser or Lisp side until DESTROY."))
(defmethod browser-gc ((obj clog-element))
(js-execute obj
@ -2305,25 +2309,6 @@ destroy."))
{if ((c[1] !== null) && (typeof c[1] === 'object') && (c[1].nodeType===1))
{if (c[1].isConnected===false) {$(clog['window']).trigger('gc', c[0])}}})"))
;;;;;;;;;;;;;;;;;;;
;; browser-clean ;;
;;;;;;;;;;;;;;;;;;;
(defgeneric browser-clean (clog-element)
(:documentation "Remove any clog cache items on browser not in DOM.
If clog-connect:*browser-clean-on-ping* is set this is done during websocket pings.
Care should be taken as any clog-element not placed in the DOM will be deleted
on the browser side (for examle :auto-place nil set and not later placed.)
The main use is when clearing out large amounts of DOM objects not using CLOG
destroy. This has the advantage that no events are fired, but will leave
some lingering data on the Lisp side unless connection until closed."))
(defmethod browser-clean ((obj clog-element))
(js-execute obj
"Object.entries(clog).forEach(function(c,i,a)
{if ((c[1] !== null) && (typeof c[1] === 'object') && (c[1].nodeType===1))
{if (c[1].isConnected===false) {delete clog[c[0]]}}})"))
;;;;;;;;;;;
;; click ;;
;;;;;;;;;;;