Cleaned up item filtering and some other small todos.

This commit is contained in:
Patrick Simpson 2017-02-15 10:38:57 +01:00
parent 9e0603e22f
commit 10d2bd4d65
8 changed files with 94 additions and 41 deletions

View File

@ -321,24 +321,20 @@ namespace Acacia.Features.GAB
{ {
using (IFolder root = store.GetRootFolder()) using (IFolder root = store.GetRootFolder())
{ {
foreach (IFolder folder in root.GetSubFolders<IFolder>()) foreach (IFolder folder in root.GetSubFolders<IFolder>().DisposeEnum())
{ {
// TODO: let enumerator handle this try
using (folder)
{ {
try if (IsGABContactsFolder(folder))
{ {
if (IsGABContactsFolder(folder)) Logger.Instance.Debug(this, "FullResync: Deleting contacts folder: {0}", folder.Name);
{ folder.Delete();
Logger.Instance.Debug(this, "FullResync: Deleting contacts folder: {0}", folder.Name);
folder.Delete();
}
}
catch (System.Exception e)
{
Logger.Instance.Error(this, "FullResync: Exception deleting contacts folder: {0}", e);
} }
} }
catch (System.Exception e)
{
Logger.Instance.Error(this, "FullResync: Exception deleting contacts folder: {0}", e);
}
} }
} }
} }

View File

@ -200,24 +200,21 @@ namespace Acacia.Features.GAB
return; return;
// Process the messages // Process the messages
foreach (IItem item in Folder.Items) foreach (IZPushItem item in Folder.Items.Typed<IZPushItem>())
{ {
// TODO: make type-checking iterator? // Store the entry id to fetch again later, the item will be disposed
if (item is IZPushItem) string entryId = item.EntryID;
Logger.Instance.Trace(this, "Checking chunk: {0}", item.Subject);
if (_feature.ProcessItems2)
{ {
string entryId = item.EntryID; Tasks.Task(_feature, "ProcessChunk", () =>
Logger.Instance.Trace(this, "Checking chunk: {0}", item.Subject);
if (_feature.ProcessItems2)
{ {
Tasks.Task(_feature, "ProcessChunk", () => using (IItem item2 = Folder.GetItemById(entryId))
{ {
using (IItem item2 = Folder.GetItemById(entryId)) if (item2 != null)
{ ProcessMessage((IZPushItem)item2);
if (item2 != null) }
ProcessMessage((IZPushItem)item2); });
}
});
}
} }
} }
} }

View File

@ -25,6 +25,12 @@ namespace Acacia.Stubs
/// <returns>The current collection, which will be sorted</returns> /// <returns>The current collection, which will be sorted</returns>
IItems Sort(string field, bool descending); IItems Sort(string field, bool descending);
/// <summary>
/// Filters the items for a specific type.
/// </summary>
/// <returns>An enumerable for items of the specified type.</returns>
IEnumerable<T> Typed<T>() where T : IItem;
/// <summary> /// <summary>
/// Returns an events subscribption object. /// Returns an events subscribption object.
/// </summary> /// </summary>

View File

