Skip to main content
Inspiring
December 5, 2022
Answered

Pass json object from JSX file to c++ plugin and return an array of json object from c++ plugin

  • December 5, 2022
  • 2 replies
  • 1501 views

Hi All,

 

I am looking for a solution in which I can pass  json object as an argument to a scriptable method

I went through the scriptable plugin architecture and created a scriptable resource and added a method on document object as follows

resource VersionedScriptElementInfo(1)
{
//Contexts
{
kCS2ScriptVersion, kCoreScriptManagerBoss, kWildFS, k_Wild,
}
{
Method
{
kTestApplyScriptElement,
e_TestApplyTag,
"apply tag",
"Apply the tag",
Int32Type, // status code
"Status: 0 if ok, non-zero if error"
{
p_TagInfo, "tag info", "tag info ...", RecordType(kAnyObjectScriptElement), kRequired,
}
}

// Connects this plug-in's text attribute to scripting and INX round trip.
Provider
{
kTestProviderBoss,
{
Object{ kDocumentObjectScriptElement },
Method{ kTestApplyScriptElement }
}
}
}

 

my provider file look like as follows

=====

ErrorCode TestProvider::HandleMethod(ScriptID methodID, IScriptRequestData* data, IScript* script)
{
ErrorCode status = kFailure;
do {
switch (methodID.Get()) {
case e_TestApplyTag:
status = this->ApplyTag(data, script);
break;
default:
status = PrefsScriptProvider::
HandleMethod
(propID, data, script);
;
}
 
} while(false);
 
return status;
}

=====

Now what code I should write in TestProvider::ApplyTag to get the key value pair of json object which I send from jsx file while calling this function.

 

code in jsx file is look like as follows

function test() {

var info = {};

info["name"] = "abc";

info["id"] = "1";

info["address"] = "abc xyz";

info["code"] = "w12";

app.activeDocument.applyTag(info)

}

 

Please help me to get solve it.

 

Regards,

Alam

This topic has been closed for replies.
Correct answer alam_84

Regarding ScriptID vs. JSON key, I also mentioned above that the scripting glue is working on ScriptIDs. It is easier to compare 32 bit integers rather than strings, so all the example code is referring to p_someProperty and m_someMethod for a reason. Also, the mapping must be declared in the ScriptInfo resource, otherwise the particular property will be lost in your call.

If you really need to translate the ScriptID back to a string e.g. for debug output, you have to get hold of the appropriate ScriptInfoManager (see IScriptUtils) - the names are formatted differently per scripting language e.g. AppleScript may break them up using spaces instead of camelCase, while VBScript may use CamelCase ...


I achieved my goals by making following changes.

p_TagInfo, "tag info", "tag info ...",  VariableArrayType( kVariableLength ){ StringArrayType(2) }

and use CusDtLnkOptionScriptProvider.cpp for storing data and fetching it.

in jsx file I pass data as follows

var testData = [];

testData.push(["key1", "val1");

testData.push(["key2", "val2");

app.activeDocument.applyTag(testData)

2 replies

Brainiac
December 5, 2022

JSON is a set of conditions that applies to a string. You can pass strings thru the scripting glue, but those JSON conditions are not enforced. At the C++ side, you'd also have to write your own parser or use e.g. the one provided by boost.

 

You can not pass arbitrary plain objects - property names must be predeclared in a ScriptInfo resource of any plug-in, the glue code will map the name to a ScriptID using the ScriptInfo database.

 

When you declare something to be RecordType(yourObjectType), that means the record is to be validated to use only properties from yourObjectType . I don't know whether there is any magic script element ID to accept arbitrary records, your RecordType(kAnyObjectScriptElement) is not used in the application itself. How did you come to that idea?

 

Anyway, if it works, your method (in the script provider) would have to extract the argument from its ScriptRequestData (ask for p_TagInfo). That would copy the value into a ScriptData. You can examine the ScriptData, ask whether it is indeed a record then extract that into a ScriptRecordData and iterate further on.

 

If your generic record approach fails, the closest you can get with a scriptable plug-in is to use AnyType instead of that RecordType. For a JavaScript object you'd receive a record with the subset of keys where the name could get found, other properties are just omitted. Of course AnyType would also accept other types (strings, numbers, arrays, native objects etc.), you'd have to weed them out yourself.

 

Another alternative could be the separate ExtendScript SDK resulting in an ExternalObject, with the disadvantage that ExternalObject is likely not supported in UXP scripting and the SDK is for thrill seekers at best. The SDK used to ship with ESTK, but nowadays the best bet would be the developer downloads of Bridge (the CC app). Be warned that it took me several days to get something going with it and it has many other limitations.

alam_84Author
Inspiring
December 6, 2022

I try to use following api in provider class to fetch data that is send from jsx file.

const ScriptRecordData props = data->GetRequestData() ; and iterate it as follows

for ( ScriptRecordData::const_iterator iter = props.begin() ; iter != props.end() ; ++iter )
{

// but iter->Key() returns me scriptId not json key

// I could not debug the plugin because on xcode debug is not working an alert is shown when try to attach.

}

 

Do I need to follow the approach that is shown in snippetrunner plugin that for kSnpRunnableObjectScriptElement has some properties and for each property they used IStringData or IStringListData

and for my requirments where I have json objects tof 10-12 properties and need to pass that object into scriptable method, Do I need to add 10-12 IStringData interface to my boss class?

and also do I need to inherit my provider class with RepresentScriptProvider.?

alam_84Author
Inspiring
December 6, 2022

Moreever in context of snippet runner plugin. in fr file there is a comment that

p_SnpRunnableName is bind to IID_ISNIPPETNAME, where is this binding code written?

alam_84Author
Inspiring
December 5, 2022

Is it possible to pass json object from jsx scripts to c++ plugin? if yes then what scriptDatatype I need to use in fr file and how to extract value in provider.cpp file.