Quantcast

* Reworking of the Waypoints API... callbacks are broken as a result

James Whitehead Ii [02-24-08 - 23:03]
* Reworking of the Waypoints API... callbacks are broken as a result
Filename
TomTom_CrazyArrow.lua
TomTom_Waypoints.lua
diff --git a/TomTom_CrazyArrow.lua b/TomTom_CrazyArrow.lua
index 52c576d..c067649 100644
--- a/TomTom_CrazyArrow.lua
+++ b/TomTom_CrazyArrow.lua
@@ -111,7 +111,7 @@ local time = 0
 local distance = 0
 local delta = 0
 local function OnUpdate(self, elapsed)
-	local dist,x,y = TomTom:GetDistanceToWaypoint(active_point)
+	local dist,x,y = active_point:GetDistanceToWaypoint()
 	if not dist then
 		self:Hide()
 		return
@@ -152,7 +152,7 @@ local function OnUpdate(self, elapsed)
 			showDownArrow = false
 		end

-		local angle = TomTom:GetDirectionToWaypoint(active_point)
+		local angle = active_point:GetDirectionToWaypoint()
 		local player = GetPlayerBearing()

 		angle = angle - player
diff --git a/TomTom_Waypoints.lua b/TomTom_Waypoints.lua
index 022231f..e88c943 100644
--- a/TomTom_Waypoints.lua
+++ b/TomTom_Waypoints.lua
@@ -21,157 +21,127 @@ do
 end

 -- Create a local table used as a frame pool
-local pool = {}
+local pool = {
+	minimap = {},
+	worldmap = {},
+}

 -- Local declarations
 local Minimap_OnEnter,Minimap_OnLeave,Minimap_OnUpdate,Minimap_OnClick,Minimap_OnEvent
 local Arrow_OnUpdate
-local Minimap_OnEvent
 local World_OnEnter,World_OnLeave,World_OnClick,World_OnEvent

--- Unique identifier for each of the waypoints
+local WaypointClass = {}

-local uidmap = {}
-local getuid
-do
-	local uid = 0
-	function getuid()
-		uid = uid + 1
-		return uid
+function WaypointClass:Show(minimap, worldmap)
+	local x = self.x / 100
+	local y = self.y / 100
+
+	if minimap then
+		Astrolabe:PlaceIconOnMinimap(self.minimap, self.c, self.z, x, y)
 	end
-end

-function TomTom:GetDistanceToWaypoint(uid)
-	local point = uidmap[uid]
-	if point then
-		return Astrolabe:GetDistanceToIcon(point.minimap)
+	if worldmap then
+		local x, y = Astrolabe:PlaceIconOnWorldMap(WorldMapDetailFrame, self.worldmap, self.c, self.z, x, y)
+		self.worldmap:Show()
 	end
 end

-function TomTom:GetDirectionToWaypoint(uid)
-	local point = uidmap[uid]
-	if point then
-		return Astrolabe:GetDirectionToIcon(point.minimap)
+function WaypointClass:Hide(minimap, worldmap)
+	if minimap then
+		Astrolabe:RemoveIconFromMinimap(self.minimap)
+	end
+
+	if worldmap then
+		Astrolabe:Hide()
 	end
 end

