Skip to content

Commit

Permalink
Merge pull request #11 from hiddenswitch/apitweaks
Browse files Browse the repository at this point in the history
Updates for next version
  • Loading branch information
doctorpangloss committed Feb 12, 2016
2 parents 15cc12e + b21e550 commit 4a3d513
Show file tree
Hide file tree
Showing 10 changed files with 289 additions and 92 deletions.
9 changes: 6 additions & 3 deletions CoroutineHost.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

using System;

public class CoroutineHost : MonoSingleton<CoroutineHost>
Expand All @@ -6,13 +7,15 @@ public CoroutineHost ()
{
}

void OnApplicationQuit() {
protected override void OnApplicationQuit ()
{
base.OnApplicationQuit ();
try {
Meteor.LiveData.Instance.Close();
Meteor.LiveData.Instance.Close ();
#pragma warning disable 0168
} catch (Exception e) {

}
#pragma warning restore 0168
}
}

24 changes: 19 additions & 5 deletions JsonFx/TypeCoercionUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
\*---------------------------------------------------------------------------------*/

#endregion License

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
Expand Down Expand Up @@ -127,23 +129,33 @@ internal object ProcessTypeHint(

internal Object InstantiateObject(Type objectType, out Dictionary<string, MemberInfo> memberMap)
{
if (objectType.IsInterface || objectType.IsAbstract || objectType.IsValueType)
if (objectType.IsInterface || objectType.IsAbstract)
{
throw new JsonTypeCoercionException(
String.Format(TypeCoercionUtility.ErrorCannotInstantiate, objectType.FullName));
}

ConstructorInfo ctor = objectType.GetConstructor(Type.EmptyTypes);
Object result = null;

if (ctor == null)
{
throw new JsonTypeCoercionException(
String.Format(TypeCoercionUtility.ErrorDefaultCtor, objectType.FullName));
if (objectType.IsValueType) {
try {
result = FormatterServices.GetUninitializedObject(objectType);
} catch {
throw new JsonTypeCoercionException(
String.Format(TypeCoercionUtility.ErrorCannotInstantiate, objectType.FullName));
}
} else {
throw new JsonTypeCoercionException(
String.Format(TypeCoercionUtility.ErrorDefaultCtor, objectType.FullName));
}
}
Object result;
try
{
// always try-catch Invoke() to expose real exception
result = ctor.Invoke(null);
result = result ?? ctor.Invoke(null);
}
catch (TargetInvocationException ex)
{
Expand Down Expand Up @@ -710,10 +722,12 @@ internal static IEnumerator GetEnumerator(object enumerable)
try {
enumerator = (IEnumerator)method.Invoke (enumerable, null);
return enumerator;
#pragma warning disable 0168
} catch (Exception e) {
// TODO: Define what to do in the case of an exception here.
return null;
}
#pragma warning restore 0168
}
}
}
160 changes: 81 additions & 79 deletions LiveData/Collection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,71 +8,6 @@

