HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Structs - Parent Problem

09-13-2009, 01:44 PM#1
Anachron
Hi, I have made this library:
Collapse JASS:
// #==============================================================
// | Window System
// | by dhk_undead_lord
// #==============================================================
library WindowSystem

    // The struct with the Data of a trackable.
    // You can store any Data you need later here
    struct TrackData
        // *&* MEMBERS *&*
        string id
        player thePlayer

        // *&* METHODS *&*
        public static method create takes string theId, player thePlayer returns TrackData
            local TrackData td = TrackData.allocate()
            set td.id = theId
            set td.thePlayer = thePlayer
            return td
        endmethod
    endstruct

    // a struct which contains the handle, the player,
    // and the Trackdata.
    struct Trackable
        // *&* MEMBERS *&*
        public trackable trackHandle
        public player playerId
        public TrackData data

        // *&* METHODS *&*
        public static method create takes trackable theTrack, TrackData theData returns Trackable
            local Trackable ta = Trackable.allocate()
            set ta.trackHandle = theTrack
            set ta.playerId = theData.thePlayer
            set ta.data = theData
            return ta
        endmethod

    endstruct

    // A struct which will contain all of your Trackable-Objects,
    // with all data. This will seek for the owner and Data later.
    struct TrackPackage
        // *&* MEMBERS *&*
        public Trackable array tracks[8191]
        public integer index = 0

        static TrackPackage allTracks
        static boolean initPack = false

        // *&* METHODS *&*
        private static method addTrackable takes Trackable theTrack returns nothing
            set TrackPackage.allTracks.tracks[TrackPackage.allTracks.index] = theTrack
            set TrackPackage.allTracks.index = TrackPackage.allTracks.index + 1
        endmethod

        public static method addPackage takes TrackPackage thePackage returns nothing
            local Trackable ta = 0
            local integer i = 0

            if not(TrackPackage.initPack) then
                set TrackPackage.allTracks = TrackPackage.allocate()
                set TrackPackage.allTracks.index = 0
            endif

            loop
                set ta = thePackage.tracks[i]
                call TrackPackage.addTrackable(ta)
                set i = i + 1
                exitwhen i >= thePackage.index
            endloop

        endmethod

        public method addTrack takes Trackable theTrack returns nothing
            set .tracks[.index] = theTrack
            set .index = .index + 1
        endmethod

        public method getTrackData takes trackable theTrack returns TrackData
           local integer i = 0

            loop
                if .tracks[i].trackHandle == theTrack then
                    return .tracks[i].data
                endif
                set i = i + 1
                exitwhen i >= .index
            endloop
            return -1
        endmethod
    endstruct
    
    struct CameraSetup
        //: ========================
        //: %Camera Settings%
        //: ========================
        //: - Player Cam Values -
        real targetX
        real targetY
        real targetZ
        
        //: - System Values -
        real systemA
        real systemF
        real systemX
        real systemY
        real systemZ
        
        static timer cameraTimer = CreateTimer()
        
        public static method forceAll takes nothing returns nothing
            local integer i = 0
            
            loop
                exitwhen i > 15
                    if Window.instances[i].displayed then
                        call Window.instances[i].forceCam()
                    endif
                set i = i + 1
            endloop
        endmethod
    endstruct
    
    struct Window extends CameraSetup
        // *&* MEMBERS *&*
        player thePlayer
        rect visibleArea
        boolean displayed
        image array images[64]
        
        trigger onTrackTrigger
        trigger onHitTrigger
        TrackPackage tracks
        
        static thistype array instances[15]
        static boolean array hasInstance[15]

        // *&* METHODS *&*
        
            // This method creates a new instance
        public static method create takes player p returns thistype
            local thistype wd = 0
            
            if .hasInstance[GetPlayerId(p)] then
                call thistype.instances[GetPlayerId(p)].destroy()
            endif
            
            set wd = thistype.allocate()
            set wd.thePlayer = p
            debug call BJDebugMsg("Triggers")
            call wd.initTriggers()
            debug call BJDebugMsg("Make Tracks")
            call wd.makeTracks()
            debug call BJDebugMsg("Images")
            call wd.makeImages()
            debug call BJDebugMsg("Camera")
            call wd.initCam()
            debug call BJDebugMsg("Finished")
            set thistype.instances[GetPlayerId(p)] = wd
            set thistype.hasInstance[GetPlayerId(p)] = true

            return wd
        endmethod
        
            // This method registers track events of a trackpackage
        public method setTrackPackage takes TrackPackage thePackage returns nothing
            local trackable track = null
            local Trackable trackObj = 0
            local integer i = 0

            set .tracks = thePackage

            loop
                exitwhen i >= thePackage.index
                set trackObj = thePackage.tracks[i]
                set track = trackObj.trackHandle
                call TriggerRegisterTrackableHitEvent(.onHitTrigger, track)
                call TriggerRegisterTrackableTrackEvent(.onTrackTrigger, track)
                set i = i + 1
            endloop

            call TrackPackage.addPackage(thePackage)
        endmethod
        
            // This method will call the track event of a window
        public static method onTrackEvent takes nothing returns nothing
            local TrackData tD = TrackPackage.allTracks.getTrackData(GetTriggeringTrackable())
            call thistype.instances[GetPlayerId(tD.thePlayer)].onHit(GetPlayerId(tD.thePlayer), tD.id)
        endmethod

            // This method will call the hit event of a window
        public static method onHitEvent takes nothing returns nothing
            local TrackData tD = TrackPackage.allTracks.getTrackData(GetTriggeringTrackable())
            call thistype.instances[GetPlayerId(tD.thePlayer)].onHit(GetPlayerId(tD.thePlayer), tD.id)
        endmethod
        
            // This method creates triggers for each window instance.
        public method initTriggers takes nothing returns nothing
            set .onHitTrigger = CreateTrigger()
            set .onTrackTrigger = CreateTrigger()
           call TriggerAddAction(.onHitTrigger, function thistype.onHitEvent)
           call TriggerAddAction(.onTrackTrigger, function thistype.onTrackEvent)
        endmethod
        
        // *&* INTERFACE METHODS *&*
        public stub method makeTracks takes nothing returns nothing
        endmethod
        public stub method makeImages takes nothing returns nothing
        endmethod

        public stub method show takes nothing returns nothing
        endmethod
        public stub method hide takes nothing returns nothing
        endmethod

        public stub method onHit takes integer playerId, string trackID returns nothing
        endmethod
        public stub method onTrack takes integer playerId, string trackID returns nothing
        endmethod
        
        public stub method initCam takes nothing returns nothing
        endmethod
        public stub method forceCam takes nothing returns nothing
        endmethod
        // *&* END OF INTERFACE METHODS*&*
    endstruct
