Thread Tools Display Modes
08-19-18, 04:25 PM   #1
Nikita S. Doroshenko
A Cyclonian
 
Nikita S. Doroshenko's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2015
Posts: 45
How can I hooksecurefunc with colon like this: "MainMenuBarMixin:OnShow"

I spend so much time trying to figure it out by myself, but unfortunately no luck.

This is blizard code mainMenuBar.lua:
Code:
local MAINMENU_SLIDETIME = 0.30;
local MAINMENU_GONEYPOS = 130;	--Distance off screen for MainMenuBar to be completely hidden
local MAINMENU_XPOS = 0;
MAIN_MENU_BAR_MARGIN = 75;		-- number of art pixels on one side, used by UIParent_ManageFramePositions. It's not the art's full size, don't care about the gryphon's tail.

MainMenuBarMixin = { };
function MainMenuBarMixin:OnStatusBarsUpdated()
	self:SetPositionForStatusBars(); 
end

function MainMenuBarMixin:OnLoad()
	self:RegisterEvent("ACTIONBAR_PAGE_CHANGED");
	self:RegisterEvent("CURRENCY_DISPLAY_UPDATE");
	self:RegisterEvent("UNIT_LEVEL");
	self:RegisterEvent("PLAYER_ENTERING_WORLD");
	self:RegisterEvent("TRIAL_STATUS_UPDATE");
	self:RegisterEvent("DISPLAY_SIZE_CHANGED");
	self:RegisterEvent("UI_SCALE_CHANGED");

	CreateFrame("FRAME", "StatusTrackingBarManager", self, "StatusTrackingBarManagerTemplate");
	
	MAX_PLAYER_LEVEL = MAX_PLAYER_LEVEL_TABLE[GetExpansionLevel()];

	self.state = "player";
	MainMenuBarArtFrame.PageNumber:SetText(GetActionBarPage());
	MicroButtonAndBagsBar:SetFrameLevel(self:GetFrameLevel()+2);
end

function MainMenuBarMixin:OnShow()
	UpdateMicroButtonsParent(MainMenuBarArtFrame);
	MoveMicroButtons("BOTTOMLEFT", MicroButtonAndBagsBar, "BOTTOMLEFT", 6, 3, false);
end

function MainMenuBarMixin:SetYOffset(yOffset)
	self.yOffset = yOffset;
end

function MainMenuBarMixin:GetYOffset()
	return self.yOffset;
end

function MainMenuBarMixin:SetPositionForStatusBars()
	MainMenuBar:ClearAllPoints(); 
	MainMenuBarArtFrame.LeftEndCap:ClearAllPoints(); 
	MainMenuBarArtFrame.RightEndCap:ClearAllPoints(); 
	if ( StatusTrackingBarManager:GetNumberVisibleBars() == 2 ) then 
		self:SetYOffset(17);
		MainMenuBarArtFrame.LeftEndCap:SetPoint("BOTTOMLEFT", MainMenuBar, -98, -17); 
		MainMenuBarArtFrame.RightEndCap:SetPoint("BOTTOMRIGHT", MainMenuBar, 98, -17); 
	elseif ( StatusTrackingBarManager:GetNumberVisibleBars() == 1 ) then
		self:SetYOffset(14);
		MainMenuBarArtFrame.LeftEndCap:SetPoint("BOTTOMLEFT", MainMenuBar, -98, -14); 
		MainMenuBarArtFrame.RightEndCap:SetPoint("BOTTOMRIGHT", MainMenuBar, 98, -14); 
	else 
		self:SetYOffset(0);
		MainMenuBarArtFrame.LeftEndCap:SetPoint("BOTTOMLEFT", MainMenuBar, -98, 0); 
		MainMenuBarArtFrame.RightEndCap:SetPoint("BOTTOMRIGHT", MainMenuBar, 98, 0); 
	end
	if ( IsPlayerInWorld() ) then
		UIParent_ManageFramePositions();
	end
