• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[JASS] Interface Problem

Status
Not open for further replies.
Level 6
Joined
Nov 3, 2008
Messages
117
Hey guys, it's me Inferior. I've just run into a weird problem regarding a struct exending an interface.

I've got something like this: an interface that is extended by a struct, which in turn is extended by another struct. In short: interface > struct > struct.

To show you what i mean i'll post you the code:

The interface with the first struct:
JASS:
interface SlotHandler
    method onHover takes player eventPlayer returns nothing defaults nothing
    method onClick takes player eventPlayer returns nothing defaults nothing
endinterface
    
struct CWSlot extends SlotHandler
endstruct

And here the struct that extends the CWSlot struct:
JASS:
struct Masteries extends CWSlot
    
    method onHover takes player eventPlayer returns nothing
        call BJDebugMsg("h")
    endmethod
        
    method onClick takes player eventPlayer returns nothing
        call BJDebugMsg("c")
    endmethod
        
endstruct

So my problem lies here:
JASS:
private static method TrackEvent takes nothing returns boolean
    local CWTrackable CWT = CWTrackable[GetTriggeringTrackable()]
    local CWSlot      CWS = CWT.parent
            
    if CWShown[CWS[GetTriggerPlayer()]].shown then
        if GetTriggerEventId()==EVENT_GAME_TRACKABLE_HIT then
            call CWS.onClick(GetTriggerPlayer())
        elseif GetTriggerEventId()==EVENT_GAME_TRACKABLE_TRACK then
            call CWS.onHover(GetTriggerPlayer())
        endif
    endif
    return false
endmethod

