source: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Samples.Kinect.Webserver/Sensor/SkeletonStreamHandler.cs@ 28896

Last change on this file since 28896 was 28896, checked in by davidb, 10 years ago

Core Web Server that connects to the Kinect device

File size: 6.2 KB
Line 
1// -----------------------------------------------------------------------
2// <copyright file="SkeletonStreamHandler.cs" company="Microsoft">
3// Copyright (c) Microsoft Corporation. All rights reserved.
4// </copyright>
5// -----------------------------------------------------------------------
6
7namespace Microsoft.Samples.Kinect.Webserver.Sensor
8{
9 using System;
10 using System.Collections.Generic;
11
12 using Microsoft.Kinect;
13 using Microsoft.Samples.Kinect.Webserver.Sensor.Serialization;
14
15 /// <summary>
16 /// Implementation of ISensorStreamHandler that exposes skeleton streams.
17 /// </summary>
18 public class SkeletonStreamHandler : SensorStreamHandlerBase
19 {
20 /// <summary>
21 /// JSON name of skeleton stream.
22 /// </summary>
23 internal const string SkeletonStreamName = "skeleton";
24
25 /// <summary>
26 /// Context that allows this stream handler to communicate with its owner.
27 /// </summary>
28 private readonly SensorStreamHandlerContext ownerContext;
29
30 /// <summary>
31 /// Serializable skeleton stream message, reused as skeleton frames arrive.
32 /// </summary>
33 private readonly SkeletonStreamMessage skeletonStreamMessage = new SkeletonStreamMessage { stream = SkeletonStreamName };
34
35 /// <summary>
36 /// true if skeleton stream is enabled. Skeleton stream is disabled by default.
37 /// </summary>
38 private bool skeletonIsEnabled;
39
40 /// <summary>
41 /// Keep track if we're in the middle of processing an skeleton frame.
42 /// </summary>
43 private bool isProcessingSkeletonFrame;
44
45 /// <summary>
46 /// Initializes a new instance of the <see cref="SkeletonStreamHandler"/> class
47 /// and associates it with a context that allows it to communicate with its owner.
48 /// </summary>
49 /// <param name="ownerContext">
50 /// An instance of <see cref="SensorStreamHandlerContext"/> class.
51 /// </param>
52 internal SkeletonStreamHandler(SensorStreamHandlerContext ownerContext)
53 {
54 this.ownerContext = ownerContext;
55
56 this.AddStreamConfiguration(SkeletonStreamName, new StreamConfiguration(this.GetProperties, this.SetProperty));
57 }
58
59 /// <summary>
60 /// Process data from one Kinect skeleton frame.
61 /// </summary>
62 /// <param name="skeletons">
63 /// Kinect skeleton data.
64 /// </param>
65 /// <param name="skeletonFrame">
66 /// <see cref="SkeletonFrame"/> from which we obtained skeleton data.
67 /// </param>
68 public override void ProcessSkeleton(Skeleton[] skeletons, SkeletonFrame skeletonFrame)
69 {
70 if (skeletonFrame == null)
71 {
72 throw new ArgumentNullException("skeletonFrame");
73 }
74
75 this.ProcessSkeletonAsync(skeletons, skeletonFrame.Timestamp);
76 }
77
78 /// <summary>
79 /// Process skeletons in async mode.
80 /// </summary>
81 /// <param name="skeletons">
82 /// Kinect skeleton data.
83 /// </param>
84 /// <param name="timestamp">
85 /// Timestamp of <see cref="SkeletonFrame"/> from which we obtained skeleton data.
86 /// </param>
87 internal async void ProcessSkeletonAsync(Skeleton[] skeletons, long timestamp)
88 {
89 if (!this.skeletonIsEnabled)
90 {
91 return;
92 }
93
94 if (this.isProcessingSkeletonFrame)
95 {
96 // Re-entered SkeletonFrameReadyAsync while a previous frame is already being processed.
97 // Just ignore new frames until the current one finishes processing.
98 return;
99 }
100
101 this.isProcessingSkeletonFrame = true;
102
103 try
104 {
105 if (skeletons != null)
106 {
107 this.skeletonStreamMessage.timestamp = timestamp;
108 this.skeletonStreamMessage.UpdateSkeletons(skeletons);
109
110 await this.ownerContext.SendStreamMessageAsync(this.skeletonStreamMessage);
111 }
112 }
113 finally
114 {
115 this.isProcessingSkeletonFrame = false;
116 }
117 }
118
119 /// <summary>
120 /// Gets a skeleton stream property value.
121 /// </summary>
122 /// <param name="propertyMap">
123 /// Property name->value map where property values should be set.
124 /// </param>
125 private void GetProperties(Dictionary<string, object> propertyMap)
126 {
127 propertyMap.Add(KinectRequestHandler.EnabledPropertyName, this.skeletonIsEnabled);
128 }
129
130 /// <summary>
131 /// Set a skeleton stream property value.
132 /// </summary>
133 /// <param name="propertyName">
134 /// Name of property to set.
135 /// </param>
136 /// <param name="propertyValue">
137 /// Property value to set.
138 /// </param>
139 /// <returns>
140 /// null if property setting was successful, error message otherwise.
141 /// </returns>
142 private string SetProperty(string propertyName, object propertyValue)
143 {
144 bool recognized = true;
145
146 if (propertyValue == null)
147 {
148 // None of the skeleton stream properties accept a null value
149 return Properties.Resources.PropertyValueInvalidFormat;
150 }
151
152 try
153 {
154 switch (propertyName)
155 {
156 case KinectRequestHandler.EnabledPropertyName:
157 this.skeletonIsEnabled = (bool)propertyValue;
158 break;
159
160 default:
161 recognized = false;
162 break;
163 }
164 }
165 catch (InvalidCastException)
166 {
167 return Properties.Resources.PropertyValueInvalidFormat;
168 }
169
170 if (!recognized)
171 {
172 return Properties.Resources.PropertyNameUnrecognized;
173 }
174
175 return null;
176 }
177 }
178}
Note: See TracBrowser for help on using the repository browser.