--- pointObject = TomTom:SetWaypoint(c,z,x,y,far,near,arrive,callback)
--- c (number) - The continent number
--- z (number) - The zone number
--- x (number) - The x coordinate
--- y (number) - The y coordinate
--- far (number) - A distance in yards to trigger the OnFar callback
--- near (number) - A distance in yards to trigger the OnNear callback
--- arrive (number) - A distance in yards to trigger the OnArrive callback
--- callback (function) - A function to be called on state changes.  This function
---   will be passed the frame itself, an event string, the distance to the point
---   in yards, and any addition arguments that are necessary.
---
--- Creates a waypoint at the given coordinates and registers a callback to handle
--- the following state changes:
-
--- OnEdgeChanged - Called when the icon's edge state changes.  Passes a boolean
---   value onEdge that indicates if the icon is currently on the edge, or not.
--- OnTooltipShown - Called every 0.2 seconds when the tooltip is visible for the
---   given icon. Passes the tooltip, the distance to the icon in yards,
---   and a boolean flag indicating if this is the first frame showing the tooltip
---   as opposed to an update
--- OnDistanceFar
--- OnDistanceNear
--- OnDistanceArrive
-function TomTom:SetWaypoint(c,z,x,y,far,near,arrive,callback)
-	-- Try to acquire a waypoint from the frame pool
-	local point = table.remove(pool)
-
-	if not point then
-		point = {}
-
-		point.minimap = CreateFrame("Button", nil, Minimap)
-		point.minimap:SetHeight(20)
-		point.minimap:SetWidth(20)
-		point.minimap:SetFrameLevel(4)
-		point.minimap:RegisterForClicks("RightButtonUp")
-
-		-- Create the actual texture attached for the minimap icon
-		point.minimap.icon = point.minimap:CreateTexture("BACKGROUND")
-		point.minimap.icon:SetTexture("Interface\\AddOns\\TomTom\\Images\\GoldGreenDot")
-		point.minimap.icon:SetPoint("CENTER", 0, 0)
-		point.minimap.icon:SetHeight(12)
-		point.minimap.icon:SetWidth(12)
-
-		point.minimap.arrowout = point.minimap:CreateTexture("BACKGROUND")
-		point.minimap.arrowout:SetTexture("Interface\\AddOns\\TomTom\\Images\\MinimapArrow-Green")
-		point.minimap.arrowout:SetPoint("CENTER", 0, 0)
-		point.minimap.arrowout:SetHeight(40)
-		point.minimap.arrowout:SetWidth(40)
-		point.minimap.arrowout:SetVertexColor(1, 1, 1)
-		point.minimap.arrowout:Hide()
-
-		-- Create the world map point, and associated texture
-		point.world = CreateFrame("Button", nil, WorldMapDetailFrame)
-		point.world:SetHeight(12)
-		point.world:SetWidth(12)
-		point.world:RegisterForClicks("RightButtonUp")
-		point.world.icon = point.world:CreateTexture()
-		point.world.icon:SetAllPoints()
- 		point.world.icon:SetTexture("Interface\\AddOns\\TomTom\\Images\\GoldGreenDot")
+function WaypointClass:GetDistanceToWaypoint()
+	return Astrolabe:GetDistanceToIcon(self.minimap)
+end

-		-- Add the behavior scripts
-		point.minimap:SetScript("OnEnter", Minimap_OnEnter)
-		point.minimap:SetScript("OnLeave", Minimap_OnLeave)
-		point.minimap:SetScript("OnUpdate", Minimap_OnUpdate)
-		point.minimap:SetScript("OnClick", Minimap_OnClick)
-		point.minimap:RegisterEvent("PLAYER_ENTERING_WORLD")
-		point.minimap:SetScript("OnEvent", Minimap_OnEvent)
-
-		point.world:RegisterEvent("WORLD_MAP_UPDATE")
-		point.world:SetScript("OnEnter", World_OnEnter)
-		point.world:SetScript("OnLeave", World_OnLeave)
-		point.world:SetScript("OnClick", World_OnClick)
-		point.world:SetScript("OnEvent", World_OnEvent)
+function WaypointClass:GetDirectionToWaypoint()
+	return Astrolabe:GetDirectionToIcon(self.minimap)
+end

-		point.data = {}

-		-- Point from the icons/arrow into the data
-		point.minimap.data = point.data
-		point.world.data = point.data
+function TomTom:SetWaypoint(c, z, x, y, distances)
+	-- Try to acquire a waypoint from the frame pool
+	local minimap = table.remove(pool.minimap)
+	local worldmap = table.remove(pool.worldmap)
+
+	if not minimap then
+		minimap = CreateFrame("Button", nil, Minimap)
+		minimap:SetHeight(20)
+		minimap:SetWidth(20)
+		minimap:RegisterForClicks("RightButtonUp")
+
+		minimap.icon = minimap:CreateTexture("BACKGROUND")
+		minimap.icon:SetTexture("Interface\\AddOns\\TomTom\\Images\\GoldGreenDot")
+		minimap.icon:SetPoint("CENTER", 0, 0)
+		minimap.icon:SetHeight(12)
+		minimap.icon:SetWidth(12)
+
+		minimap.arrow = minimap:CreateTexture("BACKGROUND")
+		minimap.arrow:SetTexture("Interface\\AddOns\\TomTom\\Images\\MinimapArrow-Green")
+		minimap.arrow:SetPoint("CENTER", 0 ,0)
+		minimap.arrow:SetHeight(40)
+		minimap.arrow:SetWidth(40)
+		minimap.arrow:Hide()
+
+		-- Add the behavior scripts
+		minimap:SetScript("OnEnter", Minimap_OnEnter)
+		minimap:SetScript("OnLeave", Minimap_OnLeave)
+		minimap:SetScript("OnUpdate", Minimap_OnUpdate)
+		minimap:SetScript("OnClick", Minimap_OnClick)
+		minimap:RegisterEvent("PLAYER_ENTERING_WORLD")
+		minimap:SetScript("OnEvent", Minimap_OnEvent)
 	end