namespace Meteor
{
public interface ICollection : System.Collections.ICollection
{
/// <summary>
/// Add a record before another record in order.
/// </summary>
/// <param name="id">Record ID.</param>
/// <param name="before">The ID of the record to insert before.</param>
/// <param name="record">The record.</param>
void AddedBefore (string id, string before, object record);

/// <summary>
/// Add the serialized message to the collection.
/// </summary>
/// <param name="addedMessage">Added message.</param>
void Added (string addedMessage);

/// <summary>
/// Add the record to the collection.
/// </summary>
/// <param name="record">Record.</param>
void Added (object record);

/// <summary>
/// Add the record to the collection with the specified ID
/// </summary>
/// <param name="id">Identifier.</param>
/// <param name="record">Record.</param>
void Added (string id, object record);

/// <summary>
/// Notify the collection that a record has changed.
/// </summary>
/// <param name="id">Record ID.</param>
/// <param name="cleared">Fields that are now undefined.</param>
/// <param name="fields">New values for fields of record.</param>
void Changed (string id, string[] cleared, IDictionary fields);

/// <summary>
/// Move a record before another record.
/// </summary>
/// <param name="id">ID of record.</param>
/// <param name="before">ID of record to move before.</param>
void MovedBefore (string id, string before);

/// <summary>
/// Remove a record.
/// </summary>
/// <param name="id">Identifier.</param>
void Removed (string id);

/// <summary>
/// Collection name.
/// </summary>
/// <value>The name.</value>
string Name {
get;
}

/// <summary>
/// Record type.
/// </summary>
/// <value>The type of the collection.</value>
Type CollectionType { get; }
}

public class TemporaryCollection : Hashtable, Meteor.ICollection
{
public TemporaryCollection () : base ()
Expand Down Expand Up @@ -169,38 +104,105 @@ protected Collection () : base ()
{
}

/// <summary>
/// Creates a new Mongo-style collection.
/// Throws an exception if a collection with the given name already exists. If you want a way to get an
/// existing collection instance if it already exists, use Collection&lt;TRecordType&gt;.Create(name)
/// </summary>
/// <param name="name">Name. If null, returns a local-only collection.</param>
public Collection (string name) : base ()
{
var doesCollectionAlreadyExist = LiveData.Instance.Collections.Contains (name);
var isNameEmpty = string.IsNullOrEmpty (name);
var isCollectionTemporary = LiveData.Instance.Collections [name] as TemporaryCollection != null;
if (!isNameEmpty
&& doesCollectionAlreadyExist
&& !isCollectionTemporary) {
throw new ArgumentException (string.Format ("A collection with name {0} already exists", name));
}

Collection<TRecordType>.Create (name, instance: this);
}

public Cursor<TRecordType> Find (Func<TRecordType, bool> selector = null)
{
return new Cursor<TRecordType> (collection: this, selector: selector);
}

public Cursor<TRecordType> Find (string id)
{
return new Cursor<TRecordType> (collection: this, id: id);
}

public Cursor<TRecordType> Find (IEnumerable<string> ids)
{
return new Cursor<TRecordType> (collection: this, ids: ids);
}

public TRecordType FindOne (string id)
{
return this [id];
}

public TRecordType FindOne (Func<TRecordType, bool> selector = null)
{
selector = selector ?? delegate(TRecordType arg) {
return true;
};

foreach (var record in this) {
if (selector (record)) {
return record;
}
}
return null;
}

public static Collection<TRecordType> Create (string name)
{
return Create (name, new Collection<TRecordType> ());
}

protected static Collection<TRecordType> Create (string name, Collection<TRecordType> instance)
{
instance = instance ?? new Collection<TRecordType> ();
if (string.IsNullOrEmpty (name)) {
return new Collection<TRecordType> ();
return instance;
}

// Check if we already have this collection defined, otherwise make it
if (!LiveData.Instance.Collections.Contains (name)) {
LiveData.Instance.Collections.Add (new Collection<TRecordType> () { name = name } as ICollection);
instance.name = name;
LiveData.Instance.Collections.Add (instance as ICollection);
}

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

// The collection may already exist, but it may be of the wrong type
if (collection == null) {
// Convert the collection to the requested type
var oldCollection = LiveData.Instance.Collections [name];
var typedCollection = new Collection<TRecordType> ();
typedCollection.name = name;
foreach (DictionaryEntry doc in oldCollection) {
var value = doc.Value.Coerce<TRecordType> ();
value._id = (string)doc.Key;
typedCollection.Add (value);
}

LiveData.Instance.Collections.Remove (name);
LiveData.Instance.Collections.Add (typedCollection);
collection = typedCollection;
collection = Convert (name, instance);
}

return collection;
}

protected static Collection<TRecordType> Convert (string name, Collection<TRecordType> instance)
{
var oldCollection = LiveData.Instance.Collections [name];
var typedCollection = instance ?? new Collection<TRecordType> ();
typedCollection.name = name;
foreach (DictionaryEntry doc in oldCollection) {
var value = doc.Value.Coerce<TRecordType> ();
value._id = (string)doc.Key;
typedCollection.Add (value);
}

LiveData.Instance.Collections.Remove (name);
LiveData.Instance.Collections.Add (typedCollection);
return typedCollection;
}

protected override string GetKeyForItem (TRecordType item)
{
return item._id;
Expand Down
76 changes: 76 additions & 0 deletions LiveData/Cursor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
using JsonFx.Json;
using Meteor.Extensions;

namespace Meteor
{
public class Cursor<TRecordType>
where TRecordType : MongoDocument, new()
{

public Collection<TRecordType> collection {
get;
protected set;
}

public Func<TRecordType, bool> selector {
get;
protected set;
}

public IEnumerable<string> ids {
get;
protected set;
}

public Cursor (Collection<TRecordType> collection, Func<TRecordType, bool> selector = null)
{
this.collection = collection;
this.selector = selector ?? SelectAll;
}

public Cursor (Collection<TRecordType> collection, string id)
{
this.collection = collection;
this.ids = new string[] { id };
}

public Cursor (Collection<TRecordType> collection, IEnumerable<string> ids)
{
this.collection = collection;
this.ids = ids;
}

public Observe<TRecordType> Observe (Action<string,TRecordType> added = null, Action<string,TRecordType,IDictionary,string[]> changed = null, Action<string> removed = null)
{
return new Observe<TRecordType> (collection: this.collection, added: added, changed: changed, removed: removed, selector: selector);
}

public IEnumerable<TRecordType> Fetch ()
{
if (ids == null) {
foreach (var record in collection) {
if (selector (record)) {
yield return record;
}
}
yield break;
}

foreach (var id in ids) {
yield return collection [id];
}

yield break;
}

private bool SelectAll (TRecordType record)
{
return true;
}
}
}
12 changes: 12 additions & 0 deletions LiveData/Cursor.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 4a3d513

Please sign in to comment.