Data Sharing
Using Shared Contexts
See the Delphi 10 and Delphi 7 examples on GitHub.
In order to use shared contexts, you must implement the IGlueContextHandler
interface:
TMainForm = class(TForm, IGlueContextHandler)
...
private
G42: IGlue42;
// The shared context handle.
myContext: IGlueContext;
protected
function HandleContext(const context: IGlueContext): HResult; stdcall;
function HandleContextUpdate(const contextUpdate: IGlueContextUpdate): HResult; stdcall;
...
Subscribing for Context Updates
To subscribe for context updates, use the SubscribeGlueContext
method. If the context doesn't exist, a new empty context will be created:
TMainForm = class(TForm, IGlueContextHandler)
...
procedure TMainForm.InitializeGlue;
...
G42.Start(inst);
// Subscribe for context updates.
G42.SubscribeGlueContext('myContextName', Self);
...
Handling Context Updates
To handle a newly activated shared context subscription, use the HandleContext
method:
function TMainForm.HandleContext(const context: IGlueContext): HResult; stdcall;
begin
// Store the context handle.
if context.GetContextInfo.Name = 'myContextName' then
myContext := context;
Result := S_OK;
end;
To handle updates of the shared context data, use the HandleContextUpdate
method:
function TMainForm.HandleContextUpdate(const contextUpdate: IGlueContextUpdate): HResult; stdcall;
var
context: IGlueContext;
contextName: WideString;
data: TGlueContextValueArray;
begin
context := contextUpdate.GetContext();
contextName := context.GetContextInfo.Name;
// Get the context data in a native data structure.
rawData := context.GetData();
data := SA_AsTranslatedContextValues(rawData);
...
SafeArrayDestroy(rawData);
Result := S_OK;
end;
Updating Contexts
To update the data of a shared context, use the SetContextData
method of the IGlueContext
interface. The data must be provided as a PSafeArray
containing GlueContextValue
values:
var
psaData: PSafeArray;
nativeData: array[0..0] of TGlueContextValue;
emails: array of TGlueValue;
begin
// Initiate an array with data.
SetLength(emails,2);
emails[0] := CreateValue('vernon.mullen@acme.com');
emails[1] := CreateValue('vernon.d.mullen@acme.com');
// Create the data with native types.
nativeData[0] := CreateContextValue('contact', CreateComposite([
CreateContextValue('name', CreateComposite([
CreateContextValue('firstName', CreateValue('Vernon')),
CreateContextValue('lastName', CreateValue('Mullen'))
], false)),
CreateContextValue('displayName', CreateValue('Vernon Mullen')),
CreateContextValue('emails', CreateTuple(emails))
], false));
// Pack the native data into a `PSafeArray`.
psaData := CreateContextValues_SA(AsGlueContextValueArray(nativeData));
// Replace the context data.
context01.SetContextData(psaData);
// Clean up.
SafeArrayDestroy(psaData);
end;
The resulting context data from the previous example, represented as JSON:
{
"contact": {
"name": {
"firstName": "Vernon",
"lastName": "Mullen"
},
"displayName": "Vernon Mullen",
"emails": [
"vernon.mullen@acme.com",
"vernon.d.mullen@acme.com"
]
}
}
If you don't want to overwrite the contents of the entire context, you can set a specific elementary or composite value by using the SetContextDataOnFieldPath
method:
var
psaData: PSafeArray;
begin
// Pack the data into a `PSafeArray`.
psaData := CreateContextValues_SA(AsGlueContextValueArray([
CreateContextValue('name', CreateComposite([
CreateContextValue('firstName', CreateValue('Vernon')),
CreateContextValue('lastName', CreateValue('Mullen'))
], false)),
CreateContextValue('displayName', CreateValue('Vernon Mullen')),
CreateContextValue('emails', CreateTuple([
CreateValue('vernon.mullen@acme.com'),
CreateValue('vernon.d.mullen@acme.com')
]))
]));
// Replace the context value for 'data.contact'.
context01.SetContextDataOnFieldPath('data.contact', psaData);
// Clean up.
SafeArrayDestroy(psaData);
end;
You can also set a specific elementary or composite value by directly providing a JSON string to the UpdateContextDataJson
method:
...
// Replace the context value for 'data.contact'.
context01.SetContextDataOnFieldPath('data.contact','{"name":{"firstName":"Vernon","lastName":"Mullen"}}');
...
Listing All Available Contexts
To obtain a list of all available contexts, use the GetKnownContexts
method:
var
saContexts: PSafeArray;
contexts: array of GlueContext;
begin
saContexts := G42.GetKnownContexts();
contexts := SA_AsGlueContextArray(saContexts);
...
SafeArrayDestroy(saContexts);
end;