Skip to content

Commit 4a3d513

Browse files
Merge pull request #11 from hiddenswitch/apitweaks
Updates for next version
2 parents 15cc12e + b21e550 commit 4a3d513

File tree

10 files changed

+289
-92
lines changed

10 files changed

+289
-92
lines changed

CoroutineHost.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
using System;
23

34
public class CoroutineHost : MonoSingleton<CoroutineHost>
@@ -6,13 +7,15 @@ public CoroutineHost ()
67
{
78
}
89

9-
void OnApplicationQuit() {
10+
protected override void OnApplicationQuit ()
11+
{
1012
base.OnApplicationQuit ();
1113
try {
12-
Meteor.LiveData.Instance.Close();
14+
Meteor.LiveData.Instance.Close ();
15+
#pragma warning disable 0168
1316
} catch (Exception e) {
14-
1517
}
18+
#pragma warning restore 0168
1619
}
1720
}
1821

JsonFx/TypeCoercionUtility.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2626
THE SOFTWARE.
2727
2828
\*---------------------------------------------------------------------------------*/
29+
2930
#endregion License
3031

3132
using System;
3233
using System.Collections;
3334
using System.Collections.Generic;
35+
using System.Runtime.Serialization;
3436
using System.ComponentModel;
3537
using System.Globalization;
3638
using System.Reflection;
@@ -127,23 +129,33 @@ internal object ProcessTypeHint(
127129

128130
internal Object InstantiateObject(Type objectType, out Dictionary<string, MemberInfo> memberMap)
129131
{
130-
if (objectType.IsInterface || objectType.IsAbstract || objectType.IsValueType)
132+
if (objectType.IsInterface || objectType.IsAbstract)
131133
{
132134
throw new JsonTypeCoercionException(
133135
String.Format(TypeCoercionUtility.ErrorCannotInstantiate, objectType.FullName));
134136
}
135137

136138
ConstructorInfo ctor = objectType.GetConstructor(Type.EmptyTypes);
139+
Object result = null;
140+
137141
if (ctor == null)
138142
{
139-
throw new JsonTypeCoercionException(
140-
String.Format(TypeCoercionUtility.ErrorDefaultCtor, objectType.FullName));
143+
if (objectType.IsValueType) {
144+
try {
145+
result = FormatterServices.GetUninitializedObject(objectType);
146+
} catch {
147+
throw new JsonTypeCoercionException(
148+
String.Format(TypeCoercionUtility.ErrorCannotInstantiate, objectType.FullName));
149+
}
150+
} else {
151+
throw new JsonTypeCoercionException(
152+
String.Format(TypeCoercionUtility.ErrorDefaultCtor, objectType.FullName));
153+
}
141154
}
142-
Object result;
143155
try
144156
{
145157
// always try-catch Invoke() to expose real exception
146-
result = ctor.Invoke(null);
158+
result = result ?? ctor.Invoke(null);
147159
}
148160
catch (TargetInvocationException ex)
149161
{
@@ -710,10 +722,12 @@ internal static IEnumerator GetEnumerator(object enumerable)
710722
try {
711723
enumerator = (IEnumerator)method.Invoke (enumerable, null);
712724
return enumerator;
725+
#pragma warning disable 0168
713726
} catch (Exception e) {
714727
// TODO: Define what to do in the case of an exception here.
715728
return null;
716729
}
730+
#pragma warning restore 0168
717731
}
718732
}
719733
}

LiveData/Collection.cs

Lines changed: 81 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -8,71 +8,6 @@
88

