What happened to the Messenger Plus! forums on msghelp.net?
Shoutbox » MsgHelp Archive » Messenger Plus! for Live Messenger » Scripting » Sleep

Sleep
Author: Message:
Scale
New Member
*


Posts: 2
Joined: Dec 2010
O.P. Sleep
Hey guys,

I'm working on a script, and i was wondering how to 'pause' the script.
Should i just call sleep in kernel32? The effect kinda depends on how the scripting engine is built.

Separate thread for each script?
12-18-2010 08:52 PM
Profile E-Mail PM Find Quote Report
mynetx
Skinning Contest Winner
*****

Avatar
Microsoft insider

Posts: 1175
Reputation: 33
36 / Male / Flag
Joined: Jul 2007
RE: Sleep
Hello Scale,

To pause the execution, you would have to create a timer using MsgPlus::AddTimer. When the timer has expired, your function OnEvent_Timer will be called with the given Timer ID string.

Does this help you out?
mynetx - Microsoft, enhanced.

You have a problem or issue with Windows, Internet
Explorer or Office?
Send a tweet!
12-18-2010 08:56 PM
Profile E-Mail PM Web Find Quote Report
Scale
New Member
*


Posts: 2
Joined: Dec 2010
O.P. RE: Sleep
That's gonna make for some BAD coding :P
Timers and loops is a bad mix ;)

Guess sleep is out of the question then,
Thanks anyway
12-18-2010 09:09 PM
Profile E-Mail PM Find Quote Report
matty
Scripting Guru
*****


Posts: 8336
Reputation: 109
39 / Male / Flag
Joined: Dec 2002
Status: Away
RE: Sleep
Currently each script is run inside the main thread of Windows Live Messenger. Calling Sleep will cause the entire thread to pause.

Simply externalize the code you wish to run after a specific matter of time. Pass the function name as the timer id then use eval to execute the function. Not the best way but currently the only plausible workaround.
12-18-2010 11:47 PM
Profile E-Mail PM Find Quote Report
Amec
Junior Member
**


Posts: 19
32 / Male / Flag
Joined: Sep 2008
RE: Sleep
Instead of passing function names to OnEvent_Timer, you could implement setTimeout and use callbacks. An example implementation would be...

code:
var timers = [];
   
function setTimeout(func, delay) {
    var timerId = "TIMEOUT_" + delay + "_" + Math.floor(Math.random()*100000000);
    MsgPlus.AddTimer(timerId, delay);
    timers[timerId] = func;
    return timerId;
}

function clearTimeout(timerId) {
    if(timerId.substr(0, 7) === "TIMEOUT")
    {
        MsgPlus.CancelTimer(timerId);
        timers[timerId] = null;
    }
}

function setInterval(func, delay) {
    var timerId = "INTERVAL_" + delay + "_" + Math.floor(Math.random()*100000000);
    MsgPlus.AddTimer(timerId, delay);
    timers[timerId] = func;
    return timerId;
}

function clearInterval(timerId) {
    if(timerId.substr(0, 8) === "INTERVAL")
    {
        MsgPlus.CancelTimer(timerId);
        timers[timerId] = null;
    }
}

function OnEvent_Timer(timerId)
{
    if(timerId.substr(0, 7) === "TIMEOUT")
    {
        timers[timerId].call(this);
        clearTimeout(timerId);
    }
    else if(timerId.substr(0, 8) === "INTERVAL")
    {
        timers[timerId].call(this);   
        MsgPlus.AddTimer(timerId, Number(timerId.split("_")[1]));
    }
}

...and an example usage would be...

code:
function OnEvent_Initialize(MessengerStart) {
    [...] //do stuff

    setTimeout(function () { //sleep for two seconds
        [...] //do more stuff
    }, 2000);

}

It's not pretty, and can get pretty deeply nested... But I think it's better than evaling stuff.

This post was edited on 01-23-2011 at 08:11 AM by Amec.
01-23-2011 08:06 AM
Profile E-Mail PM Find Quote Report
Matti
Elite Member
*****

Avatar
Script Developer and Helper

Posts: 1646
Reputation: 39
31 / Male / Flag
Joined: Apr 2004
RE: Sleep
@Amec: That implementation would do the job just fine, but there's still room for improvement.
  • You're trying to add elements to the timers array, but since you're using a string as key you're actually just setting an object property. Either you use numerical indexes and make proper use of the array, or you just make timers an object. Because you're not actually using any array-specific features, you can simply get away with an object here.
  • Instead of parsing data out of the keys in OnEvent_Timer, you can just store objects as elements in timers and read the properties instead.
  • You should check whether the timerId actually exists in timers in OnEvent_Timer. Sure, chances are slim that you'll ever get an invalid timer, but you never know.
  • Try to reuse some of your code! setTimeout and setInterval are almost identical. ;)
I had a go with this myself, threw in some tasty OOP and here's what I came up with:
js code:
/* Somewhat private worker classes */
// Timer sets up a timer and exposes methods
var Timer = function(fCallback, nInterval) {
    this.Callback = function() {
        fCallback.call(this);
        this.Cancel();
    };
    this.Interval = nInterval;
    // Add to storage
    this.Index = Timer.Storage.length;
    Timer.Storage.push(this);
    // Identifier for timer events
    this.Id = 'Timer#'+this.Index;
    MsgPlus.AddTimer(this.Id, this.Interval);
};
// Storage array as static property
Timer.Storage = [];
// Instance methods
Timer.prototype = {
    Refresh : function() {
        Timers[this.Index] = this;
        MsgPlus.AddTimer(this.Id, this.Interval);
    },
    Cancel : function() {
        Timers[this.Index] = null;
        MsgPlus.CancelTimer(this.Id);
    }
};

// Interval is identical to Timer, except for its Callback property
var Interval = function(fCallback, nInterval) {
    // Call superclass constructor
    Timer.apply(this, arguments);
    // Callback refreshes timer instead of canceling it
    this.Callback = function() {
        fCallback.call(this);
        this.Refresh();
    };
};
Interval.prototype = Timer.prototype; // Prototypical inheritance! :O

// Timer event handling
function OnEvent_Timer(timerId) {
    if((m = /^Timer#(\d+)$/.exec(timerId)) !== null) {
        var nIndex = 1*m[1], timer = Timer.Storage[nIndex];
        if(timer && timer.Callback) {
            timer.Callback();
            return;
        }
    }
    // Other timers can be handled here...
}

function setTimeout(func, delay) {
    var timer = new Timer(func, delay);
    return timer.Index;
}
function setInterval(func, delay) {
    var interval = new Interval(func, delay);
    return interval.Index;
}

function clearTimeout(timerIndex) {
    var timer = Timer.Storage[timerIndex];
    if(timer && timer.Cancel) {
        timer.Cancel();
    }
}
var clearInterval = clearTimeout;
In fact, you could use this code without the functions at the bottom and simply go with the classes.

I don't want to scare you off, I simply thought I'd show you another way to do it. Feel free to play around with it. :)
Plus! Script Developer | Plus! Beta Tester | Creator of Countdown Live | Co-developer of Screenshot Sender 5

Found my post useful? Rate me!
01-23-2011 11:02 AM
Profile E-Mail PM Web Find Quote Report
« Next Oldest Return to Top Next Newest »


Threaded Mode | Linear Mode
View a Printable Version
Send this Thread to a Friend
Subscribe | Add to Favorites
Rate This Thread:

Forum Jump:

Forum Rules:
You cannot post new threads
You cannot post replies
You cannot post attachments
You can edit your posts
HTML is Off
myCode is On
Smilies are On
[img] Code is On