1mutable struct Context 2 ref::RefValue{C.CeedQFunctionContext} 3 data::Any 4 function Context(ref::Ref{C.CeedQFunctionContext}) 5 obj = new(ref) 6 finalizer(obj) do x 7 # ccall(:jl_safe_printf, Cvoid, (Cstring, Cstring), "Finalizing %s.\n", repr(x)) 8 C.CeedQFunctionContextDestroy(x.ref) 9 end 10 return obj 11 end 12end 13Base.getindex(ctx::Context) = ctx.ref[] 14Base.show(io::IO, ::MIME"text/plain", c::Context) = 15 ceed_show(io, c, C.CeedQFunctionContextView) 16 17""" 18 Context(ceed::Ceed, data; mtype=MEM_HOST, cmode=USE_POINTER) 19 20Create a `CeedQFunctionContext` object that allows user Q-functions to access an arbitrary 21data object. `data` should be an instance of a mutable struct. If the copy mode `cmode` is 22`USE_POINTER`, then the data will be preserved from the GC when assigned to a `QFunction` 23object using `set_context!`. 24 25Copy mode `OWN_POINTER` is not supported by this interface because Julia-allocated objects 26cannot be freed from C. 27""" 28function Context(c::Ceed, data; mtype=MEM_HOST, cmode=USE_POINTER) 29 ref = Ref{C.CeedQFunctionContext}() 30 C.CeedQFunctionContextCreate(c[], ref) 31 ctx = Context(ref) 32 set_data!(ctx, mtype, cmode, data) 33 return ctx 34end 35 36function set_data!(ctx::Context, mtype, cmode::CopyMode, data) 37 # Store a reference to the context data so that it will not be GC'd before 38 # it is accessed in the user Q-function. 39 # A reference to the context object is stored in the QFunction object, and 40 # references to the QFunctions are stored in the Operator. 41 # This means that when `apply!(op, ...)` is called, the context data is 42 # ensured to be valid. 43 if cmode == USE_POINTER 44 ctx.data = data 45 elseif cmode == OWN_POINTER 46 error("set_data!: copy mode OWN_POINTER is not supported") 47 end 48 49 C.CeedQFunctionContextSetData( 50 ctx[], 51 mtype, 52 cmode, 53 sizeof(data), 54 pointer_from_objref(data), 55 ) 56end 57