99
namespace Meteor
1010
{
11-
public interface ICollection : System.Collections.ICollection
12-
{
13-
/// <summary>
14-
/// Add a record before another record in order.
15-
/// </summary>
16-
/// <param name="id">Record ID.</param>
17-
/// <param name="before">The ID of the record to insert before.</param>
18-
/// <param name="record">The record.</param>
19-
void AddedBefore (string id, string before, object record);
20-
21-
/// <summary>
22-
/// Add the serialized message to the collection.
23-
/// </summary>
24-
/// <param name="addedMessage">Added message.</param>
25-
void Added (string addedMessage);
26-
27-
/// <summary>
28-
/// Add the record to the collection.
29-
/// </summary>
30-
/// <param name="record">Record.</param>
31-
void Added (object record);
32-
33-
/// <summary>
34-
/// Add the record to the collection with the specified ID
35-
/// </summary>
36-
/// <param name="id">Identifier.</param>
37-
/// <param name="record">Record.</param>
38-
void Added (string id, object record);
39-
40-
/// <summary>
41-
/// Notify the collection that a record has changed.
42-
/// </summary>
43-
/// <param name="id">Record ID.</param>
44-
/// <param name="cleared">Fields that are now undefined.</param>
45-
/// <param name="fields">New values for fields of record.</param>
46-
void Changed (string id, string[] cleared, IDictionary fields);
47-
48-
/// <summary>
49-
/// Move a record before another record.
50-
/// </summary>
51-
/// <param name="id">ID of record.</param>
52-
/// <param name="before">ID of record to move before.</param>
53-
void MovedBefore (string id, string before);
54-
55-
/// <summary>
56-
/// Remove a record.
57-
/// </summary>
58-
/// <param name="id">Identifier.</param>
59-
void Removed (string id);
60-
61-
/// <summary>
62-
/// Collection name.
63-
/// </summary>
64-
/// <value>The name.</value>
65-
string Name {
66-
get;
67-
}
68-
69-
/// <summary>
70-
/// Record type.
71-
/// </summary>
72-
/// <value>The type of the collection.</value>
73-
Type CollectionType { get; }
74-
}
75-
7611
public class TemporaryCollection : Hashtable, Meteor.ICollection
7712
{
7813
public TemporaryCollection () : base ()
@@ -169,38 +104,105 @@ protected Collection () : base ()
169104
{
170105
}
171106

107+
/// <summary>
108+
/// Creates a new Mongo-style collection.
109+
/// Throws an exception if a collection with the given name already exists. If you want a way to get an
110+
/// existing collection instance if it already exists, use Collection&lt;TRecordType&gt;.Create(name)
111+
/// </summary>
112+
/// <param name="name">Name. If null, returns a local-only collection.</param>
113+
public Collection (string name) : base ()
114+
{
115+
var doesCollectionAlreadyExist = LiveData.Instance.Collections.Contains (name);
116+
var isNameEmpty = string.IsNullOrEmpty (name);
117+
var isCollectionTemporary = LiveData.Instance.Collections [name] as TemporaryCollection != null;
118+
if (!isNameEmpty
119+
&& doesCollectionAlreadyExist
120+
&& !isCollectionTemporary) {
121+
throw new ArgumentException (string.Format ("A collection with name {0} already exists", name));
122+
}
123+
124+
Collection<TRecordType>.Create (name, instance: this);
125+
}
126+
127+
public Cursor<TRecordType> Find (Func<TRecordType, bool> selector = null)
128+
{
129+
return new Cursor<TRecordType> (collection: this, selector: selector);
130+
}
131+
132+
public Cursor<TRecordType> Find (string id)
133+
{
134+
return new Cursor<TRecordType> (collection: this, id: id);
135+
}
136+
137+
public Cursor<TRecordType> Find (IEnumerable<string> ids)
138+
{
139+
return new Cursor<TRecordType> (collection: this, ids: ids);
140+
}
141+
142+
public TRecordType FindOne (string id)
143+
{
144+
return this [id];
145+
}
146+
147+
public TRecordType FindOne (Func<TRecordType, bool> selector = null)
148+
{
149+
selector = selector ?? delegate(TRecordType arg) {
150+
return true;
151+
};
152+
153+
foreach (var record in this) {
154+
if (selector (record)) {
155+
return record;
156+
}
157+
}
158+
return null;
159+
}
160+
172161
public static Collection<TRecordType> Create (string name)
173162
{
163+
return Create (name, new Collection<TRecordType> ());
164+
}
165+
166+
protected static Collection<TRecordType> Create (string name, Collection<TRecordType> instance)
167+
{
168+
instance = instance ?? new Collection<TRecordType> ();
174169
if (string.IsNullOrEmpty (name)) {
175-
return new Collection<TRecordType> ();
170+
return instance;
176171
}
177172

178173
// Check if we already have this collection defined, otherwise make it
179174
if (!LiveData.Instance.Collections.Contains (name)) {
180-
LiveData.Instance.Collections.Add (new Collection<TRecordType> () { name = name } as ICollection);
175+
instance.name = name;
176+
LiveData.Instance.Collections.Add (instance as ICollection);
181177
}
182178

183179
var collection = LiveData.Instance.Collections [name] as Collection<TRecordType>;
184180

185181
// The collection may already exist, but it may be of the wrong type
186182
if (collection == null) {
187183
// Convert the collection to the requested type
188-
var oldCollection = LiveData.Instance.Collections [name];
189-
var typedCollection = new Collection<TRecordType> ();
190-
typedCollection.name = name;
191-
foreach (DictionaryEntry doc in oldCollection) {
192-
var value = doc.Value.Coerce<TRecordType> ();
193-
value._id = (string)doc.Key;
194-
typedCollection.Add (value);
195-
}
196-
197-
LiveData.Instance.Collections.Remove (name);
198-
LiveData.Instance.Collections.Add (typedCollection);
199-
collection = typedCollection;
184+
collection = Convert (name, instance);
200185
}
186+
201187
return collection;
202188
}
203189

190+
protected static Collection<TRecordType> Convert (string name, Collection<TRecordType> instance)
191+
{
192+
var oldCollection = LiveData.Instance.Collections [name];
193+
var typedCollection = instance ?? new Collection<TRecordType> ();
194+
typedCollection.name = name;
195+
foreach (DictionaryEntry doc in oldCollection) {
196+
var value = doc.Value.Coerce<TRecordType> ();
197+
value._id = (string)doc.Key;
198+
typedCollection.Add (value);
199+
}
200+
201+
LiveData.Instance.Collections.Remove (name);
202+
LiveData.Instance.Collections.Add (typedCollection);
203+
return typedCollection;
204+
}
205+
204206
protected override string GetKeyForItem (TRecordType item)
205207
{
206208
return item._id;

LiveData/Cursor.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Collections.ObjectModel;
5+
using System.Reflection;
6+
using JsonFx.Json;
7+
using Meteor.Extensions;
8+
9+
namespace Meteor
10+
{
11+
public class Cursor<TRecordType>
12+
where TRecordType : MongoDocument, new()
13+
{
14+
15+
public Collection<TRecordType> collection {
16+
get;
17+
protected set;
18+
}
19+
20+
public Func<TRecordType, bool> selector {
21+
get;
22+
protected set;
23+
}
24+
25+
public IEnumerable<string> ids {
26+
get;
27+
protected set;
28+
}
29+
30+
public Cursor (Collection<TRecordType> collection, Func<TRecordType, bool> selector = null)
31+
{
32+
this.collection = collection;
33+
this.selector = selector ?? SelectAll;
34+
}
35+
36+
public Cursor (Collection<TRecordType> collection, string id)
37+
{
38+
this.collection = collection;
39+
this.ids = new string[] { id };
40+
}
41+
42+
public Cursor (Collection<TRecordType> collection, IEnumerable<string> ids)
43+
{
44+
this.collection = collection;
45+
this.ids = ids;
46+
}
47+
48+
public Observe<TRecordType> Observe (Action<string,TRecordType> added = null, Action<string,TRecordType,IDictionary,string[]> changed = null, Action<string> removed = null)
49+
{
50+
return new Observe<TRecordType> (collection: this.collection, added: added, changed: changed, removed: removed, selector: selector);
51+
}
52+
53+
public IEnumerable<TRecordType> Fetch ()
54+
{
55+
if (ids == null) {
56+
foreach (var record in collection) {
57+
if (selector (record)) {
58+
yield return record;
59+
}
60+
}
61+
yield break;
62+
}
63+
64+
foreach (var id in ids) {
65+
yield return collection [id];
66+
}
67+
68+
yield break;
69+
}
70+
71+
private bool SelectAll (TRecordType record)
72+
{
73+
return true;
74+
}
75+
}
76+
}

LiveData/Cursor.cs.meta

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)