LFSLib 0.16b w/ InSim Relay support released
With this version, LFSLib.NET gains support for the InSim Relay currently in testing (see this Forum thread for details). The InSim relay allows you to get a listing of servers connected to the relay and send and receive InSim packets to them without having to directly connect to them. To create an InSimHandler to the relay simply call:
IInSimRelayHandler relay = InSimHandler.GetMasterRelayHandler();
This server isn't up yet, so for testing Victor has set up the following server:
IInSimRelayHandler relay = InSimHandler.GetRelayHandler("vic.lfs.net", 47474);
IInSimRelayHandler implements a subset of the main InSimHandler, discarding methods, properties and events that don't make sense and adding a couple of relay specific ones.
The remainder of the changes are minor tweaks and bug fixes:
- Added auto-reconnect feature to handler (really only works for TCP, since UDP is connectionless)
- CameraPositionInfo now allows ShiftU & related properties to be set
- Updated TrackingInterval to accept values as low as 50ms
- BUGFIX: Fixed race condition where a LFSState event could be fired on a separate thread before the main thread noticed that LFS was connected, allowing for invalid NotConnected exceptions to occur.
- BUGFIX: Fixed Ping event (was looking for the wrong packet)
- BUGFIX: RaceTrackPlayer.HandicapIntakeRestriction always returned zero
Full details are in the release notes.
All links, docs, etc are at lfs.fullmotionracing.com
Labels: InSim Relay, LFS, LFSLib.NET, live for speed
Observable event subscription
The other day I was trying to create an explicit interface implementation of an event and ran into a snag. Now I've done many explicit interface implementations before, but, I guess, never of an event, because I'd not seen the below compiler error before:
An explicit interface implementation of an event must use property syntax
Huh? I did some searches on that error and the best reference was this page. I had long forgotten that the whole += and -= was closely related to how properties work. But instead of using get and set you can create your own logic for subscribe and unsubscribe using add and remove.
As Oliver points out on his blog, it does mean that your event just becomes a facade and you still need another event that actually is being subscribed to. So for that explicit interface implemenation you'd get something like this:
interface IFoo
{
event EventHandler FooHappened;
}
class SomeClass : IFoo
{
private event EventHandler internal_FooHappened;
public event EventHandler IFoo.FooHappened
{
add { internal_FooHappened += value; }
remove { internal_FooHappened -= value; }
}
private void OnFooHappened()
{
if( internal_FooHappened != null )
{
internal_FooHappened(this,EventArgs.Empty);
}
}
}
Now this is really an edge case, imho. But the same syntactic trick does allow for something else that's pretty cool, i.e. being able to be notified when someone subscribes to your event. I've had it happen a number of times, where it would have been useful to take some action on subscription. Maybe the event needs some extra resource, that you don't want to initialize unless someone needs it. It may even be that the real event handler is that resource. So now you can use the above syntax and put extra logic inside of the add to initialize that resource, like this:
class SomeClass
{
SomeResource myResource;
public event EventHandler FooHappened
{
add
{
if( myResource == null )
{
myResource = new SomeResource();
}
myResource.FooHappened += value;
}
remove
{
myResource.FooHappened -= value;
if( myResource.FooHappened == null )
{
myResource.Dispose();
myResource = null;
}
}
}
} Labels: .net, c#, events, explicit interface implementation