Skip to content

Commit

Permalink
Improve adaptive converter caching
Browse files Browse the repository at this point in the history
  • Loading branch information
hyazinthh committed Sep 16, 2024
1 parent c232790 commit e806a5c
Showing 1 changed file with 12 additions and 14 deletions.
26 changes: 12 additions & 14 deletions src/Aardvark.Rendering/Resources/Adaptive/AdaptiveConverter.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ open Aardvark.Base

open System
open System.Reflection
open System.Collections.Concurrent
open FSharp.Data.Adaptive

[<AutoOpen>]
Expand Down Expand Up @@ -45,22 +46,21 @@ module AdaptivePrimitiveValueConverterExtensions =
member x.ConvertUntyped(value : IAdaptiveValue) = x.Convert(value)
member x.Convert(array : aval<Array>) = x.Convert(array)

let private staticInstanceCache = Dict<Type, obj>()
let private getStaticInstance (t : Type) : 'T =
lock staticInstanceCache (fun () ->
staticInstanceCache.GetOrCreate(t, fun t ->
let p = t.GetProperty("Instance", BindingFlags.Static ||| BindingFlags.NonPublic ||| BindingFlags.Public)
p.GetValue(null)
) |> unbox<'T>
)
let private converterCache = ConcurrentDictionary<Type * Type, obj>()

let private getConverter<'T when 'T :> IAdaptiveConverter> (inputType: Type) (outputType: Type) : 'T =
converterCache.GetOrAdd((inputType, outputType), fun (inputType, outputType) ->
let tconv = typedefof<AdaptiveConverter<_,_>>.MakeGenericType [| inputType; outputType |]
let prop = tconv.GetProperty(nameof(AdaptiveConverter.Instance), BindingFlags.Static ||| BindingFlags.NonPublic ||| BindingFlags.Public)
prop.GetValue(null)
) |> unbox<'T>

let convertArray (inputElementType : Type) (array : aval<Array>) : aval<'T[]> =
if inputElementType = typeof<'T> then
array |> AdaptiveResource.mapNonAdaptive unbox
else
try
let tconv = typedefof<AdaptiveConverter<_,_>>.MakeGenericType [| inputElementType; typeof<'T> |]
let converter : IAdaptiveConverter<'T> = tconv |> getStaticInstance
let converter : IAdaptiveConverter<'T> = getConverter inputElementType typeof<'T>
converter.Convert(array)
with
| InvalidConversion exn -> raise exn
Expand All @@ -71,8 +71,7 @@ module AdaptivePrimitiveValueConverterExtensions =
value
else
try
let tconv = typedefof<AdaptiveConverter<_,_>>.MakeGenericType [| inputType; outputType |]
let converter : IAdaptiveConverter = tconv |> getStaticInstance
let converter : IAdaptiveConverter = getConverter inputType outputType
converter.ConvertUntyped(value)
with
| InvalidConversion exn -> raise exn
Expand All @@ -83,8 +82,7 @@ module AdaptivePrimitiveValueConverterExtensions =
unbox value
else
try
let tconv = typedefof<AdaptiveConverter<_,_>>.MakeGenericType [| inputType; typeof<'T> |]
let converter : IAdaptiveConverter<'T> = tconv |> getStaticInstance
let converter : IAdaptiveConverter<'T> = getConverter inputType typeof<'T>
converter.Convert(value)
with
| InvalidConversion exn -> raise exn

0 comments on commit e806a5c

Please sign in to comment.