最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

xml - self in OnLoad function nil - Stack Overflow

programmeradmin0浏览0评论

I'm trying to create a simple addon for vanilla wow with Lua, the very first task - is to initialise some UI and to call a function for initial configuration.

MyAddonName.xml

<Ui xmlns="/"
    xmlns:xsi=";
    xsi:schemaLocation="/ .xsd">

   <Frame name="MyAddonName" parent="UIParent">
        <Size x="384" y="512" />

        <Anchors>
            <Anchor point="CENTER" relativePoint="CENTER"
                relativeTo="UIParent" />
        </Anchors>

        <Layers>
            <Layer level="BACKGROUND">
                <Texture name="$parent_Portrait" parentKey="portrait"
                    file="Interface\Icons\INV_Misc_EngGizmos_30">
                    <Size x="60" y="60" />
                    <Anchors>
                        <Anchor point="TOPLEFT">
                            <Offset x="7" y="-6" />
                        </Anchor>
                    </Anchors>
                </Texture>
            </Layer>
        </Layers> 

        <Scripts>
           <OnLoad function="MyAddonName_OnLoad" />
        </Scripts>

  </Frame>
</Ui>

MyAddonName.lua

function Print(msg, r, g, b)
    DEFAULT_CHAT_FRAME:AddMessage("|c0033ffccMyAddonName|r "..msg.."", r, g, b)
end

function MyAddonName_OnLoad(self)
    Print("loaded"..tostring(self), 0, 1, 0) // <- self exists

    self.items = {}

end

function MyAddonName_TestFunct()
    Print(MyAddonName.items) or Print(self.items) // <- not exists, attempt to index field 'items' (a nil value)
    
end

MyAddonName_TestFunct will be called later, for test purpose I just called this from

/run MyAddonName_TestFunct()
/run MyAddonName_TestFunct()

I assumed that MyAddonName_OnLoad with self will be called after addon is loaded from xml part where self is a table that represent instance of addon, and later on some event I can call MyAddonName_TestFunct with some initial value stored in a table accessible via self.

I checked other addons (for example BetterCharacterStats) and there is a similar code, for example

BetterCharacterStats.lua

function BCS:OnLoad() // `BCS:` means that self passed implicitly

I also noticed that table BSC created explicitly, but thus I have self during check - this is not needed for me.

----

Here is a more complete example that I tested (with more code) - I'm trying to follow some tutorial, result now a bit different

And this is result of prints

Image of output

Can anyone suggest where I'm wrong?

I'm trying to create a simple addon for vanilla wow with Lua, the very first task - is to initialise some UI and to call a function for initial configuration.

MyAddonName.xml

<Ui xmlns="http://www.blizzard/wow/ui/"
    xmlns:xsi="http://www.w3./2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.blizzard/wow/ui/ https://raw.githubusercontent/Gethe/wow-ui-source/live/Interface/AddOns/Blizzard_SharedXML/UI.xsd">

   <Frame name="MyAddonName" parent="UIParent">
        <Size x="384" y="512" />

        <Anchors>
            <Anchor point="CENTER" relativePoint="CENTER"
                relativeTo="UIParent" />
        </Anchors>

        <Layers>
            <Layer level="BACKGROUND">
                <Texture name="$parent_Portrait" parentKey="portrait"
                    file="Interface\Icons\INV_Misc_EngGizmos_30">
                    <Size x="60" y="60" />
                    <Anchors>
                        <Anchor point="TOPLEFT">
                            <Offset x="7" y="-6" />
                        </Anchor>
                    </Anchors>
                </Texture>
            </Layer>
        </Layers> 

        <Scripts>
           <OnLoad function="MyAddonName_OnLoad" />
        </Scripts>

  </Frame>
</Ui>

MyAddonName.lua

function Print(msg, r, g, b)
    DEFAULT_CHAT_FRAME:AddMessage("|c0033ffccMyAddonName|r "..msg.."", r, g, b)
end

function MyAddonName_OnLoad(self)
    Print("loaded"..tostring(self), 0, 1, 0) // <- self exists

    self.items = {}

end

function MyAddonName_TestFunct()
    Print(MyAddonName.items) or Print(self.items) // <- not exists, attempt to index field 'items' (a nil value)
    
end

MyAddonName_TestFunct will be called later, for test purpose I just called this from

/run MyAddonName_TestFunct()
/run MyAddonName_TestFunct()

I assumed that MyAddonName_OnLoad with self will be called after addon is loaded from xml part where self is a table that represent instance of addon, and later on some event I can call MyAddonName_TestFunct with some initial value stored in a table accessible via self.

I checked other addons (for example BetterCharacterStats) and there is a similar code, for example

BetterCharacterStats.lua

function BCS:OnLoad() // `BCS:` means that self passed implicitly

I also noticed that table BSC created explicitly, but thus I have self during check - this is not needed for me.

----

Here is a more complete example that I tested (with more code) - I'm trying to follow some tutorial, result now a bit different

And this is result of prints

Image of output

Can anyone suggest where I'm wrong?

Share Improve this question edited Nov 20, 2024 at 16:18 Ali Khan 1781 silver badge6 bronze badges asked Nov 20, 2024 at 8:38 khbkhb 16 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

The issue you're encountering with self being nil during the OnLoad event is a common problem in World of Warcraft UI scripting, especially for custom frames. This typically happens because when the OnLoad script is fired, the reference to self is not automatically passed in the way you'd expect it to be, especially when it's a custom frame or button.

Here's why:

In WoW, the self parameter is typically passed in automatically by the system when you use the OnLoad event in combination with a frame or button. However, if the OnLoad event is handled within XML, the frame might not have been fully initialized when the event fires, or the XML setup might not be correctly linked to the Lua function.

The Root Cause

The OnLoad event is generally triggered when the frame has been loaded, but in some cases (depending on the context), self might not reference the frame as expected.

Reference the Frame Directly in Lua

If you don’t want to change the XML, you can modify the Lua function to get a reference to the frame directly, even if self is nil. You can achieve this by referencing the frame by name within the MyAddonName_OnLoad function.

fix:

local frame = self or MyAddonName  -- Fallback to MyAddonName if self is nil
发布评论

评论列表(0)

  1. 暂无评论