Jump to content

Need information/help on my script


HappySlapp

Recommended Posts

I need some help on what I think may be a potential memory leak waiting to happen, the problem is I don't know if it would or wouldn't actually cause a memory leak, here's the script that I'm concerned about:

Scriptname zYAS_Manager_Skills Extends Quest


Float 	Property TimerEventInterval 	= 1.0	Auto
Int		Property TimerEventID		 	= 1		Auto


{MCM EDITABLE VARIABLES}
Float 	Property fSkillAttributeMult 	= 2.0 	Auto
Float 	Property fSkillsTagMult			= 15.0 	Auto


ActorValue[] Property Attributes Auto
Float[] 	 Property AttributeValues Auto


Struct SkillStruct
	String		_id
	ActorValue 	_skill
	ActorValue 	_attribute
	Float		_skillBase
	Float		_attributeBase
	Float		_attributeValue
	ActorValue	_skillEffect
EndStruct
	
	
SkillStruct[] Property SkillsArray Auto


Function RegisterNewSkill(String asID, ActorValue avSkill, ActorValue avAttribute)
	SkillStruct _newSkill = new SkillStruct
	
	_newSkill._id	 		= asID
	_newSkill._skill 		= avSkill
	_newSkill._attribute 	= avAttribute

	SkillsArray.Add(_newSkill)
EndFunction


SkillStruct Function GetSkillStruct(String asID)
	Int _index = SkillsArray.FindStruct("_id", asID, 0)
	Return SkillsArray[_index]
EndFunction


SkillStruct[] Function GetSkillStructsByAttribute(ActorValue avAttribute)
	Int _index = 0
	SkillStruct[] _returnStruct = new SkillStruct[0]
	While (_index < SkillsArray.Length)
		If (SkillsArray[_index]._attribute == avAttribute)
			_returnStruct.Add(SkillsArray[_index])
		EndIf
		_index += 1
	EndWhile
	Return _returnStruct
EndFunction


Function ReevaluateSkill(String asID)
	Int _index = SkillsArray.FindStruct("_id", asID, 0)
	SkillStruct _thisSkill = SkillsArray[_index]
	Float _difference = 0
	If (_thisSkill._attributeBase != Game.GetPlayer().GetBaseValue(_thisSkill._attribute) * fSkillAttributeMult)
		_difference = -(_thisSkill._attributeBase - Game.GetPlayer().GetBaseValue(_thisSkill._attribute) * fSkillAttributeMult)
		_thisSkill._attributeBase = Game.GetPlayer().GetBaseValue(_thisSkill._attribute) * fSkillAttributeMult
	EndIf
	If (_thisSkill._skillBase != Game.GetPlayer().GetBaseValue(_thisSkill._skill) + _difference)
		_thisSkill._skillBase = Game.GetPlayer().GetBaseValue(_thisSkill._skill) + _difference
	EndIf
	If (_difference != 0)
		Debug.Trace(_difference)
		_difference = 0
	EndIf
	Game.GetPlayer().SetValue(_thisSkill._skill, _thisSkill._skillBase)
	
	If (_thisSkill._attributeValue != (Game.GetPlayer().GetBaseValue(_thisSkill._attribute) - Game.GetPlayer().GetValue(_thisSkill._attribute)) * fSkillAttributeMult)
		_difference = (_thisSkill._attributeValue - (Game.GetPlayer().GetBaseValue(_thisSkill._attribute) - Game.GetPlayer().GetValue(_thisSkill._attribute)) * fSkillAttributeMult)
		_thisSkill._attributeValue = (Game.GetPlayer().GetBaseValue(_thisSkill._attribute) - Game.GetPlayer().GetValue(_thisSkill._attribute)) * fSkillAttributeMult
	EndIf
	
	If (_difference != 0)
		Debug.Trace(_difference)
		Game.GetPlayer().ModValue(_thisSkill._skill, _difference)
	EndIf
	
	If (Game.GetPlayer().GetValue(_thisSkill._skillEffect) != (Game.GetPlayer().GetValue(_thisSkill._skill)))
		Game.GetPlayer().SetValue(_thisSkill._skillEffect, Game.GetPlayer().GetValue(_thisSkill._skill) * 0.01)
	EndIf
EndFunction

Function ReevaluateSkillsByAttribute(ActorValue avAttribute)
	SkillStruct[] _theseStructs = GetSkillStructsByAttribute(avAttribute)
	Int _index = 0
	While (_index < _theseStructs.Length)
		ReevaluateSkill(_theseStructs[_index]._id)
		_index += 1
	EndWhile
EndFunction


Function CheckAttributesForChange()
	Int _index = 0
	While (_index < Attributes.Length)
		If (AttributeValues[_index] != Game.GetPlayer().GetValue(Attributes[_index]))
			ReevaluateSkillsByAttribute(Attributes[_index])
		EndIf
		_index += 1
	EndWhile
EndFunction


Event OnQuestInit()
	StartTimer(TimerEventInterval, TimerEventID)
EndEvent


Event OnQuestShutdown()
	CancelTimer(TimerEventID)
EndEvent


Event OnTimer(Int iTimerID)
	If (iTimerID == TimerEventID)
		CheckAttributesForChange()
	EndIf
	StartTimer(TimerEventInterval, TimerEventID)
EndEvent

I'm more specifically concerned about one section in particular:

SkillStruct[] Function GetSkillStructsByAttribute(ActorValue avAttribute)
	Int _index = 0
	SkillStruct[] _returnStruct = new SkillStruct[0]
	While (_index < SkillsArray.Length)
		If (SkillsArray[_index]._attribute == avAttribute)
			_returnStruct.Add(SkillsArray[_index])
		EndIf
		_index += 1
	EndWhile
	Return _returnStruct
EndFunction

And even more specifically, this line in particular:

SkillStruct[] _returnStruct = new SkillStruct[0]

I'm afraid it's actually legitimately creating a new copy of "SkillStruct" every single time that line is ran, would this be the case, or would the function automatically discard it from memory in some way?

 

Any help would be GREATLY appreciated.

Edited by HappySlapp
Link to comment
Share on other sites

I don't know how the engine manages it, but it would be weird if the variables of the function stay in memory after its execution. At any case, if you want to make sure that this variable is recycled you could declare it out of the function.

Link to comment
Share on other sites

According to this page from the creation kit wiki, an array is garbage collected, once it's no longer referenced. You can read about it in the "Assigning/Passing Arrays" section. The issue is that you're calling this function each second multiple times, I don't know if the garbage collector is fast enough to keep up. I have a bit of optimisation notes. TimerEventInterval and TimerEventID shouldn't be properties unless you intend to access them outside this script. If you're going to be accessing the player reference a lot, consider storing it as a script property instead.

Edited by NoCashNoExp
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...