-	-- Set the relevant data in the point object
-	point.data.c = c
-	point.data.z = z
-	point.data.x = x
-	point.data.y = y
-	point.data.far = far
-	point.data.near = near
-	point.data.arrive = arrive
-	point.data.callback = callback
+	if not worldmap then
+		worldmap = CreateFrame("Button", nil, WorldMapDetailFrame)
+		worldmap:SetHeight(12)
+		worldmap:SetWidth(12)
+		worldmap:RegisterForClicks("RightButtonUp")
+		worldmap.icon = worldmap:CreateTexture("ARTWORK")
+		worldmap.icon:SetAllPoints()
+		worldmap.icon:SetTexture("Interface\\AddOns\\TomTom\\Images\\GoldGreenDot")
+
+		worldmap:RegisterEvent("WORLD_MAP_UPDATE")
+		worldmap:SetScript("OnEnter", World_OnEnter)
+		worldmap:SetScript("OnLeave", World_OnLeave)
+		worldmap:SetScript("OnClick", World_OnClick)
+		worldmap:SetScript("OnEvent", World_OnEvent)
+	end

-	local uid = getuid()
-	point.data.uid = uid
-	uidmap[uid] = point
+	-- Create a new waypoint object which wraps
+	local point = setmetatable({}, {__index=WaypointClass})
+	point.c = c
+	point.z = z
+	point.x = x
+	point.y = y
+	point.distances = distances
+	point.minimap = minimap
+	point.worldmap = worldmap

+	-- Link the actual frames back to the waypoint object
+	minimap.point = point
+	worldmap.point = point

-	-- Use Astrolabe to place the waypoint
-	local x = x/100
-	local y = y/100
-	Astrolabe:PlaceIconOnMinimap(point.minimap, c, z, x, y)
-	Astrolabe:PlaceIconOnWorldMap(WorldMapDetailFrame, point.world, c, z, x, y)
+	-- Place the waypoints
+	point:Show(true, true)

-	return uid
+	return point
 end

-function TomTom:ClearWaypoint(uid)
-	local point = uidmap[uid]
+function TomTom:ClearWaypoint(point)
 	if point then
-		point.data = {}
-		point.minimap.data = point.data
-		point.world.data = point.data
-
-		Astrolabe:RemoveIconFromMinimap(point.minimap)
-		point.world:Hide()
-		table.insert(pool, point)
-		uidmap[uid] = nil
+		point:Hide(true, true)
+		table.insert(pool.minimap, point.minimap)
+		table.insert(pool.worldmap, point.worldmap)
+		point.minimap = nil
+		point.worldmap = nil
 	end
 end

@@ -179,8 +149,10 @@ do
 	local tooltip_icon,tooltip_callback

 	function Minimap_OnEnter(self, motion)
+		local data = self
+
 		tooltip_icon = self
-		tooltip_callback = self.data.callback
+		tooltip_callback = data.callback

 		if tooltip_callback then
 			local dist,x,y = Astrolabe:GetDistanceToIcon(self)
@@ -225,14 +197,14 @@ do
 		minimap_count = 0

 		local edge = Astrolabe:IsIconOnEdge(self)
-		local data = self.data
+		local data = self.point
 		local callback = data.callback

 		if edge then
 			-- Check to see if this is a transition
 			if not data.edge then
 				self.icon:Hide()
-				self.arrowout:Show()
+				self.arrow:Show()
 				data.edge = true

 				if callback then
@@ -253,11 +225,11 @@ do
 			end

 			local sin,cos = math.sin(angle) * square_half, math.cos(angle) * square_half
-			self.arrowout:SetTexCoord(0.5-sin, 0.5+cos, 0.5+cos, 0.5+sin, 0.5-cos, 0.5-sin, 0.5+sin, 0.5-cos)
+			self.arrow:SetTexCoord(0.5-sin, 0.5+cos, 0.5+cos, 0.5+sin, 0.5-cos, 0.5-sin, 0.5+sin, 0.5-cos)

 		elseif data.edge then
 			self.icon:Show()
-			self.arrowout:Hide()
+			self.arrow:Hide()
 			data.edge = nil

 			if callback then
@@ -331,7 +303,7 @@ do

 	function World_OnEvent(self, event, ...)
 		if event == "WORLD_MAP_UPDATE" then
-			local data = self.data
+			local data = self.point
 			-- It seems that data.x and data.y are occasionally not valid
 			-- perhaps when the waypoint is removed.  Guard this for now
 			-- TODO: Fix permanently