Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Bug reports ➜ WindowAddHotSpot - Silent Fail

WindowAddHotSpot - Silent Fail

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Kathan   USA  (9 posts)  Bio
Date Fri 25 Jul 2014 07:00 AM (UTC)

Amended on Fri 25 Jul 2014 07:05 AM (UTC) by Kathan

Message
Before I start, I just want to state that I've only been using MUSHClient for a week.

Version: 4.84

Problem: I was playing around with a blank miniwindow plugin that I created. I was using the Immediate window (Ctrl+I) and adding in text using the WindowText function. Worked perfectly.

Then I wanted to experiment with hotspots.

I used the WindowAddHotSpot function, and there were no errors, but there was no hotspot.


function MouseDown()
    Execute ( "say Hello!" )
end

txt = "(Hellow)"
txtlen = WindowTextWidth(win,font_id,txt)
WindowAddHotspot ( win, "hello" , (209-txtlen)/2, 170 , ((209-txtlen)/2)+txtlen , 170+12 , "", "", "MouseDown", "", "", "Salutations!", 1, 0)


I tried a code snippet I found on the forums:

-- show all hotspots
hotspots = WindowHotspotList(win)

if hotspots then
  for _, v in ipairs (hotspots) do 
    Note (v) 
  end
end -- if any


The only hotspots listed were the ones created inside the plugin itself. I tried adding the new hotspot code to the plugin and it worked as expected.

After playing around for a bit, I decided to try wrapping the WindowAddHotspot function in the check function. This time when running the code, I got the error "Hotspot processing must all be in same plugin".


Run-time error
World: Aardwolf
Immediate execution
[string "Immediate"]:6: Hotspot processing must all be in same plugin
stack traceback:
        [C]: in function 'error'
        [string "Check function"]:1: in function 'check'
        [string "Immediate"]:6: in main chunk


I think this is saying that all the functions the hotspots call have to be in one place (plugin or world script).

My complaint is I would have expected the error without using the check function. It was very frustrating to have the WindowAddHotspot function fail silently the way it did.

I also looked through the documentation and couldn't find any mention of the requirement for all the hotspots being in one place.
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #1 on Fri 25 Jul 2014 10:37 PM (UTC)

Amended on Fri 25 Jul 2014 11:00 PM (UTC) by Nick Gammon

Message
Quote:

My complaint is I would have expected the error without using the check function. It was very frustrating to have the WindowAddHotspot function fail silently the way it did.


It is pretty standard practice with API calls in many operating systems and utilities that they return a "success" or "failure" code (or throw an exception) rather than raising a dialog box or printing something to output.

It is usually the responsibility of the programmer to check documented return codes. Those return codes are mentioned in the documentation for the MUSHclient function APIs.

You could wrap a "check" call around every Windowxxxx call, however that gets a bit messy to read.

Another approach is to automatically replace all function calls with a "stub" function that does the check for you, as shown below.


-- automatically check Window* function results

-- stub function generator to check a function call

local function make_check_func (f)
  return function (...)
     local results = { f (...) }  -- call original function
     check (results [1])          -- check return value
     return unpack (results)      -- return results 
  end -- function
end -- make_check_func 

-- functions this will work with (that return eOK, and other things)

local valid_funcs = { }

for k, v in ipairs  {
"WindowAddHotspot", "WindowArc", "WindowBezier", "WindowBlendImage", 
"WindowCircleOp", "WindowCreate", "WindowCreateImage", "WindowDelete", 
"WindowDeleteAllHotspots", "WindowDeleteHotspot", "WindowDragHandler", 
"WindowDrawImage", "WindowDrawImageAlpha", "WindowFilter", "WindowFont", 
"WindowGetImageAlpha", "WindowGradient", "WindowHotspotTooltip", "WindowImageFromWindow", 
"WindowImageOp", "WindowLine", "WindowLoadImage", "WindowMergeImageAlpha", 
"WindowMoveHotspot", "WindowPolygon", "WindowPosition", "WindowRectOp", 
"WindowResize", "WindowScrollwheelHandler", "WindowSetPixel", "WindowSetZOrder", 
"WindowShow", "WindowTransformImage", "WindowWrite", 
} do valid_funcs [v] = true end 

-- see if one of them is a C function or a Lua function
local t = debug.getinfo (WindowShow, "S")

-- replace world Window* functions with a stub
if t.short_src == "[C]" then  -- if not already converted
  for k, f in pairs (world) do
    if type (f) == "function" and valid_funcs [k] then
      world [k] = make_check_func (f)  -- replace with stub
    end -- if
  end -- for