end
I would like to add my code after function MainMenuBarMixin:SetPositionForStatusBars(), so i thought I could just use something like this:
Code:
local function Test()
	print("test")
end
hooksecurefunc(MainMenuBarMixin, "SetPositionForStatusBars", Test);
I tried lots of methods and google alot, the last this I made, came here. Will apreciate any help.
  Reply With Quote
08-19-18, 04:36 PM   #2
Kanegasi
A Molten Giant
 
Kanegasi's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2007
Posts: 666
Anything with "mixin" in it's name isn't actually used directly, so if you were to hook that function, the hook won't get called. You'll need to hook the actual method on the frame that uses the mixin.

Mixins are a template of methods that frames then inherit. Blizzard gives frames a mixin template in two ways: calling frame = CreateFromMixins(mixin) or in xml using the mixin="" attribute. In this case, MainMenuBar gets its methods from MainMenuBar.xml:

XML Code:
  1. <Frame name="MainMenuBar" enableMouse="true" parent="UIParent" mixin="MainMenuBarMixin">

You should be able to do this:

Lua Code:
  1. hooksecurefunc(MainMenuBar, "SetPositionForStatusBars", Test)
  Reply With Quote
08-19-18, 04:53 PM   #3
Nikita S. Doroshenko
A Cyclonian
 
Nikita S. Doroshenko's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2015
Posts: 45
Originally Posted by Kanegasi View Post
Anything with "mixin" in it's name isn't actually used directly, so if you were to hook that function, the hook won't get called. You'll need to hook the actual method on the frame that uses the mixin.

Mixins are a template of methods that frames then inherit. Blizzard gives frames a mixin template in two ways: calling frame = CreateFromMixins(mixin) or in xml using the mixin="" attribute. In this case, MainMenuBar gets its methods from MainMenuBar.xml:

XML Code:
  1. <Frame name="MainMenuBar" enableMouse="true" parent="UIParent" mixin="MainMenuBarMixin">

You should be able to do this:

Lua Code:
  1. hooksecurefunc(MainMenuBar, "SetPositionForStatusBars", Test)

Kanegasi you saved my day! Thank you very much for explanation.

I hope this thread will be helpful for all beginners or coming back modders.
Very appreciate your help.

I think it's new thing from Legion maybe, don't remember mixins in Pandaria-Warlords of Draenor.
  Reply With Quote
08-19-18, 07:39 PM   #4
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
Originally Posted by Kanegasi View Post
Anything with "mixin" in it's name isn't actually used directly, so if you were to hook that function, the hook won't get called. You'll need to hook the actual method on the frame that uses the mixin.

Mixins are a template of methods that frames then inherit. Blizzard gives frames a mixin template in two ways: calling frame = CreateFromMixins(mixin) or in xml using the mixin="" attribute. In this case, MainMenuBar gets its methods from MainMenuBar.xml:

XML Code:
  1. <Frame name="MainMenuBar" enableMouse="true" parent="UIParent" mixin="MainMenuBarMixin">

You should be able to do this:

Lua Code:
  1. hooksecurefunc(MainMenuBar, "SetPositionForStatusBars", Test)

It's interesting to me that you would say that, because this works for me:

lua Code:
  1. hooksecurefunc(ExpBarMixin, "Update", function(self)
  2.     TextStatusBar_UpdateTextString(self)
  3.     self:ShowText(self)
  4.     self:UpdateCurrentText()
  5. end)

Maybe it depends on the mixin? idk
  Reply With Quote
08-19-18, 10:35 PM   #5
Gethe
RealUI Developer
 
Gethe's Avatar
Premium Member
Featured
Join Date: Sep 2008
Posts: 942
It depends on 1) when the mixin is created 2) when the function is hooked and 3) when the frame has the mixin applied.

