Created
January 2, 2011 04:38
-
-
Save dvdsgl/762279 to your computer and use it in GitHub Desktop.
This is why MonoMac is hot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using MonoMac.Foundation; | |
using MonoMac.AppKit; | |
using MonoMac.ObjCRuntime; | |
using Cadenza; | |
namespace MySecretApp { | |
public class UserStateObserver { | |
public event EventHandler<UserStateEventArgs> UserStateChanged; | |
public UserState State { | |
get { return state; } | |
private set { | |
if (value != state) | |
UserStateChanged.Raise (this, new UserStateEventArgs (value)); | |
state = value; | |
} | |
} | |
bool ScreenSaverIsOn; | |
UserState state; | |
List<NSTimer> Timers; | |
public UserStateObserver () | |
{ | |
state = UserState.Busy; | |
Timers = new List<NSTimer> (); | |
} | |
public void Start () | |
{ | |
TransitionTo (UserState.Idle, WheneverComputerSleeps); | |
TransitionTo (UserState.Busy, WheneverComputerWakes); | |
TransitionTo (UserState.Idle, WheneverScreenSaverBegins); | |
TransitionTo (UserState.Idle, Every (5.Minutes (), IfScreenSaverIsOn)); | |
TransitionTo (UserState.Busy, WheneverScreenSaverEnds); | |
} | |
public void Stop () | |
{ | |
Timers.ForEach (timer => timer.Invalidate ()); | |
} | |
void OnWorkspaceNotification (string notification, Action act) | |
{ | |
var center = NSWorkspace.SharedWorkspace.NotificationCenter; | |
center.AddObserver (new NSString (notification), note => act ()); | |
} | |
void OnDistributedNotification (string notification, Action act) | |
{ | |
// TODO remove extraneous cast when API is typed correctly. | |
// TODO how do we remove an observer? | |
var center = NSDistributedNotificationCenter.DefaultCenter as NSDistributedNotificationCenter; | |
center.AddObserver (new NSString (notification), note => act ()); | |
} | |
void TransitionTo (UserState state, Action<Action> whenever) | |
{ | |
whenever (() => State = state); | |
} | |
/// <summary> | |
/// If foo is an Action<Action>, and bar is Action, then (Every (period, foo) (bar)) | |
/// starts a timer which calls foo (bar) every period. | |
Action<Action> Every (TimeSpan period, Action<Action> act) | |
{ | |
return transition => { | |
var timer = NSTimer.CreateRepeatingTimer (period, () => act (transition)); | |
NSRunLoop.Current.AddTimer (timer, NSRunLoop.NSRunLoopCommonModes); | |
Timers.Add (timer); | |
}; | |
} | |
void WheneverComputerSleeps (Action act) | |
{ | |
OnWorkspaceNotification ("NSWorkspaceWillSleepNotification", act); | |
} | |
void WheneverComputerWakes (Action act) | |
{ | |
OnWorkspaceNotification ("NSWorkspaceDidWakeNotification", act); | |
} | |
void WheneverScreenSaverBegins (Action act) | |
{ | |
OnDistributedNotification ("com.apple.screensaver.didstart", () => { | |
ScreenSaverIsOn = true; | |
act (); | |
}); | |
} | |
void IfScreenSaverIsOn (Action act) | |
{ | |
if (ScreenSaverIsOn) act (); | |
} | |
void WheneverScreenSaverEnds (Action act) | |
{ | |
OnDistributedNotification ("com.apple.screensaver.didstop", () => { | |
ScreenSaverIsOn = false; | |
act (); | |
}); | |
} | |
} | |
} |
No, (() => State = state) is an Action that sets the state.
Oops, sorry for the mistake! Makes sense.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Line 67: Do you want == instead of = ?