end -- if not done already


Put the above at the start of your world script file, or your plugin script.

Now you can call the functions normally, but an error will be raised if they fail. For example, testing (on the command line) with an non-existent window name:


/ WindowShow ("foo")


Result:


Run-time error
World: smaug2
Immediate execution
[string "Immediate"]:8: Requested miniwindow does not exist
stack traceback:
        [C]: in function 'error'
        [string "Check function"]:1: in function 'check'
        [string "Immediate"]:8: in function 'WindowShow'
        [string "Command line"]:1: in main chunk


There is a bit of complexity in the above because not every function call is documented to return eOK (zero) or something else, for example WindowInfo returns a variant which is the information requested. Thus there is a table above to limit the conversion of only certain functions to the stub calls.

Quote:

I also looked through the documentation and couldn't find any mention of the requirement for all the hotspots being in one place.


The last line (presently) in the documentation for WindowAddHotspot reads:


WARNING: The hotspot callbacks are not functions, but names of functions. That is, they should be supplied as string arguments. The supplied names are looked up in the script space at the appropriate time.


Each world file (and each plugin) has their own script space, indeed those scripts might be written in different languages. The wording "the script space" is supposed to imply "of the current plugin".

I have amended the documentation in the next release to emphasise that the callbacks have to be in the same plugin.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #2 on Fri 25 Jul 2014 11:03 PM (UTC)
Message

A quick scan of the help database reveals that these are the functions (Window-related or not) which might return eOK.

Name
Accelerator
AcceleratorTo
AddAlias
AddFont
AddMapperComment
AddSpellCheckWord
AddTimer
AddToMapper
AddTrigger
AddTriggerEx
ArrayClear
ArrayCreate
ArrayDelete
ArrayDeleteKey
ArrayImport
ArraySet
CallPlugin
ChatAcceptCalls
ChatCall
ChatCallzChat
ChatDisconnect
ChatEverybody
ChatGroup
ChatID
ChatMessage
ChatNameChange
ChatPasteEverybody
ChatPasteText
ChatPeekConnections
ChatPersonal
ChatPing
ChatRequestConnections
ChatSendFile
ChatStopFileTransfer
CloseLog
Connect
DeleteAlias
DeleteAllMapItems
DeleteLastMapItem
DeleteTimer
DeleteTrigger
DeleteVariable
Disconnect
DoAfter
DoAfterNote
DoAfterSpecial
DoAfterSpeedWalk
DoCommand
EnableAlias
EnablePlugin
EnableTimer
EnableTrigger
Execute
FlushLog
GetAlias
GetTimer
GetTrigger
IsAlias
IsTimer
IsTrigger
LoadPlugin
LogSend
OpenBrowser
OpenLog
PlaySound
PluginSupports
Queue
ReadNamesFile
ReloadPlugin
ResetTimer
Save
SaveState
Send
SendImmediate
SendNoEcho
SendPkt
SendPush
SendSpecial
SetAliasOption
SetAlphaOption
SetBackgroundImage
SetChatOption
SetCommand
SetCommandSelection
SetCommandWindowHeight
SetCursor
SetCustomColourName
SetForegroundImage
SetOption
SetScroll
SetTimerOption
SetToolBarPosition
SetTriggerOption
SetVariable
SetWorldWindowStatus
ShiftTabCompleteItem
Sound
StopSound
TextRectangle
UdpListen
UnloadPlugin
WindowAddHotspot
WindowArc
WindowBezier
WindowBlendImage
WindowCircleOp
WindowCreate
WindowCreateImage
WindowDelete
WindowDeleteAllHotspots
WindowDeleteHotspot
WindowDragHandler
WindowDrawImage
WindowDrawImageAlpha
WindowFilter
WindowFont
WindowGetImageAlpha
WindowGradient
WindowHotspotTooltip
WindowImageFromWindow
WindowImageOp
WindowLine
WindowLoadImage
WindowMergeImageAlpha
WindowMoveHotspot
WindowPolygon
WindowPosition
WindowRectOp
WindowResize
WindowScrollwheelHandler
WindowSetPixel
WindowSetZOrder
WindowShow
WindowTransformImage
WindowWrite
WriteLog

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Kathan   USA  (9 posts)  Bio
Date Reply #3 on Fri 25 Jul 2014 11:27 PM (UTC)
Message
Ok, that makes sense. Thanks for the information.
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #4 on Fri 25 Jul 2014 11:36 PM (UTC)
Message
This isn't a bug BTW, it is doing what it is documented to do.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


16,477 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.