jaynic 1 Posted December 2, 2014 Hey all - I have the following script: /*OHTC OBJECT FUNCTION * This function is designed to be a single global function to call the methods from a "model" in a more object oriented approach * * PARAMETERS: * 0 : array : "objectPath" the file path to find the desired function. Each entry should be a string of a folder, and the * final one should be the method name. The final must NOT include the .sqf file extension * 1 : array : "parameters" the array of parameters to pass to the desired class/script - these will be passed as is without manipulation. * NOTE that a null value will be replaced with a new and empty array * An example call of this function: * [["ohtc","unit","new"],[_unit]] call ohtc_fnc_obj; * The above would call the execVm of the file at: ohtc/unit/new.sqf */ //Define our variabless private ["_parameters","_objectPath","_result","_mypath"]; _objectPath = []; if(typeName (_this select 0) == "ARRAY") then { _objectPath = _this select 0; }; _parameters = []; if(typeName (_this select 1) == "ARRAY") then { _parameters = _this select 1; }; _mypath = ""; _result = ""; diag_log format ["obj: entered with: parameters: %1, and objectPath: %2",_parameters,_objectPath]; diag_log format ["obj: parameters type: %1, and objectPath type: %2",typeName _parameters,typeName _objectPath]; diag_log format ["obj: objectPath[0]: %1",_objectPath select 0]; //If the user has passed null parameters - we replace that with a new array //Now the logic try { diag_log format ["obj: in try block: objectPath[0]: %1",_objectPath select 0]; //Validate that the user has passed us an object path, and that if it is there - its not null /* if((count _objectPath) == 0) then { //Throw the 101 error code diag_log "obj: objectPath is not an array or is empty"; throw "100"; }; */ diag_log format ["obj: _mypath type: %1",typeName _mypath]; //Now attempt to concatenate the string and call the exec vm requested //loop through the array of folders and construct the path _mypath = _objectPath select 0; diag_log "obj: initial path is: " + _mypath; for "_x" from 1 to (count _objectPath) do { _mypath = _mypath + "\" + (_objectPath select _x); }; _mypath = _mypath + ".sqf"; diag_log "obj: path constructed as: " + _mypath; _result = _parameters execVM _mypath; } catch { diag_log "obj: WARNIng caught an exception: " + _exception; /* case "100": { _nul = [["ohtc","exception","new"],["OHTC_OBJECT_FUNCTION_100", "The objectPath must not be null, or empty"]] call ohtc_fnc_obj; }; default { //Wups - we caught an unhandled exception! _nul = [["ohtc","exception","new"],["OHTC_OBJECT_FUNCTION_UNKNOWN", "An unknown exception was caught"]] call ohtc_fnc_obj; }; */ }; _result When I run it - my log shows as follows: 21:31:28 No owner 21:31:42 Cannot load sound 'a3\ui_f\data\sound\onclick.wss' 21:31:42 "obj: entered with: parameters: ["here is what i passed"], and objectPath: ["ohtc","testFunction"]" 21:31:42 "obj: parameters type: ARRAY, and objectPath type: ARRAY" 21:31:42 "obj: objectPath[0]: ohtc" 21:31:42 "obj: in try block: objectPath[0]: ohtc" 21:31:42 "obj: _mypath type: STRING" 21:31:42 "obj: initial path is: " 21:31:42 "obj: path constructed as: " 21:31:42 Error in expression <+ (_objectPath select _x); }; _mypath = _mypath + ".sqf"; diag_log "obj: path co> 21:31:42 Error position: <_mypath + ".sqf"; diag_log "obj: path co> 21:31:42 Error Undefined variable in expression: _mypath 21:31:42 File mpmissions\OHTC_FPOC_Blank_Mission.Altis\ohtc\fn_obj.sqf, line 53 21:31:42 Error in expression < exception: " + _exception; }; _result> 21:31:42 Error position: <_result> 21:31:42 Error Undefined variable in expression: _result 21:31:42 File mpmissions\OHTC_FPOC_Blank_Mission.Altis\ohtc\fn_obj.sqf, line 68 Why the heck is _mypath undefined?! Share this post Link to post Share on other sites
dreadedentity 278 Posted December 2, 2014 Code blocks are a separate environment, so if you rely on variables, they absolutely must be passed to it. Try this: /*OHTC OBJECT FUNCTION * This function is designed to be a single global function to call the methods from a "model" in a more object oriented approach * * PARAMETERS: * 0 : array : "objectPath" the file path to find the desired function. Each entry should be a string of a folder, and the * final one should be the method name. The final must NOT include the .sqf file extension * 1 : array : "parameters" the array of parameters to pass to the desired class/script - these will be passed as is without manipulation. * NOTE that a null value will be replaced with a new and empty array * An example call of this function: * [["ohtc","unit","new"],[_unit]] call ohtc_fnc_obj; * The above would call the execVm of the file at: ohtc/unit/new.sqf */ //Define our variabless try { private ["_parameters","_objectPath","_result","_mypath"]; _objectPath = []; if(typeName (_this select 0) == "ARRAY") then { _objectPath = _this select 0; }; _parameters = []; if(typeName (_this select 1) == "ARRAY") then { _parameters = _this select 1; }; // _objectPath = [_this, 0, [], [[]]] call BIS_fnc_param; //this would be shorter than what you have // _parameters = [_this, 0, [], [[]]] call BIS_fnc_param; _mypath = ""; _result = ""; diag_log format ["obj: entered with: parameters: %1, and objectPath: %2",_parameters,_objectPath]; diag_log format ["obj: parameters type: %1, and objectPath type: %2",typeName _parameters,typeName _objectPath]; diag_log format ["obj: objectPath[0]: %1",_objectPath select 0]; //moved "try" to the top diag_log format ["obj: in try block: objectPath[0]: %1",_objectPath select 0]; //Validate that the user has passed us an object path, and that if it is there - its not null /* if((count _objectPath) == 0) then { //Throw the 101 error code diag_log "obj: objectPath is not an array or is empty"; throw "100"; }; */ diag_log format ["obj: _mypath type: %1",typeName _mypath]; _mypath = _objectPath select 0; diag_log "obj: initial path is: " + _mypath; for "_x" from 1 to (count _objectPath) do //should be from 0 to ((count _objectPath) - 1)...unless the first element is not important? { _mypath = _mypath + "\" + (_objectPath select _x); }; _mypath = _mypath + ".sqf"; diag_log "obj: path constructed as: " + _mypath; _result = _parameters execVM _mypath; } catch { diag_log "obj: WARNIng caught an exception: " + _exception; /* case "100": { _nul = [["ohtc","exception","new"],["OHTC_OBJECT_FUNCTION_100", "The objectPath must not be null, or empty"]] call ohtc_fnc_obj; }; default { //Wups - we caught an unhandled exception! _nul = [["ohtc","exception","new"],["OHTC_OBJECT_FUNCTION_UNKNOWN", "An unknown exception was caught"]] call ohtc_fnc_obj; }; */ }; _result Also, using BIS_fnc_param should be able to help condense your code, I have provided an example. Share this post Link to post Share on other sites
jshock 513 Posted December 2, 2014 _objectpath select 0 is returning nothing for whatever reason, I don't think it's scoping however. And at this current moment in time all of this is mushing together, as it's late, so I can't see what could be causing it. But as some helpful info, for the following: _objectPath = []; if(typeName (_this select 0) == "ARRAY") then { _objectPath = _this select 0; }; _parameters = []; if(typeName (_this select 1) == "ARRAY") then { _parameters = _this select 1; }; You could use BIS_fnc_param instead, it's a bit cleaner and you can define defaults (for debugging later down the road): _objectpath = [_this, 0, [],[[]]] call BIS_fnc_param; _parameters = [_this, 1, [], [[]]] call BIS_fnc_param; //example debug if (count _objectpath isEqualTo 0) exitWith { diag_log "_objectpath undefined"; }; EDIT: Ninja'd Share this post Link to post Share on other sites
killzone_kid 1333 Posted December 2, 2014 [color="#FF8040"][color="#191970"][b]for[/b][/color] [color="#7A7A7A"]"_x"[/color] [color="#191970"][b]from[/b][/color] [color="#FF0000"]1[/color] [color="#191970"][b]to[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#191970"][b]count[/b][/color] [color="#1874CD"]_objectPath[/color][color="#8B3E2F"][b])[/b][/color] [color="#191970"][b]do[/b][/color] [color="#8B3E2F"][b]{[/b][/color] [color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#7A7A7A"]"\"[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#1874CD"]_objectPath[/color] [color="#191970"][b]select[/b][/color] [color="#000000"]_x[/color][color="#8B3E2F"][b])[/b][/color][color="#8B3E2F"][b];[/b][/color] [color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color][/color] Made with KK's SQF to BBCode Converter should be [color="#FF8040"][color="#191970"][b]for[/b][/color] [color="#7A7A7A"]"_x"[/color] [color="#191970"][b]from[/b][/color] [color="#FF0000"]0[/color] [color="#191970"][b]to[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#191970"][b]count[/b][/color] [color="#1874CD"]_objectPath[/color] [color="#8B3E2F"][b]-[/b][/color] [color="#FF0000"]1[/color][color="#8B3E2F"][b])[/b][/color] [color="#191970"][b]do[/b][/color] [color="#8B3E2F"][b]{[/b][/color] [color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#7A7A7A"]"\"[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#8B3E2F"][b]([/b][/color][color="#1874CD"]_objectPath[/color] [color="#191970"][b]select[/b][/color] [color="#000000"]_x[/color][color="#8B3E2F"][b])[/b][/color][color="#8B3E2F"][b];[/b][/color] [color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color] [/color] Made with KK's SQF to BBCode Converter or even better [color="#FF8040"][color="#8B3E2F"][b]{[/b][/color] [color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]=[/b][/color] [color="#1874CD"]_mypath[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#7A7A7A"]"\"[/color] [color="#8B3E2F"][b]+[/b][/color] [color="#000000"]_x[/color][color="#8B3E2F"][b];[/b][/color] [color="#8B3E2F"][b]}[/b][/color] [color="#191970"][b]forEach[/b][/color] [color="#1874CD"]_objectPath[/color][color="#8B3E2F"][b];[/b][/color][/color] Made with KK's SQF to BBCode Converter Share this post Link to post Share on other sites
jshock 513 Posted December 2, 2014 { _mypath = _mypath + "\" + _x; } forEach _objectPath; Could that be improved further in terms of speed by using count? { _mypath = _mypath + "\" + _x; } count _objectPath; Share this post Link to post Share on other sites
SilentSpike 84 Posted December 2, 2014 Could that be improved further in terms of speed by using count? { _mypath = _mypath + "\" + _x; } count _objectPath; Honestly, I think this is a myth and I'm not sure how it started. I did some (admittedly primitive) testing using BIS_fnc_codePerformance and both commands showed almost identical speeds. Also, if you use count you need to return a boolean value at the end. Share this post Link to post Share on other sites
jshock 513 Posted December 2, 2014 (edited) Honestly, I think this is a myth and I'm not sure how it started. I did some (admittedly primitive) testing using BIS_fnc_codePerformance and both commands showed almost identical speeds.Also, if you use count you need to return a boolean value at the end. I assume BIKI wouldn't lie to us: https://community.bistudio.com/wiki/Code_Optimisation#forEach_vs_count Edited December 2, 2014 by JShock Share this post Link to post Share on other sites
SilentSpike 84 Posted December 2, 2014 Well it looks like KK first added that piece of info to the page, perhaps it's no longer the case or perhaps my results are simply false? The only way to tell for sure is to test it yourself. Share this post Link to post Share on other sites
killzone_kid 1333 Posted December 2, 2014 Well it looks like KK first added that piece of info to the page, perhaps it's no longer the case or perhaps my results are simply false?The only way to tell for sure is to test it yourself. Pretty sure you raised this question before and pretty sure I showed you that it is still valid. Share this post Link to post Share on other sites
jshock 513 Posted December 2, 2014 And on a small scale like this the difference in performance is negligible, but I was just clarifying a "faster" possibility, and I did forget to put in the boolean return, below is fixed: { _mypath = _mypath + "\" + _x; } count _objectPath > 0; Share this post Link to post Share on other sites
killzone_kid 1333 Posted December 2, 2014 Well it looks like KK first added that piece of info to the page, perhaps it's no longer the case or perhaps my results are simply false?The only way to tell for sure is to test it yourself. Here just did the test for you, can we finally lay this to rest please? [color="#FF8040"]arr [color="#8B3E2F"][b]=[/b][/color] [color="#8B3E2F"][b][[/b][/color][color="#8B3E2F"][b]][/b][/color][color="#8B3E2F"][b];[/b][/color] [color="#191970"][b]for[/b][/color] [color="#7A7A7A"]"_i"[/color] [color="#191970"][b]from[/b][/color] [color="#FF0000"]1[/color] [color="#191970"][b]to[/b][/color] [color="#FF0000"]1000[/color] [color="#191970"][b]do[/b][/color] [color="#8B3E2F"][b]{[/b][/color] arr [color="#191970"][b]pushBack[/b][/color] [color="#FF0000"]1[/color][color="#8B3E2F"][b];[/b][/color] [color="#8B3E2F"][b]}[/b][/color][color="#8B3E2F"][b];[/b][/color] [color="#8B3E2F"][b][[/b][/color][color="#7A7A7A"]'{} count arr'[/color][color="#8B3E2F"][b]][/b][/color] [color="#191970"][b]call[/b][/color] bis_fnc_codePerformance[color="#8B3E2F"][b];[/b][/color] [color="#006400"][i]//1.02ms[/i][/color] [color="#8B3E2F"][b][[/b][/color][color="#7A7A7A"]'{} forEach arr'[/color][color="#8B3E2F"][b]][/b][/color] [color="#191970"][b]call[/b][/color] bis_fnc_codePerformance[color="#8B3E2F"][b];[/b][/color] [color="#006400"][i]//1.77ms[/i][/color][/color] Made with KK's SQF to BBCode Converter Share this post Link to post Share on other sites
SilentSpike 84 Posted December 3, 2014 Pretty sure you raised this question before and pretty sure I showed you that it is still valid. I don't believe I've ever spoken to you about this? :confused: I appreciate the evidence though. Share this post Link to post Share on other sites