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