This method lies in the CWSlot struct. It fires whenever a player tracks or clicks a trackable (the trackable doesn't matter right now). So whenever a trackable is tracked or clicked it should run this method. When a trackable is clicked the onClick method from the Masteries-Struct shall be fired. Same goes for the onHover method when a trackable is tracked.

(Just for those who are crazy and want to run through the whole code here it goes)

The whole CustomSlot Library:
JASS:
library CustomSlot requires TableExtension

    globals
        private constant string CUSTOM_SLOT_TRACKABLE_MODEL = "CustomWindow\\Track75.mdx"
        private constant real   CUSTOM_SLOT_ICON_SIZE_64x64 = .82
        private constant real   CUSTOM_SLOT_ICON_Z_OFFSET   = 50.
    endglobals

    private struct CWTrackable
        private trackable track
        static method operator [] takes trackable track returns CWTrackable
            return HandleMacro[track][0]
        endmethod
        
        method operator parent takes nothing returns CWSlot
            return HandleMacro[this.track][this]
        endmethod
        
        static method create takes real x, real y, trigger t, CWSlot CWS returns CWTrackable
            local CWTrackable CWT = CWTrackable.allocate()
            set CWT.track         = CreateTrackable(CUSTOM_SLOT_TRACKABLE_MODEL,x,y,180.)
        
            set HandleMacro[CWT.track][CWT] = CWS
            set HandleMacro[CWT.track][ 0 ] = CWT
            call TriggerRegisterTrackableHitEvent(t,CWT.track)
            call TriggerRegisterTrackableTrackEvent(t,CWT.track)
            return CWT
        endmethod
    endstruct
    
    private struct CWDestructable
        private destructable dest
        static method create takes real x, real y, integer id returns CWDestructable
            local CWDestructable CWD = CWDestructable.allocate()
            set CWD.dest             = CreateDestructableZ(id,x,y,CUSTOM_SLOT_ICON_Z_OFFSET,180.,CUSTOM_SLOT_ICON_SIZE_64x64,0)
            
            call ShowDestructable(CWD.dest,false)
            return CWD
        endmethod
        
        method show takes boolean b returns nothing
            call ShowDestructable(this.dest,b)
        endmethod
        
        method onDestroy takes nothing returns nothing
            call RemoveDestructable(this.dest)
        endmethod
    endstruct
    
    private struct CWShown extends array  
        readonly boolean shown
        method show takes boolean b returns nothing
            set this.shown=b
        endmethod
    endstruct
    
    interface SlotHandler
        method onHover takes player eventPlayer returns nothing defaults nothing
        method onClick takes player eventPlayer returns nothing defaults nothing
    endinterface
    
    struct CWSlot extends SlotHandler
        private        real         xPos        = 0.
        private        real         yPos        = 0.     
        private static Table        Tracks
        private static Table        Dests
        private static trigger      Event       = CreateTrigger()
        
        private method operator [] takes player p returns integer
            return 15 * ( this - 1 ) + GetPlayerId(p)
        endmethod
        
        method addEventObject takes nothing returns nothing
            set CWSlot.Tracks[this] = CWTrackable.create(this.xPos,this.yPos,CWSlot.Event,this)
        endmethod
        
        method addVisualObject takes integer id, player p returns nothing
            set CWSlot.Dests[this] = CWDestructable.create(this.xPos,this.yPos,id)
            call CWShown[this].show(false)
        endmethod
        
        method removeVisualObject takes player p returns nothing
            local CWDestructable CWD
            if CWSlot.Dests.exists(this) then
                set CWD = CWSlot.Dests[this]
                call CWD.destroy()
                call CWShown[this].show(false)
            endif
        endmethod
        
        method showVisualObject takes player p, boolean b returns nothing
            local CWDestructable CWD
            if CWSlot.Dests.exists(this) then
                set CWD = CWSlot.Dests[this]
                call CWShown[this].show(b)
                if p==GetLocalPlayer() then
                    call CWD.show(b)
                endif
            endif
        endmethod
                    
        static method create takes CustomWindow CW, real xOffset, real yOffset returns CWSlot
            local CWSlot CWS
            if xOffset > CW.boardWidth or yOffset > CW.boardHeight then
                return 0
            endif
            set CWS         = CWSlot.allocate()
            set CWS.xPos    = CW.startX + xOffset
            set CWS.yPos    = CW.startY + yOffset
            return CWS
        endmethod
        
        private static method TrackEvent takes nothing returns boolean
            local CWTrackable CWT = CWTrackable[GetTriggeringTrackable()]
            local CWSlot      CWS = CWT.parent
            
            if CWShown[CWS[GetTriggerPlayer()]].shown then
                if GetTriggerEventId()==EVENT_GAME_TRACKABLE_HIT then
                    call CWS.onClick(GetTriggerPlayer())
                elseif GetTriggerEventId()==EVENT_GAME_TRACKABLE_TRACK then
                    call CWS.onHover(GetTriggerPlayer())
                endif
            endif
            return false
        endmethod
        
        private static method onInit takes nothing returns nothing
            set CWSlot.Tracks = Table.create()
            set CWSlot.Dests  = Table.create()
            
            call TriggerAddCondition( CWSlot.Event , Condition( function CWSlot.TrackEvent ) )
        endmethod
    endstruct
    
endlibrary

The Mastery Library:
JASS:
library MasterySetup initializer Init requires CustomWindow, CustomSlot

    globals
        private CustomWindow SkillMasteries = 0
    endglobals

    struct Masteries extends CWSlot
    
        method onHover takes player eventPlayer returns nothing
            call BJDebugMsg("h")
        endmethod
        
        method onClick takes player eventPlayer returns nothing
            call BJDebugMsg("c")
        endmethod
        
    endstruct
        
    private function Init takes nothing returns nothing
        local Masteries CM      = 0
        local rect   CR         = Rect(-1216.,332.,-1214.,616.8)
        set SkillMasteries      = CustomWindow.CreateNew(CR)
        
        set CM                  = CWSlot.create(SkillMasteries,0.,0.)
        call CM.addEventObject()
        call CM.addVisualObject('Mas1',Player(0))
        call SkillMasteries.addSlot(CM)
        
        set CM                  = CWSlot.create(SkillMasteries,0.,67.2)
        call CM.addEventObject()
        call CM.addVisualObject('Mas2',Player(0))
        call SkillMasteries.addSlot(CM)
        
        set CM                  = CWSlot.create(SkillMasteries,0.,134.4)
        call CM.addEventObject()
        call CM.addVisualObject('Mas3',Player(0))
        call SkillMasteries.addSlot(CM)
        
        set CM                  = CWSlot.create(SkillMasteries,0.,201.6)
        call CM.addEventObject()
        call CM.addVisualObject('Mas4',Player(0))
        call SkillMasteries.addSlot(CM)
        
        set CM                  = CWSlot.create(SkillMasteries,0.,268.8)
        call CM.addEventObject()
        call CM.addVisualObject('Mas5',Player(0))
        call SkillMasteries.addSlot(CM)
        
        call SkillMasteries.Show(Player(0),true)
    endfunction
    
endlibrary

So what this is supposed to do, is predominantly to print "c" when a trackable is clicked, and "h" when it is tracked. ( Just for testing )

Side Info: This is part of a fullscreen window system. I attached the map for the craziest of the crazy of you!!
 

Attachments

  • Custom Window.w3x
    120.1 KB · Views: 65
An interface with optional methods would be better served as stub methods from the parent stuct (instead of extending an interface) or delegates to a dummy struct; each of these ways you can have default behavior instead of "nothing".

Stub methods
JASS:
struct CWSlot extends SlotHandler
    stub method onHover takes player eventPlayer returns nothing
    endmethod
    stub method onClick takes player eventPlayer returns nothing
    endmethod
endstruct

Delegates

JASS:
private struct dummy extends array
    method onHover takes player eventPlayer returns nothing
    endmethod
    method onClick takes player eventPlayer returns nothing
    endmethod
endstruct
    
struct CWSlot
    private delegate dummy d_d
endstruct
 
Level 6
Joined
Nov 3, 2008
Messages
117
I don't think that delegates work here. I need the following:
JASS:
interface handler
   method onHover takes player p returns nothing defaults nothing
   method onClick takes player p returns nothing defaults nothing
endinterface

struct CWSlot extends handler
   
   static method trackableEvent takes nothing returns nothing
        local thistype instance = // How i get the Slot instance doesn't care, but just imagine we got the Instance
        local player    p          = // How i get the Event player doesn't care, but just imagine we got the event player
        if GetEventId()==EVENT_GAME_TRACKABLE_HIT then
             call instance.onClick(p)
        elseif GetEventId()==EVENT_GAME_TRACKABLE_TRACK then
             call instance.onHover(p)
        endif
    endmethod

endstruct

struct Masteries extends CWSlot

     method onHover takes player p returns nothing
     endmethod

     method onClick takes player p returns nothing
     endmethod

endstruct

now whenever a trackable is clicked or hovered. It shall fire the onHover/onClick method from the Masteries struct. How does this work with delegates.

About stub methods. That would work too, but those 2 methods have to be declared. Otherwise this whole code wouldn't have any sense.
 
Delegates work just fine. There are already trackable libraries, so I don't know if you are trying to do something that someone has already done.

JASS:
private struct handler extends array
   method onHover takes player p returns nothing
   endmethod
   method onClick takes player p returns nothing
   endmethod
endstruct

struct CWSlot
   
   private static delegate handler h_d = 0
   
   static method trackableEvent takes nothing returns nothing
        local thistype instance = //Why do you need instances?
        local player p = //What do you want to do with the player?
        if GetTriggerEventId()==EVENT_GAME_TRACKABLE_HIT then
             call instance.onClick(p)
        elseif GetTriggerEventId()==EVENT_GAME_TRACKABLE_TRACK then
             call instance.onHover(p)
        endif
    endmethod

endstruct

struct Masteries extends CWSlot

     method onHover takes player p returns nothing
     endmethod

     method onClick takes player p returns nothing
     endmethod

endstruct
 
Status
Not open for further replies.
Top