endlibrary

And this example:
Collapse JASS:
library Skill initializer init requires WindowSystem
    struct SkillWindow extends Window
    
        //: Creates tracks for all players
        public method makeTracks takes nothing returns nothing
            local trackable track = null
            local Trackable trackObj = 0
            local TrackData trackData = 0
            local TrackPackage trackPack = 0
            local string path = ""
            local string dummyPath = "IconBase.mdx"

            if GetLocalPlayer() == .thePlayer then
                set path = dummyPath
            else
                set path = ""
            endif

            // ===========================================================
            // Create new Trackpackage
            // =======================
            set trackPack = TrackPackage.create()

            // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            // Create trackables
            // - - - - - - - - -
            set track = CreateTrackable(path, 0., 0., 270.)
            set trackData = TrackData.create("Spell1", .thePlayer)
            set trackObj = Trackable.create(track, trackData)
            call trackPack.addTrack(trackObj)
            // - - - - - - - - -
            set track = CreateTrackable(path, 0., 96., 270.)
            set trackData = TrackData.create("Spell2", .thePlayer)
            set trackObj = Trackable.create(track, trackData)
            call trackPack.addTrack(trackObj)
            // - - - - - - - - -
            set track = CreateTrackable(path, 0., 192., 270.)
            set trackData = TrackData.create("Spell3", .thePlayer)
            set trackObj = Trackable.create(track, trackData)
            call trackPack.addTrack(trackObj)
            // - - - - - - - - -
            set track = CreateTrackable(path, 96., 0., 270.)
            set trackData = TrackData.create("Spell4", .thePlayer)
            set trackObj = Trackable.create(track, trackData)
            call trackPack.addTrack(trackObj)
            // - - - - - - - - -
            set track = CreateTrackable(path, 96., 96., 270.)
            set trackData = TrackData.create("Spell5", .thePlayer)
            set trackObj = Trackable.create(track, trackData)
            call trackPack.addTrack(trackObj)
            // - - - - - - - - -
            set track = CreateTrackable(path, 96., 192., 270.)
            set trackData = TrackData.create("Spell6", .thePlayer)
            set trackObj = Trackable.create(track, trackData)
            call trackPack.addTrack(trackObj)
            // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
            // ===========================================================

            call .setTrackPackage(trackPack)
        endmethod
        
        public method makeImages takes nothing returns nothing
            set .images[0] = CreateImage("ReplaceableTextures\\BTNCMD_UPGRADE.blp", 64., 64., 1., 0., 0., 0., 0., 0., 0., 32)
            call ShowImage(.images[0], true)
        endmethod

        public method onTrack takes integer playerId, string trackID returns nothing
            call BJDebugMsg("Player " + GetPlayerName(Player(playerId)) + " has forced Track Event of Track " + trackID)
        endmethod

        public method onHit takes integer playerId, string trackID returns nothing
            call BJDebugMsg("Player " + GetPlayerName(Player(playerId)) + " has forced Hit Event of Track " + trackID)
        endmethod

        public method show takes nothing returns nothing
            set .targetX = GetCameraTargetPositionX()
            set .targetY = GetCameraTargetPositionY()
            set .targetZ = GetCameraTargetPositionZ()
            
            set .displayed = true
        endmethod
        
        public method hide takes nothing returns nothing
            call SetCameraPositionForPlayer(.thePlayer, .targetX, .targetY)
            set .displayed = false
        endmethod
        
        public method initCam takes nothing returns nothing
            set .systemA = 270.
            set .systemF = 90.
            set .systemX = 0.
            set .systemY = 0.
            set .systemZ = 900.
        endmethod
        
        public method forceCam takes nothing returns nothing
            if GetLocalPlayer() == .thePlayer then
                call SetCameraPosition(.systemX, .systemY)
                call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, .systemZ, 0.)    
                call SetCameraField(CAMERA_FIELD_ROTATION, .systemF, 0.)
                call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, .systemA, 0.)
                debug call DisplayTextToPlayer(.thePlayer, 0., 0., "targetA :" + R2S(.systemA))
                debug call DisplayTextToPlayer(.thePlayer, 0., 0., "targetF :" + R2S(.systemF))
                debug call DisplayTextToPlayer(.thePlayer, 0., 0., "targetX :" + R2S(.systemX))
                debug call DisplayTextToPlayer(.thePlayer, 0., 0., "targetY :" + R2S(.systemY))
                debug call DisplayTextToPlayer(.thePlayer, 0., 0., "targetZ :" + R2S(.systemZ))
            endif   
        endmethod
    endstruct

    private function init takes nothing returns nothing
        local SkillWindow sw = SkillWindow.create(Player(0))
        
        call TimerStart(CameraSetup.cameraTimer, 0.07, true, function CameraSetup.forceAll)    
        call FogModifierStart(CreateFogModifierRect(Player(0), FOG_OF_WAR_VISIBLE, GetPlayableMapRect(), true, true))
        call sw.show()
    endfunction
endlibrary

My problem is, the parent methods will be runned on the create call of the parent, not the child ones.
09-13-2009, 01:54 PM#2
weaaddar
Yes, it totally sucks but vJass doesn't determine type until the constructor is finished.
I ran into this problem earlier, but you'll simply need to abstract logic from the constructor.

The easiest way to do this is to create a factory method, that calls the constructor and adds the appropriate logic. In fact you can add that to the parent only and have it call the children methods and that should be fine provided that the logic is outside of the constructor.
09-13-2009, 02:07 PM#3
Earth-Fury
Quote:
Originally Posted by weaaddar
constructor
vJass doesn't have constructors. It has these weird ass factory methods that implement some constructor logic. Personally, I call them "confucktors".

--------

There's some weird stuff with interfaces you may wanna check out... something like:

Collapse JASS:
InterfaceType.create(ExtendsInterface.type_id, params)
// in the child's constructor:
local ExtendsInterface ei = ExtendsInterface.allocate(params)

Check the manual...
09-13-2009, 02:24 PM#4
Anachron
Why is it that hard to run a chields method on parents constructur?

Edit: CHecked the manual, but I didn'T see anything.