简体   繁体   中英

Managing Resources with FRP in Scala RX

I'm using scala rx for an application. I have a reactive variable holding a File (which is a PDF file). I'm using a library to render pages from this pdf file to the screen. Now the PDF library I'm using gives me an object (let's call it Doc ), which I can use to render single pages. But in order to render a page from a Doc object, the Doc object must be opened (thus the resource must be acquired).

Right now I'm loading the pdf file for each page I'm rendering anew (creating a new Doc object and closing it after rendering the single page). This makes the rendering of the page functional (given a file and a page number, return an image).

Is there a way to cling to an opened resource and close it on change in FRP in general, and for scala rx in particular? How would one handle this very common situation?

You can simply enclose the Doc object. So instead of render being

def render(file: File, pageNumber: Int): Image =  // blah blah blah

change it to:

def open(file: File): (Int => Image) = {
  val doc = // call your library to read file
  (x: Int) => doc.getPage(x)
}

and then pass the function open returns to whatever page change signal you're reacting to.

Edit : Oh, I see, so you're saying you want it to close the file whenever the file:File signal changes to be a different file. In that case you should be able do something like this:

def pageGetterRx(file: Rx[File]): Rx[Int => Image] = {
  val doc: Var[Doc] = Var(null)
  val o = file.foreach { f =>
    Option(doc()).foreach(_.close)
    doc() = PdfLib.read(f)  // or however you do the reading
  }
  Rx {
    (x: Int) => doc().getPage(x)
  }
}

Edit 2 : To clarify, if you impose a "assemble network of functions phase / run the network on some signal(s) phase" distinction on FRP, the above function would be called only once; in the assemble phase. To say it another way, pageGetterRx (a lousy name, I'm fully aware) doesn't participate in a FR way, instead it returns a signal of lambdas that each close over one particular file and return pages from it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM