Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Link Breaking Macro Conflict

I've run into an odd problem while working in harlowe. If I use the click-replace macro and in the same passage us live and replace to cycle through some text (example below) hovering over the click-replace link causes it to blink with the live macro and can't be clicked in between blinks. If the macro is set to a faster rate (like the example) the link can't be clicked at all. If the time is slowed down to a more readable rate it's possible to click in between blinks, but that still feels less then ideal. This problem does not affect regular passage to passage links. Is there any way to fix this or work around it? Or, is there a better way I could be cycling through text that won't cause this problem?

Click-Replace (click-replace: "Click-Replace")[Replace with this text]

Replace this
(live: 0.1s)[(replace: "Replace this")[with this]]
(live: 0.1s)[(replace: "with this")[then back]]
(live: 0.1s)[(replace: "then back")[Replace this]]

Comments

  • notes:
    1. Because I don't want to talk about advanced topics like threading and concurrence the following information will be simplified and not 100% technically correct.

    2. There is a logic error in your example, the "Replace with this text" text will not exist until after the related link is click, so until that happens your (live:) macros are constantly scanner the whole of the current passage's content over and over looking for the relevant text to replace.

    Each of your (live:) macros creates it's own background timer that will execute the contents of the each of the related associated hook over and over until either each timer is stopped via it's own (stop:) macro or the story navigates to another (possible the same) passage.

    Simply put the web-browser can either monitor the user's input (like a mouse click) or execute the content of one of your timers, it can't do multiple things at the same time. This is why you are having problems clicking on the link.

    eg. In your example the web-browser is constantly switching between four things, monitoring the user's input and processing the content of each of the three timers.

    Because of this it is generally a good idea to only use a single (live:) macro per passage, and to use logic with it's associate hook to control what happens each time it executes, this technique is commonly known as a Game Loop. This topic was partly covered in the How to restart a live macro thread.

    eg. One possible version of your example using a single (live:) macro, I have changed the delay to one second (1s) so you can see the changes but it works just as well using one hundred milliseconds (100ms)
    Click-Replace (click-replace: "Click-Replace")[Replace with this text\
    {
    (set: $tick to 0)
    (live: 1s)[
    	(set: $tick to it +1)
    	(if: $tick is 1)[(replace: "Replace this")[with this]]
    	(else-if: $tick is 2)[(replace: "with this")[then back]]
    	(else:)[
    		(stop:)
    		(replace: "then back")[Replace this]
    	]
    ]
    }]
    
    ... notice I moved the usage of the (live:) macro into the (click-replace:) macro's associated hook, this way the timer does not start until after the link has been clicked.

    Personally I try not to use the String based version of macros like (click-replace:) and (replace:) unless necessary because they need to scan the whole contents of a passage to find every occurrence of their target text, instead I use the named hook versions whenever I can.
  • edited September 2016
    That's great. Thanks for the insight.
  • Greyelf, you got me thinking and I've got a couple question about what you posted if you don't mind getting into this subject a little further.

    So I had and idea that's a little beyond my understanding of if macros right now. I want to keep a looping live replace macro. Is it possible to stop the live macro when the .link.enchantment-link:hover is active in between scan intervals, and then start the live macro up again after the links been clicked? Or is that beyond the scope of if macros?

    And another question, so if scanning interrupts user input why is the passage to passage link interrupted? Is it just that the click-replace link requires scanning and the passage to passage link doesn't? And what about mouseover-replace how come it's not affected in the same scenario as the example? The mouseover-replace and the passage to passage links both seem like user interactions that aren't interrupted my the scanning.
  • notes:
    1. The following information will be simplified and not 100% technically correct.
    2. The term user input generally covers both keyboard key-presses and mouse button clicks.
    so if scanning interrupts user input...
    My previous post may not of been clear enough, it is the timer events created by the (live:) macros that are the main cause of the interrupting of user input.

    eg. Basic 'Threading'.

    You have a Teacher with four students (A, B, C, D) and each of the students has a task to do. A student can only preform their task if the Teacher hands them the Rod of Command, and once a student has finished their task they have to hand the Rod back to the Teacher.

    In your example student A is monitoring for key-presses and mouse clicks, and students B-D represent each of the timers created by the (live:) macros.

    eg. Basic 'Priority'.

    Student A's task is very important so the Teacher decides that Student A should hold the Rod whenever no-one else is using it. Thus Student A gets to hold the Rod more often that the other students do.

    eg. Basic 'Yielding'

    Student A is very passive and allows Student B-D to take the Rod from them even though Student A may not of completely finished their task yet. In your example this can result in the mouse clicks being ignored.

    To further complicate matters a task can be made up of multiple steps and some of these steps can be executed in a manor that allows them to 'yield' the Rod to someone else if asked. This can cause a delay in that step's processing, and thus a delay in the completion of the task.

    Is it possible to stop the live macro when the .link.enchantment-link:hover is active...
    I personally don't know of a simple way to detect the relevant hover event that would allow the timer thread to be stopped. The main issue is that the timer thread needs to be stopped from within the associated hook.
    And what about mouseover....
    Simply put, the movement of the mouse cursor is handled differently to that of user imputs like a mouse click.
Sign In or Register to comment.