diff --git a/addons/arrays/CfgFunctions.hpp b/addons/arrays/CfgFunctions.hpp index 420276bad..abb1b1ebf 100644 --- a/addons/arrays/CfgFunctions.hpp +++ b/addons/arrays/CfgFunctions.hpp @@ -15,6 +15,30 @@ class CfgFunctions description = "Filter each element of an array via a function."; file = "\x\cba\addons\arrays\fnc_filter.sqf"; }; + // CBA_fnc_findNil + class findNil + { + description = "A function that returns the index of the first empty (nil) entry in an array."; + file = "\x\cba\addons\arrays\fnc_findNil.sqf"; + }; + // CBA_fnc_findTypeName + class findTypeName + { + description = "A function that returns the index of the first entry of a certain type in an array."; + file = "\x\cba\addons\arrays\fnc_findTypeName.sqf"; + }; + // CBA_fnc_findTypeOf + class findTypeOf + { + description = "A function that returns the index of the first entry of a certain type in an array."; + file = "\x\cba\addons\arrays\fnc_findTypeOf.sqf"; + }; + // CBA_fnc_findNull + class findNull + { + description = "A function that returns the index of the first null entry in an array."; + file = "\x\cba\addons\arrays\fnc_findNull.sqf"; + }; // CBA_fnc_getArrayDiff class getArrayDiff { diff --git a/addons/arrays/fnc_findNil.sqf b/addons/arrays/fnc_findNil.sqf new file mode 100644 index 000000000..e7a681020 --- /dev/null +++ b/addons/arrays/fnc_findNil.sqf @@ -0,0 +1,33 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_findNil + +Description: + A function that returns the index of the first empty (nil) entry in an array. + +Parameters: + The array to search in. + +Example: + (begin example) + _index = ["", Player, "test", nil, VARIABLE, nil] call CBA_fnc_findNil + (end) + +Returns: + Index of the first nil entry in the array. If there is no nil entry, the function returns -1 + +Author: + joko // Jonas +---------------------------------------------------------------------------- */ +#include "script_component.hpp" + +if !(IS_ARRAY(_this)) exitWith {-1}; + +scopeName "main"; + +{ + if (isNil "_x") then { + _forEachIndex breakOut "main"; + }; +} forEach _this; + +-1 diff --git a/addons/arrays/fnc_findNull.sqf b/addons/arrays/fnc_findNull.sqf new file mode 100644 index 000000000..41e7babf6 --- /dev/null +++ b/addons/arrays/fnc_findNull.sqf @@ -0,0 +1,37 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_findNull + +Description: + A function that returns the index of the first null entry in an array. + +Parameters: + The array to search in. + +Example: + (begin example) + _index = ["", Player, "test", objNull, VARIABLE] call CBA_fnc_findNull + (end) + +Returns: + Index of the first null entry in the array. If there is no null entry, the function returns -1 + +Author: + joko // Jonas +---------------------------------------------------------------------------- */ +#include "script_component.hpp" + +if !(IS_ARRAY(_this)) exitWith {-1}; + +scopeName "main"; + +private "_checkableTypes"; + +_checkableTypes = ["OBJECT", "CONTROL", "DISPLAY", "GROUP", "LOCATION", "TASK", "SCRIPT"]; + +{ + if (typeName _x in _checkableTypes && {isNull _x}) then { + _forEachIndex breakOut "main"; + }; +} forEach _this; + +-1 diff --git a/addons/arrays/fnc_findTypeName.sqf b/addons/arrays/fnc_findTypeName.sqf new file mode 100644 index 000000000..405d7fdc7 --- /dev/null +++ b/addons/arrays/fnc_findTypeName.sqf @@ -0,0 +1,48 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_findTypeName + +Description: + A function that returns the index of the first entry of the given type in an array. + +Parameters: + 0: Array + 1: TypeName, if parameter is a string, that contains a case insensitive typename, it will be used. Otherwise typename of the variable will be used. + +Example: + (begin example) + _index = ["OBJECT",["", Player, "test", nil, VARIABLE, nil]] call CBA_fnc_findTypeName + (end) + +Returns: + Index of the first entry of the indicated type in the array or -1 if no entry of the type could be found. + +Author: + joko // Jonas +---------------------------------------------------------------------------- */ +#include "script_component.hpp" + +#define TYPENAMES ["ARRAY", "BOOL", "CODE", "CONFIG", "CONTROL", "DISPLAY", "GROUP", "LOCATION", "OBJECT", "SCALAR", "SCRIPT", "SIDE", "STRING", "TASK", "TEXT", "TEAM_MEMBER", "NAMESPACE"] + +scopeName "main"; + +params [["_array", [], [[]]], "_typeName"]; + +if (isNil "_typeName" || {_array isEqualTo []}) exitWith {-1}; + +// If a string is given, convert to uppercase for type matching +if (IS_STRING(_typeName)) then { + _typeName = toUpper _typeName; +}; + +// If _typeName is not a typename description, use the type of that value +if !(_typeName in TYPENAMES) then { + _typeName = typeName _typeName; +}; + +{ + if (typeName _x == _typeName) then { + _forEachIndex breakOut "main"; + }; +} forEach _array; + +-1 diff --git a/addons/arrays/fnc_findTypeOf.sqf b/addons/arrays/fnc_findTypeOf.sqf new file mode 100644 index 000000000..e857c0eba --- /dev/null +++ b/addons/arrays/fnc_findTypeOf.sqf @@ -0,0 +1,43 @@ +/* ---------------------------------------------------------------------------- +Function: CBA_fnc_findTypeOf + +Description: + A function that returns the index of the first entry (either object or class name string) of the given type in an array. + +Parameters: + 0: Array + 1: Entry type, can be either Object or class name string (as returned by typeOf) + +Example: + (begin example) + _index = [["", Player, "test", nil, VARIABLE, nil], player] call CBA_fnc_findTypeOf + (end) + +Returns: + Index of the first entry of the indicated type in the array or -1 if no entry of the type could be found. + +Author: + joko // Jonas +---------------------------------------------------------------------------- */ +#include "script_component.hpp" + +scopeName "main"; + +params [["_array", [], [[]]], ["_typeOf", nil, [objNull, ""]]]; + +if (isNil "_typeOf" || {_array isEqualTo []}) exitWith {-1}; + +if (IS_OBJECT(_typeOf)) then { + _typeOf = typeOf _typeOf; +}; + +{ + if (IS_OBJECT(_x) && {typeOf _x == _typeOf}) then { + _forEachIndex breakOut "main"; + }; + if (IS_STRING(_x) && {_x == _typeOf}) then { + _forEachIndex breakOut "main"; + }; +} forEach _array; + +-1 diff --git a/addons/arrays/test.sqf b/addons/arrays/test.sqf index 6ce586d79..c3aeda4d4 100644 --- a/addons/arrays/test.sqf +++ b/addons/arrays/test.sqf @@ -5,7 +5,7 @@ #define DEBUG_MODE_FULL #include "script_component.hpp" -#define TESTS ["filter", "inject", "join", "shuffle"] +#define TESTS ["filter", "inject", "join", "shuffle", "findNil", "findNull", "findTypeName", "findTypeOf"] SCRIPT(test-arrays); diff --git a/addons/arrays/test_findNil.sqf b/addons/arrays/test_findNil.sqf new file mode 100644 index 000000000..338c470fa --- /dev/null +++ b/addons/arrays/test_findNil.sqf @@ -0,0 +1,41 @@ +// ---------------------------------------------------------------------------- +#define DEBUG_MODE_FULL +#include "script_component.hpp" + +SCRIPT(test_findNil); + +// ---------------------------------------------------------------------------- + +private ["_expected", "_result", "_fn"]; + +_fn = "CBA_fnc_findNil"; +LOG("Testing " + _fn); + +TEST_DEFINED("CBA_fnc_findNil",""); + +// Use of embedded nil +_result = ["", 5, objNull, nil, player] call CBA_fnc_findNil; +_expected = 3; +TEST_OP(_result,==,_expected,_fn); + +// Only find the first nil +_result = ["", 5, objNull, player, nil, nil] call CBA_fnc_findNil; +_expected = 4; +TEST_OP(_result,==,_expected,_fn); + +// Return a not found when there is no nil +_result = ["", 5, objNull, displayNull, player] call CBA_fnc_findNil; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return a not found when empty array is given +_result = [] call CBA_fnc_findNil; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return a not found when a non array is given +_result = "not an array" call CBA_fnc_findNil; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +nil; diff --git a/addons/arrays/test_findNull.sqf b/addons/arrays/test_findNull.sqf new file mode 100644 index 000000000..4a843236c --- /dev/null +++ b/addons/arrays/test_findNull.sqf @@ -0,0 +1,41 @@ +// ---------------------------------------------------------------------------- +#define DEBUG_MODE_FULL +#include "script_component.hpp" + +SCRIPT(test_findNull); + +// ---------------------------------------------------------------------------- + +private ["_original", "_expected", "_result", "_fn"]; + +_fn = "CBA_fnc_findNull"; +LOG("Testing " + _fn); + +TEST_DEFINED("CBA_fnc_findNull",""); + +// Use of embedded null +_result = ["", objNull, player, 3] call CBA_fnc_findNull; +_expected = 1; +TEST_OP(_result,==,_expected,_fn); + +// Only find first null +_result = ["", player, objNull, displayNull, 4] call CBA_fnc_findNull; +_expected = 2; +TEST_OP(_result,==,_expected,_fn); + +// Return not found if there is no null +_result = ["", player, 5] call CBA_fnc_findNull; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return a not found if empty array is given +_result = [] call CBA_fnc_findNull; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return a not found when a non array is given +_result = "not an array" call CBA_fnc_findNull; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +nil; diff --git a/addons/arrays/test_findTypeName.sqf b/addons/arrays/test_findTypeName.sqf new file mode 100644 index 000000000..cc5641a24 --- /dev/null +++ b/addons/arrays/test_findTypeName.sqf @@ -0,0 +1,118 @@ +// ---------------------------------------------------------------------------- +#define DEBUG_MODE_FULL +#include "script_component.hpp" + +SCRIPT(test_findTypeName); + +// ---------------------------------------------------------------------------- + +private ["_array", "_expected", "_result", "_fn"]; + +_fn = "CBA_fnc_findTypeName"; +LOG("Testing " + _fn); + +TEST_DEFINED("CBA_fnc_findTypeName",""); + +// Basic value typename check tests +_array = [[], true, {}, configFile >> "CfgWeapons", controlNull, displayNull, grpNull, locationNull, objNull, 5, scriptNull, side player, "test", taskNull, text "test", missionNamespace]; + +_result = [_array, "ARRAY"] call CBA_fnc_findTypeName; +_expected = 0; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "BOOL"] call CBA_fnc_findTypeName; +_expected = 1; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "CODE"] call CBA_fnc_findTypeName; +_expected = 2; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "CONFIG"] call CBA_fnc_findTypeName; +_expected = 3; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "CONTROL"] call CBA_fnc_findTypeName; +_expected = 4; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "DISPLAY"] call CBA_fnc_findTypeName; +_expected = 5; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "GROUP"] call CBA_fnc_findTypeName; +_expected = 6; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "LOCATION"] call CBA_fnc_findTypeName; +_expected = 7; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "OBJECT"] call CBA_fnc_findTypeName; +_expected = 8; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "SCALAR"] call CBA_fnc_findTypeName; +_expected = 9; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "SCRIPT"] call CBA_fnc_findTypeName; +_expected = 10; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "SIDE"] call CBA_fnc_findTypeName; +_expected = 11; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "STRING"] call CBA_fnc_findTypeName; +_expected = 12; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "TASK"] call CBA_fnc_findTypeName; +_expected = 13; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "TEXT"] call CBA_fnc_findTypeName; +_expected = 14; +TEST_OP(_result,==,_expected,_fn); + +_result = [_array, "NAMESPACE"] call CBA_fnc_findTypeName; +_expected = 15; +TEST_OP(_result,==,_expected,_fn); + +// Allow any capitalization +_result = [_array, "sCalAr"] call CBA_fnc_findTypeName; +_expected = 9; +TEST_OP(_result,==,_expected,_fn); + +// Allow value pass in for typename +_result = [_array, scriptNull] call CBA_fnc_findTypeName; +_expected = 10; +TEST_OP(_result,==,_expected,_fn); + +// Only find first instance of given typename +_result = [["", 4, 5], "SCALAR"] call CBA_fnc_findTypeName; +_expected = 1; +TEST_OP(_result,==,_expected,_fn); + +// Return not found if typename has no value in array +_result = [["", 5, objNull], "NAMESPACE"] call CBA_fnc_findTypeName; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return not found if empty array is given +_result = [[], "STRING"] call CBA_fnc_findTypeName; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return not found if non array is given +_result = ["not an array", "STRING"] call CBA_fnc_findTypeName; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return not found if parameters are nil +_result = [nil, nil] call CBA_fnc_findTypeName; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +nil; diff --git a/addons/arrays/test_findTypeOf.sqf b/addons/arrays/test_findTypeOf.sqf new file mode 100644 index 000000000..fec21e000 --- /dev/null +++ b/addons/arrays/test_findTypeOf.sqf @@ -0,0 +1,61 @@ +// ---------------------------------------------------------------------------- +#define DEBUG_MODE_FULL +#include "script_component.hpp" + +SCRIPT(test_findTypeOf); + +// ---------------------------------------------------------------------------- + +private ["_original", "_expected", "_result", "_fn"]; + +_fn = "CBA_fnc_findTypeOf"; +LOG("Testing " + _fn); + +TEST_DEFINED("CBA_fnc_findTypeOf",""); + +// Find by class name string +_result = [["", player, 5], typeOf player] call CBA_fnc_findTypeOf; +_expected = 1; +TEST_OP(_result,==,_expected,_fn); + +// Find by object +_result = [["", player, 5], player] call CBA_fnc_findTypeOf; +_expected = 1; +TEST_OP(_result,==,_expected,_fn); + +// Find first only +_result = [["", player, 5, objNull, player], typeOf player] call CBA_fnc_findTypeOf; +_expected = 1; +TEST_OP(_result,==,_expected,_fn); + +// Find first only, mixed solutions in array +_result = [["", typeOf player, 5, objNull, player], typeOf player] call CBA_fnc_findTypeOf; +_expected = 1; +TEST_OP(_result,==,_expected,_fn); + +// Return not found, when no matching element is in array +_result = [["", 5, objNull], typeOf player] call CBA_fnc_findTypeOf; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return not found, when empty array is passed +_result = [[], typeOf player] call CBA_fnc_findTypeOf; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return not found, when a non array is passed +_result = ["not an array", typeOf player] call CBA_fnc_findTypeOf; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return not found, when search parameter is not an object or string +_result = [["", player, 5, objNull], 5] call CBA_fnc_findTypeOf; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +// Return not found, when parameters are nil +_result = [nil, nil] call CBA_fnc_findTypeOf; +_expected = -1; +TEST_OP(_result,==,_expected,_fn); + +nil;