createHashMapObject: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
m (Some wiki formatting)
No edit summary
Line 132: Line 132:


|seealso= [[call]] [[createHashMap]]
|seealso= [[call]] [[createHashMap]]
}}
{{Note
|user= Hypoxic125
|timestamp= 20240827054058
|text= You can perform '''Constructor Chaining''' by calling the base classes constructor, then followed with your modified constructor to be executed after. Be sure to use the same parameters when chaining.
<sqf>
private _baseClass = [
["#create", {
systemChat "Doing base class things";
}]
];
private _derivedClass = [
["#base", _baseClass],
["#create", {
// Execute base class constructor
_self get "#base" call ["#create", _this];
// This class constructor to be performed after
systemChat "Doing derived class things";
}]
];
createHashMapObject [_derivedClass]; // "Doing base class things"
// "Doing derived class things"
</sqf>
}}
}}

Revision as of 07:40, 27 August 2024

Hover & click on the images for description

Description

Description:
Create a HashMap with an Object-Oriented Programming behaviour.
Inside a object, Methods (if they are called correctly, either by engine or via call - Syntax 3) will have the objects instance inside the _self variable.
The Destructor ("#delete" method) will be executed when the last reference to the objects variable gets deleted. (Except when the mission is ended and all variables are deleted at once)

Inheritance: HashMap objects support a simple form of Inheritance.
It behaves similar to the merge command with overwriteExisting enabled. Sub-class methods and properties with same name, overwrite their Base-class values.
Constructor/Destructor/Clone methods will be merged together and executed in sequence.
Flags entry will use overwrite behaviour.
Groups:
HashMap

Syntax

Syntax:
createHashMapObject [classDefinition, constructorArguments]
Parameters:
classDefinition: HashMap or Array of Arrays, format [name, value]: name can be anything like any other HashMap, but it must be a String for it to be used like an OOP object method (see call - Syntax 3).
Some special values, starting with #, are reserved and expect a specific value type (they are all optional):
  • "#create": Code - this is the hashmap object's constructor
  • "#clone": Code - this is code happening when cloning is done on this hashmap object
  • "#delete": Code - this is the hashmap object's destructor. It will always be executed inside missionNamespace.
  • "#str": Code - code that is used to evaluate what is displayed when the str function is called on the object - must return String
  • "#flags": Array of Strings - case-insensitive flags regarding this hashmap object
    • "noCopy": forbids copying, +_hashMapObject will throw an error
    • "sealed": prevents from adding and removing any keys - key values can still be edited
    • "unscheduled": all methods (including #clone and #create) will be executed in unscheduled environment
  • "#base": Array or HashMap - declaration of base class for inheritance
  • "#type": Any - can be used to give a object a "type name", on inheritance types will be merged into an Array
Note that all entries beginning with # are reserved, the engine might use these internally without their use being documented.
constructorArguments: Anything - (Optional, default Nothing) passed as _this argument to the "#create" method.
Return Value:
HashMap

Examples

Example 1:
private _declaration = [ ["#flags", ["sealed"]], ["#create", { hint "Hello!" }], ["#clone", { hint "We were copied!" }], ["#delete", { hint "Goodbye" }], ["#str", { "My HashMap Object" }], ["Method", { hint "Method has been called" }] ]; private _hashMapObject = createHashMapObject [_declaration]; // hints "Hello!" _hashMapObject call ["Method"]; // hints "Method has been called" hint str _hashMapObject; // hints "My HashMap Object" private _shallowCopy = _hashMapObject; // no hint private _deepCopy = +_hashMapObject; // hints "We were copied!" // at the end of the scope, _hashMapObject is deleted and hints "Goodbye"
Example 2:
Inheritance constructor/destructor/copy orderings:
private _animalDeclaration = [ ["#type", "IAnimal"], ["#create", { systemChat "Animal Init" }], ["#clone", { systemChat "Animal Copied" }], ["#delete", { systemChat "Animal Bye" }] ]; private _pigDeclaration = [ ["#base", _animalDeclaration], ["#type", "Pig"], ["#create", { systemChat "Pig Init" }], ["#clone", { systemChat "Pig Copied" }], ["#delete", { systemChat "Pig Bye" }] ]; private _smolPigDeclaration = [ ["#base", _pigDeclaration], ["#type", "SmolPig"], ["#create", { systemChat "SmolPig Init" }], ["#clone", { systemChat "Smol Copied" }], ["#delete", { systemChat "Smol Bye" }] ]; private _smolPigInstance = createHashMapObject [_smolPigDeclaration]; // prints "Animal Init", "Pig Init", "SmolPig Init" private _copy = +_smolPigInstance; // prints "Animal Copied", "Pig Copied", "SmolPig Copied" _copy = nil; // prints "SmolPig Bye", "Pig Bye", "Animal Bye"
Example 3:
Inheritance type checking:
private _animalDeclaration = [ ["#type", "IAnimal"], ["FurType", { "None" }] // default implementation ]; private _pigDeclaration = [ ["#base", _animalDeclaration], ["#type", "Pig"], ["FurType", { "Bristles" }] // override the base class method ]; private _catDeclaration = [ ["#base", _animalDeclaration], ["#type", "Cat"], ["FurType", { "Hair" }] // override the base class method ]; private _instance = createHashMapObject [selectRandom [_pigDeclaration, _catDeclaration]]; if ("IAnimal" in (_instance get "#type")) then // check if a object instance is or inherits from a specific type { _instance call ["FurType"]; // now that we know it implements IAnimal, we know that "FurType" method will be present };
Example 4:
Destructor:
private _temporaryVehicle = [ ["#create", { params ["_vehicleType", "_vehiclePos", "_lifetimeSeconds"]; // handle constructor arguments private _newVehicle = _vehicleType createVehicle _vehiclePos; _self set ["MyVehicle", _newVehicle]; // Store the vehicle inside the object for later // because _self is passed as parameter, it will be referenced by the spawned script until it ends. [_lifetimeSeconds, _self] spawn { params ["_lifetimeSeconds", "_self"]; sleep _lifetimeSeconds; }; }], ["#delete", { deleteVehicle (_self get "MyVehicle"); // delete the vehicle when we go away }], ["MyVehicle", objNull] // placeholder, this is not needed ]; // create a temporary RoadCone, at player position, that will delete itself after 5 seconds. createHashMapObject [_temporaryVehicle, ["RoadCone_F", getPos player, 5]];

Additional Information

See also:
call createHashMap

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
Hypoxic125 - c
Posted on Aug 27, 2024 - 05:40 (UTC)
You can perform Constructor Chaining by calling the base classes constructor, then followed with your modified constructor to be executed after. Be sure to use the same parameters when chaining.
private _baseClass = [ ["#create", { systemChat "Doing base class things"; }] ]; private _derivedClass = [ ["#base", _baseClass], ["#create", { // Execute base class constructor _self get "#base" call ["#create", _this]; // This class constructor to be performed after systemChat "Doing derived class things"; }] ]; createHashMapObject [_derivedClass]; // "Doing base class things" // "Doing derived class things"