callExtension: Difference between revisions
Jump to navigation
Jump to search
Lou Montana (talk | contribs) m (Text replacement - " +" to " ") |
Lou Montana (talk | contribs) m (Text replacement - " \| +(x[0-9]|p[0-9]{1,2}|descr|game[0-9]|version[0-9]|s[0-9]|exec|r[0-9]|arg|eff|branch|serverExec|gr[0-9]|mp|pr|seealso) *=" to " |$1=") |
||
Line 58: | Line 58: | ||
| [[String]] - data sent back from extension; If the extensiion was not found an empty String will be returned | | [[String]] - data sent back from extension; If the extensiion was not found an empty String will be returned | ||
| s2= extension '''callExtension''' [function, arguments] {{Since|arma3|1.67|y}} | |s2= extension '''callExtension''' [function, arguments] {{Since|arma3|1.67|y}} | ||
|p21= extension: [[String]] - extension name | |p21= extension: [[String]] - extension name | ||
Line 66: | Line 66: | ||
|p23= arguments: [[Array]] - function arguments. Could be array of [[Anything]], each element will be converted to [[String]] automatically. Current allowed max length of this array is 2048 (since Arma 3 v1.92; previous limit: 1024) | |p23= arguments: [[Array]] - function arguments. Could be array of [[Anything]], each element will be converted to [[String]] automatically. Current allowed max length of this array is 2048 (since Arma 3 v1.92; previous limit: 1024) | ||
| r2= [[Array]] - in format [result, returnCode, errorCode], where: | |r2= [[Array]] - in format [result, returnCode, errorCode], where: | ||
* result: [[String]] - data sent back from extension. It is up to extension maker what it is. | * result: [[String]] - data sent back from extension. It is up to extension maker what it is. | ||
* returnCode: [[Number]] - integer return from extension method. It is up to extension maker to define it. | * returnCode: [[Number]] - integer return from extension method. It is up to extension maker to define it. |
Revision as of 23:30, 10 June 2021
Description
- Description:
- Description needed
- Groups:
- System
Syntax
- Syntax:
- Syntax needed
- Parameters:
- extension: String - extension name
- function: String - data sent to the extension
- Return Value:
- Return value needed
Alternative Syntax
- Syntax:
- extension callExtension [function, arguments] Template:Since
- Parameters:
- extension: String - extension name
- function: String - extension function identifier
- arguments: Array - function arguments. Could be array of Anything, each element will be converted to String automatically. Current allowed max length of this array is 2048 (since Arma 3 v1.92; previous limit: 1024)
- Return Value:
- Array - in format [result, returnCode, errorCode], where:
Examples
- Example 1:
_return = "myExtension" callExtension "stringToBeParsed";
- Example 2:
_result = "test_extension" callExtension str weapons player; _result = "test_extension" callExtension ["fnc1", getUnitLoadout player]; _result = "test_extension" callExtension ["fnc2", magazinesAmmoFull player]; _result = "test_extension" callExtension ["fnc1", [weapons player, magazines player]];
- Example 3:
_result = "test_extension" callExtension ["fnc1", [1,"two",true,[4,"five",false]]]; parseSimpleArray (_result select 0) params ["_number","_string","_boolean","_array"]; systemChat str [_number,_string,_boolean,_array];
Source Code (Download .dll)
This is an example of an extension compatible with both syntaxes. When using 1st syntax, the data is just copied from input to output. When using alt syntax, the arguments are parsed and then assembled back into string array in 2 ways: fnc1 and fnc2. fnc1 is a fraction faster.#include <string> #include <vector> #include <iterator> #include <sstream> #define CURRENT_VERSION "1.0.0.1" extern "C" { //--- Engine called on extension load __declspec (dllexport) void __stdcall RVExtensionVersion(char *output, int outputSize); //--- STRING callExtension STRING __declspec (dllexport) void __stdcall RVExtension(char *output, int outputSize, const char *function); //--- STRING callExtension ARRAY __declspec (dllexport) int __stdcall RVExtensionArgs(char *output, int outputSize, const char *function, const char **args, int argsCnt); } //--- Extension version information shown in .rpt file void __stdcall RVExtensionVersion(char *output, int outputSize) { //--- max outputSize is 32 bytes strncpy_s(output, outputSize, CURRENT_VERSION, _TRUNCATE); } //--- name callExtension function void __stdcall RVExtension(char *output, int outputSize, const char *function) { std::string str = function; strncpy_s(output, outputSize, ("Input Was: " + str).c_str(), _TRUNCATE); } //--- name callExtension [function, args] int __stdcall RVExtensionArgs(char *output, int outputSize, const char *function, const char **args, int argsCnt) { if (strcmp(function, "fnc1") == 0) { //--- Manually assemble output array int i = 0; std::string str = "["; //--- Each argument can be accessed via args[n] if (argsCnt > 0) str += args[i++]; while (i < argsCnt) { str += ","; str += args[i++]; } str += "]"; //--- Extension result strncpy_s(output, outputSize, str.c_str(), _TRUNCATE); //--- Extension return code return 100; } else if (strcmp(function, "fnc2") == 0) { //--- Parse args into vector std::vector<std::string> vec(args, std::next(args, argsCnt)); std::ostringstream oss; if (!vec.empty()) { //--- Assemble output array std::copy(vec.begin(), vec.end() - 1, std::ostream_iterator<std::string>(oss, ",")); oss << vec.back(); } //--- Extension result strncpy_s(output, outputSize, ("[" + oss.str() + "]").c_str(), _TRUNCATE); //--- Extension return code return 200; } else { strncpy_s(output, outputSize, "Avaliable Functions: fnc1, fnc2", outputSize - 1); return -1; } }
- Example 4:
fncToExecute_1 = { hint format ["Extension Result 1: %1", _this] };
fncToExecute_2 = { hint format ["Extension Result 2: %1", _this] }; fncToExecute_3 = { hint format ["Extension Result 3: %1", _this] };
addMissionEventHandler ["ExtensionCallback", { params ["_name", "_function", "_data"]; if (_name isEqualTo "test_callback") then { parseSimpleArray _data call (missionNamespace getVariable [_function, { hint "Function does not exist!" }]); }; }];
"test_callback" callExtension str "test data";
Here is a minimal example of an extension utilising extension callback (don't actually do it like this). fncToExecute_X function is called from "ExtensionCallback" event handler when it is triggered after 2 seconds of the extension call.#include <thread> #include <string> #include <chrono> extern "C" { __declspec (dllexport) void __stdcall RVExtensionRegisterCallback(int(*callbackProc)(char const *name, char const *function, char const *data)); __declspec (dllexport) void __stdcall RVExtension(char *output, int outputSize, const char *function); } int(*callbackPtr)(char const *name, char const *function, char const *data) = nullptr; void __stdcall RVExtensionRegisterCallback(int(*callbackProc)(char const *name, char const *function, char const *data)) { callbackPtr = callbackProc; } void __stdcall RVExtension(char *output, int outputSize, const char *function) { if (!callbackPtr) return; std::thread ([](std::string fnc) { using namespace std::chrono_literals; fnc = "[1,2,3," + fnc + "]"; for (int i = 1; i < 4; ++i) // run 3 times { std::this_thread::sleep_for(2s); // sleep for 2 seconds callbackPtr("test_callback", ("fncToExecute_" + std::to_string(i)).c_str(), fnc.c_str()); } }, function).detach(); }
Additional Information
- See also:
- callcompileparseSimpleArrayExtensions
Notes
-
Report bugs on the Feedback Tracker and/or discuss them on the Arma Discord or on the Forums.
Only post proven facts here! Add Note