@ -46,7 +46,7 @@ namespace Acacia.Stubs.OutlookWrappers
public void Clear() public void Clear()
{ {
foreach(dynamic item in _item.Items.RawEnum()) foreach(dynamic item in _item.Items.ComEnum())
{ {
item.Delete(); item.Delete();
} }

View File

@ -207,7 +207,7 @@ namespace Acacia.Stubs.OutlookWrappers
where FolderType : IFolder where FolderType : IFolder
{ {
// Don't release the items, the wrapper manages them // Don't release the items, the wrapper manages them
foreach (NSOutlook.Folder folder in _item.Folders.RawEnum(false)) foreach (NSOutlook.Folder folder in _item.Folders.ComEnum(false))
{ {
yield return folder.Wrap<FolderType>(); yield return folder.Wrap<FolderType>();
}; };
@ -228,7 +228,7 @@ namespace Acacia.Stubs.OutlookWrappers
// to prevent exceptions in the log. // to prevent exceptions in the log.
// Don't release the items in RawEnum, they are release manually or handed to WrapFolders. // Don't release the items in RawEnum, they are release manually or handed to WrapFolders.
NSOutlook.Folder sub = null; NSOutlook.Folder sub = null;
foreach(NSOutlook.Folder folder in _item.Folders.RawEnum(false)) foreach(NSOutlook.Folder folder in _item.Folders.ComEnum(false))
{ {
if (folder.Name == name) if (folder.Name == name)
{ {

View File

@ -22,7 +22,7 @@ namespace Acacia.Stubs.OutlookWrappers
public IEnumerator<IFolder> GetEnumerator() public IEnumerator<IFolder> GetEnumerator()
{ {
// Don't release the items, the wrapper manages them // Don't release the items, the wrapper manages them
foreach (NSOutlook.Folder folder in _folder.RawItem.Folders.RawEnum(false)) foreach (NSOutlook.Folder folder in _folder.RawItem.Folders.ComEnum(false))
{ {
yield return folder.Wrap<IFolder>(); yield return folder.Wrap<IFolder>();
}; };
@ -31,7 +31,7 @@ namespace Acacia.Stubs.OutlookWrappers
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
{ {
// Don't release the items, the wrapper manages them // Don't release the items, the wrapper manages them
foreach (NSOutlook.Folder folder in _folder.RawItem.Folders.RawEnum(false)) foreach (NSOutlook.Folder folder in _folder.RawItem.Folders.ComEnum(false))
{ {
yield return folder.Wrap<IFolder>(); yield return folder.Wrap<IFolder>();
}; };

View File

@ -13,6 +13,7 @@ namespace Acacia.Stubs.OutlookWrappers
{ {
// Managed by the caller, not released here // Managed by the caller, not released here
private readonly FolderWrapper _folder; private readonly FolderWrapper _folder;
private string _field; private string _field;
private bool _descending; private bool _descending;
@ -28,6 +29,21 @@ namespace Acacia.Stubs.OutlookWrappers
return this; return this;
} }
public IEnumerable<T> Typed<T>() where T: IItem
{
foreach(IItem item in this)
{
if (typeof(T).IsInstanceOfType(item))
{
yield return (T)item;
}
else
{
item.Dispose();
}
}
}
private NSOutlook.Items GetItems() private NSOutlook.Items GetItems()
{ {
return _folder.RawItem.Items; return _folder.RawItem.Items;
@ -35,7 +51,7 @@ namespace Acacia.Stubs.OutlookWrappers
public IEnumerator<IItem> GetEnumerator() public IEnumerator<IItem> GetEnumerator()
{ {
return new ItemsEnumerator<IItem>(this, _field, _descending); return new ItemsEnumerator<IItem>(this);
} }
IEnumerator IEnumerable.GetEnumerator() IEnumerator IEnumerable.GetEnumerator()
@ -51,13 +67,15 @@ namespace Acacia.Stubs.OutlookWrappers
private IEnumerator _enum; private IEnumerator _enum;
private ItemType _last; private ItemType _last;
public ItemsEnumerator(ItemsWrapper items, string field, bool descending) : base(items.GetItems()) public ItemsEnumerator(ItemsWrapper items) : base(items.GetItems())
{ {
// TODO: can _items be released here already? // Apply any sort options
if (field != null) if (items._field != null)
{ {
this._item.Sort("[" + field + "]", descending); this._item.Sort("[" + items._field + "]", items._descending);
} }
// Get the enumerator
this._enum = _item.GetEnumerator(); this._enum = _item.GetEnumerator();
} }

View File

@ -45,7 +45,15 @@ namespace Acacia.Utils
return a.Equals(b); return a.Equals(b);
} }
public static IEnumerable<T> RawEnum<T>(this IEnumerable<T> source, bool releaseItems = true) #region Enumeration helpers
/// <summary>
/// Extension for a Com enumeration. Disposes the enumerated object and - optionally - the returned elements.
/// </summary>
/// <param name="source">The object to be enumerated. This will be released.</param>
/// <param name="releaseElements">If true (the default), elements will also be released.</param>
/// <returns></returns>
public static IEnumerable<T> ComEnum<T>(this IEnumerable<T> source, bool releaseElements = true)
{ {
foreach (T item in source) foreach (T item in source)
{ {
@ -55,14 +63,20 @@ namespace Acacia.Utils
} }
finally finally
{ {
if (releaseItems) if (releaseElements)
ComRelease.Release(item); ComRelease.Release(item);
} }
} }
ComRelease.Release(source); ComRelease.Release(source);
} }
public static IEnumerable RawEnum(this IEnumerable source, bool releaseItems = true) /// <summary>
/// Extension for a Com enumeration. Disposes the enumerated object and - optionally - the returned elements.
/// </summary>
/// <param name="source">The object to be enumerated. This will be released.</param>
/// <param name="releaseElements">If true (the default), elements will also be released.</param>
/// <returns></returns>
public static IEnumerable ComEnum(this IEnumerable source, bool releaseElements = true)
{ {
foreach (object item in source) foreach (object item in source)
{ {
@ -72,13 +86,35 @@ namespace Acacia.Utils
} }
finally finally
{ {
if (releaseItems) if (releaseElements)
ComRelease.Release(item); ComRelease.Release(item);
} }
} }
ComRelease.Release(source); ComRelease.Release(source);
} }
/// <summary>
/// Helper for enumeration that disposes the returned items. Note that source will not be disposed,
/// as that is normally done by foreach.
/// </summary>
public static IEnumerable<T> DisposeEnum<T>(this IEnumerable<T> source)
where T : IDisposable
{
foreach (T item in source)
{
try
{
yield return item;
}
finally
{
item.Dispose();
}
}
}
#endregion
public static void GarbageCollect() public static void GarbageCollect()
{ {
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)