Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds finalize methods to R6 class (ghost issue) (#606)
WIP. Still testing with more filter option Companion of insightsengineering/teal#1275 #### Changes description - Removes all observeEvents generated from `FilterData` when `finalize` method is called. #### How to test - Override `observeEvent` in `{teal.slice}` in order to keep track of all that are created - Stores observers in `.tmp_list` on `.GlobalEnv` - Place `browser()` call somewhere with access to `FilterData` object - Run snippet at bottom that shows count of observers that have not been destroyed - These are shown in order of creation `<order>_<parent r6 class>_<memory address>` - Run `finalize()` - Run snippet again <details> <summary>Example teal app</summary> ```r .tmp_list <- rlang::new_environment() options( teal.log_level = "INFO", teal.show_js_log = TRUE, # teal.bs_theme = bslib::bs_theme(version = 5), shiny.bookmarkStore = "server" ) pkgload::load_all("../teal.slice") pkgload::load_all("../teal") data <- teal::teal_data_module( ui = function(id) { ns <- shiny::NS(id) shiny::tagList( shiny::checkboxGroupInput( ns("datasets"), "Datasets", choices = c("ADSL", "ADTTE", "iris", "CO2", "miniACC"), selected = c("ADSL", "ADTTE", "iris", "CO2") ), shiny::actionButton(ns("submit"), label = "Submit") ) }, server = function(id, ...) { shiny::moduleServer(id, function(input, output, session) { code <- list( ADSL = expression( ADSL <- teal.data::rADSL ), ADTTE = expression({ ADTTE <- teal.data::rADTTE ADTTE$CNSRL <- as.logical(ADTTE$CNSR) }), iris = expression( iris <- iris ), CO2 = expression({ CO2 <- CO2 factors <- names(Filter(isTRUE, vapply(CO2, is.factor, logical(1L)))) CO2[factors] <- lapply(CO2[factors], as.character) }), miniACC = expression({ data( "miniACC", package = "MultiAssayExperiment", envir = environment(), overwrite = TRUE ) miniACC <- miniACC }) ) datasets <- reactive(input$datasets) shiny::eventReactive(input$submit, { code_to_eval <- do.call(c, code[datasets()]) data <- teal.code::eval_code(teal.data::teal_data(), code_to_eval) join_keys(data) <- default_cdisc_join_keys[datasets()] teal.data::datanames(data) <- datasets() data }) }) }, once = FALSE ) teal::init( data = data, modules = teal::modules( teal::example_module(label = "A"), teal::example_module(label = "B") ), filter = teal::teal_slices( # FilterRange teal.slice::teal_slice("ADSL", "AGE", selected = c(18L, 65L)), # FilterExpr teal_slice( dataname = "ADSL", id = "Female adults", expr = "SEX == 'F' & AGE >= 18", title = "Female adults" ), # FilterDatetime teal_slice( dataname = "ADTTE", varname = "ADTM", id = "Analysis DTM", selected = c("2019-03-25 07:06:18", "2020-01-22 15:03:58"), title = "Female adults" ), # FilterDate with LSTALVDT teal_slice( dataname = "ADSL", varname = "LSTALVDT", id = "Last Alive Date", selected = c("2022-02-14", "2022-11-24"), title = "Last Alive Date" ), # FilterEmpty # FilterLogical with CNSRL teal_slice( dataname = "ADTTE", varname = "CNSRL", id = "Censored", selected = TRUE, title = "Censored" ), module_specific = TRUE, teal.slice::teal_slice("ADSL", "SEX") ), title = "yada" ) |> shiny::runApp() ``` </details> <details> <summary>"observeEvent" override</summary> ```r observeEvent = function(eventExpr, handlerExpr, ... ) { logger::log_info("yada") rlang::enquo(eventExpr) rlang::enquo(handlerExpr) obs <- do.call( shiny::observeEvent, list( eventExpr = rlang::enquo(eventExpr), handlerExpr = rlang::enquo(handlerExpr), ... ), envir = parent.frame() ) # Create a temporary list to store observers and parent objects if (is.null(.GlobalEnv$.tmp_list)) .GlobalEnv$.tmp_list <- rlang::new_environment() self <- parent.env(parent.env(parent.frame()))$self obj_addr <- rlang::obj_address(self) |> as.character() |> stringr::str_replace("0x", "") obj_addr <- paste0(class(self)[1], "_", obj_addr) .tmp_list[["objects"]] <- c( list(), .tmp_list[["objects"]], setNames(list(self), obj_addr) ) .tmp_list[[sprintf("%03d_%s", length(.tmp_list[["objects"]]), obj_addr)]] <- c( list(), .tmp_list[[obj_addr]], list(obs) ) obs } ``` </details> <details> <summary>Snippet to analyse ".tmp_list"</summary> ```r ls(.tmp_list) |> purrr::keep(~!grepl("^objects$", .x)) |> vapply( \(x) { sum( vapply( .tmp_list[[x]], \(.x) isFALSE(.x$.destroyed), integer(1L) ) ) }, integer(1L) ) |> as.list() |> jsonlite::toJSON(pretty = TRUE, auto_unbox = TRUE) ``` </details> ![text444](https://github.com/user-attachments/assets/95e29e4a-d2dd-4872-859c-9dbc70ec39a6) --------- Co-authored-by: go_gonzo <[email protected]>
- Loading branch information