Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin API: add a CreateScriptArray method #2313

Open
ivan-mogilko opened this issue Jan 25, 2024 · 2 comments
Open

Plugin API: add a CreateScriptArray method #2313

ivan-mogilko opened this issue Jan 25, 2024 · 2 comments
Labels
context: plugin api type: enhancement a suggestion or necessity to have something improved

Comments

@ivan-mogilko
Copy link
Contributor

ivan-mogilko commented Jan 25, 2024

When a plugin registers a script function that returns a String, it must use IAGSEngine::CreateScriptString in order to create an internal engine's ScriptString object, that engine knows how to deal with.

But there's no such function for creating a dynamic array object. This means that plugins cannot register script functions that return dynamic arrays.

Optionally same could be done for "user struct" object. The use case for this is when plugin wants to return a managed struct, but not manage that struct type itself: don't provide a type's manager, and have struct's data stored in engine's mem.

@ivan-mogilko ivan-mogilko added type: enhancement a suggestion or necessity to have something improved context: plugin api labels Jan 25, 2024
@ericoporto
Copy link
Member

ericoporto commented May 1, 2024

But there's no such function for creating a dynamic array object.

The closest thing for this we already have is the DynamicArrayHelpers function to create string arrays - we use for retrieving keys from the dictionary and the set.

DynObjectRef DynamicArrayHelpers::CreateStringArray(const std::vector<const char*> items)
{
// NOTE: we need element size of "handle" for array of managed pointers
DynObjectRef arr = globalDynamicArray.Create(items.size(), sizeof(int32_t), true);
if (!arr.Obj)
return arr;
// Create script strings and put handles into array
int32_t *slots = static_cast<int32_t*>(arr.Obj);
for (auto s : items)
{
DynObjectRef str = ScriptString::Create(s);
// We must add reference count, because the string is going to be saved
// within another object (array), not returned to script directly
ccAddObjectReference(str.Handle);
*(slots++) = str.Handle;
}
return arr;
}

Don't know how to make this generic for any object as plugin interface. Take both void* and handle of each element?

We never in script take an array as input! So the reverse of receiving an array as input in a plugin would take more effort.

@ivan-mogilko
Copy link
Contributor Author

ivan-mogilko commented May 1, 2024

Don't know how to make this generic for any object as plugin interface. Take both void* and handle of each element?

If a plugin returns dynamic array, then it knows the type and size of elements. The engine only need to know the size of element, and its count, in order to create a buffer of necessary length. Plugin will be supposed to write the memory itself, just like with script strings.

In regards to type, at the very least the function should accept "is array of pointers" argument, to let engine know that it has to dereference these.

In AGS 4, since we support RTTI and proper garbage collector, then "type id" could be another argument. It may be treated as optional, since it's mostly required for dereferencing managed pointers in structs, and plugins usually expose structs with attributes instead. But, I suppose, that for AGS 4 we may also add GetTypeidByName, which plugins can use to get typeid value for the type that it declares.

We never in script take an array as input! So the reverse of receiving an array as input in a plugin would take more effort.

Plugin can receive arrays in its script functions just like it can receive strings: a pointer to a buffer of memory. If it subscribed for its receival, then it should know which type of elements are expected there.

In simple words: engine is only responsible for allocating the object and managing its references (as usual), plugin has to read and write the buffer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
context: plugin api type: enhancement a suggestion or necessity to have something improved
Projects
None yet
Development

No branches or pull requests

2 participants