In Ammako's case, ExpBarMixin is created and is applied to a template in the frame xml, before any addon gets loaded. The template however is not used for instantiating a frame until PLAYER_ENTERING_WOLRD fires, which is typically after most addons are loaded. As such, any hooks applied to the mixin before PLAYER_ENTERING_WOLRD fires will propagate the the new frame.

In Nikita's case, MainMenuBarMixin is created and immediately used in the creation of MainMenuBar. This means there is no allowance for any hooks to be made and applied via the mixin.
__________________
Knowledge = Power; Be OP


Last edited by Gethe : 08-19-18 at 10:39 PM.
  Reply With Quote
08-21-18, 06:17 PM   #6
Nikita S. Doroshenko
A Cyclonian
 
Nikita S. Doroshenko's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2015
Posts: 45
Originally Posted by Gethe View Post
It depends on 1) when the mixin is created 2) when the function is hooked and 3) when the frame has the mixin applied.

In Ammako's case, ExpBarMixin is created and is applied to a template in the frame xml, before any addon gets loaded. The template however is not used for instantiating a frame until PLAYER_ENTERING_WOLRD fires, which is typically after most addons are loaded. As such, any hooks applied to the mixin before PLAYER_ENTERING_WOLRD fires will propagate the the new frame.

In Nikita's case, MainMenuBarMixin is created and immediately used in the creation of MainMenuBar. This means there is no allowance for any hooks to be made and applied via the mixin.
The thing that is confusing me, is hoocsecurefunc sometimes toggle lua errors like "funxtionX is not a function"
For example, I tried to hook some functions like function PlayerTalentFrame_UpdateSpecFrame(self, spec) from Blizzard_TalentUI.lua:

Lua Code:
  1. function PlayerTalentFrame_UpdateSpecFrame(self, spec)
  2.     local playerTalentSpec = GetSpecialization(nil, self.isPet, specs[selectedSpec].talentGroup);
  3.     local shownSpec = spec or playerTalentSpec or 1;
  4.     local numSpecs = GetNumSpecializations(nil, self.isPet);
  5.     local petNotActive = self.isPet and not IsPetActive();
  6.     local sex = self.isPet and UnitSex("pet") or UnitSex("player");
  7.     -- and so on... very large function
  8. end
So I used this code:
Lua Code:
  1. local function Test(self, spec)
  2.     print("test")
  3.     print(self)
  4.     print(spec)
  5. end
  6. hooksecurefunc('PlayerTalentFrame_UpdateSpecFrame', Test)
And got this: Error. hooksecurefunc(): PlayerTalentFrame_UpdateSpecFrame is not a function

At the same time, for example:
Lua Code:
  1. local function Test(self, spec)
  2.     print("test")
  3.     print(self)
  4.     print(spec)
  5. end
  6. hooksecurefunc('SpellBookFrame_UpdateSkillLineTabs', Test)
Works perfectly.

Can't understand why this happens, and will appreciate any advises how to hook functions with "funxtionX is not a function" error.
  Reply With Quote
08-21-18, 06:24 PM   #7
Ammako
A Frostmaul Preserver
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 256
Originally Posted by Nikita S. Doroshenko View Post
The thing that is confusing me, is hoocsecurefunc sometimes toggle lua errors like "funxtionX is not a function"
For example, I tried to hook some functions like function PlayerTalentFrame_UpdateSpecFrame(self, spec) from Blizzard_TalentUI.lua:

-snip-
So I used this code:
-snip
And got this: Error. hooksecurefunc(): PlayerTalentFrame_UpdateSpecFrame is not a function

At the same time, for example:
-snip
Works perfectly.

Can't understand why this happens, and will appreciate any advises how to hook functions with "funxtionX is not a function" error.
Blizzard_TalentUI is LoadOnDemand, you need to wait for ADDON_LOADED and check for Blizzard_TalentUI, or set your addon to LoadOnDemand and LoadWith Blizzard_TalentUI, depending on your use case.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » How can I hooksecurefunc with colon like this: "MainMenuBarMixin:OnShow"

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off