Skip to content

Commit

Permalink
Fix ImageLoading to use new smart callbacks
Browse files Browse the repository at this point in the history
New start callbacks for Image were introduced.
Fix these smart callbacks ("load,ready", "load,error") are used
instead of "preloaded" evas callback.

Change-Id: Ia78fb25f29f926045f2ef4c5aa2d457ff9821ff8
  • Loading branch information
WonyoungChoi committed Oct 20, 2016
1 parent 3859563 commit d5858a0
Show file tree
Hide file tree
Showing 24 changed files with 867 additions and 555 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true

[*]
end_of_line = lf

[*.{cs,xaml}]
indent_style = space
indent_size = 4
14 changes: 14 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Set default behaviour, in case users don't have core.autocrlf set.
* text=auto

# Explicitly declare text files we want to always be normalized and converted
# to native line endings on checkout.
*.cs text

# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.jpeg binary
2 changes: 1 addition & 1 deletion packaging/elm-sharp.spec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Name: elm-sharp
Summary: C# Binding for Elementary
Version: 1.0.8
Version: 1.0.9
Release: 1
Group: Development/Libraries
License: Apache-2.0
Expand Down
328 changes: 164 additions & 164 deletions src/ElmSharp/ElmSharp.Net45.csproj

Large diffs are not rendered by default.

346 changes: 173 additions & 173 deletions src/ElmSharp/ElmSharp.csproj

Large diffs are not rendered by default.

190 changes: 116 additions & 74 deletions src/ElmSharp/ElmSharp/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ public class Image : Widget
public Image(EvasObject parent) : base(parent)
{
_clicked = new Interop.SmartEvent(this, Handle, "clicked");
_clicked.On += (s, e) =>
{
Clicked?.Invoke(this, EventArgs.Empty);
};
_clicked.On += (s, e) => Clicked?.Invoke(this, EventArgs.Empty);
}

public event EventHandler Clicked;
Expand Down Expand Up @@ -193,7 +190,6 @@ public bool IsOpaque
}
}


public ImageOrientation Orientation
{
get
Expand All @@ -206,44 +202,65 @@ public ImageOrientation Orientation
}
}

public void Load(string file)
public bool Load(string file)
{
if (file == null)
throw new ArgumentNullException("file");

Interop.Elementary.elm_image_async_open_set(Handle, false);
Interop.Elementary.elm_image_preload_disabled_set(Handle, true);
bool ret = Interop.Elementary.elm_image_file_set(Handle, file, null);
if (!ret)
{
throw new InvalidOperationException("Failed to set file to Image");
}
return Interop.Elementary.elm_image_file_set(Handle, file, null);
}

LoadingCompleted?.Invoke(this, EventArgs.Empty);
public bool Load(Uri uri)
{
if (uri == null)
throw new ArgumentNullException("uri");

return Load(uri.IsFile ? uri.LocalPath : uri.AbsoluteUri);
}

[CLSCompliant(false)]
public unsafe void Load(byte* img, long size)
[Obsolete("This method will be removed. Use Load(Stream stream) instead.")]
public unsafe bool Load(byte* img, long size)
{
bool ret = Interop.Elementary.elm_image_memfile_set(Handle, img, size, IntPtr.Zero, IntPtr.Zero);
if (!ret)
{
throw new InvalidOperationException("Failed to set memory buffer to Image");
}
if (img == null)
throw new ArgumentNullException("img");

LoadingCompleted?.Invoke(this, EventArgs.Empty);
Interop.Elementary.elm_image_async_open_set(Handle, false);
Interop.Elementary.elm_image_preload_disabled_set(Handle, true);
return Interop.Elementary.elm_image_memfile_set(Handle, img, size, IntPtr.Zero, IntPtr.Zero);
}

public void LoadAsync(Uri uri)
public bool Load(Stream stream)
{
if (uri.IsFile)
LoadFromFileAsync(uri.LocalPath);
else
LoadFromUriAsync(uri.AbsoluteUri);
if (stream == null)
throw new ArgumentNullException("stream");

Interop.Elementary.elm_image_async_open_set(Handle, false);
Interop.Elementary.elm_image_preload_disabled_set(Handle, true);
MemoryStream memstream = new MemoryStream();
stream.CopyTo(memstream);
unsafe
{
byte[] dataArr = memstream.ToArray();
fixed (byte* data = &dataArr[0])
{
return Interop.Elementary.elm_image_memfile_set(Handle, data, dataArr.Length, IntPtr.Zero, IntPtr.Zero);
}
}
}

public async Task<bool> LoadAsync(Stream stream, CancellationToken cancellationToken)
public Task<bool> LoadAsync(string file, CancellationToken cancellationToken = default(CancellationToken))
{
var tcs = new TaskCompletionSource<bool>();
if (file == null)
throw new ArgumentNullException("file");

Interop.Elementary.elm_image_async_open_set(Handle, true);
Interop.Elementary.elm_image_preload_disabled_set(Handle, false);

var tcs = new TaskCompletionSource<bool>();

cancellationToken.Register(() =>
{
if (tcs != null && !tcs.Task.IsCompleted)
Expand All @@ -252,82 +269,107 @@ public async Task<bool> LoadAsync(Stream stream, CancellationToken cancellationT
}
});

MemoryStream memstream = new MemoryStream();
await stream.CopyToAsync(memstream);

unsafe
Interop.SmartEvent loadReady = new Interop.SmartEvent(this, Handle, "load,ready");
loadReady.On += (s, e) =>
{
byte[] dataArr = memstream.ToArray();
fixed (byte* data = &dataArr[0])
loadReady.Dispose();
LoadingCompleted?.Invoke(this, EventArgs.Empty);
if (tcs != null && !tcs.Task.IsCompleted)
{
bool ret = Interop.Elementary.elm_image_memfile_set(Handle, data, dataArr.Length, IntPtr.Zero, IntPtr.Zero);
if (!ret)
{
return false;
}
tcs.SetResult(true);
}
}
};

var evasObj = Interop.Elementary.elm_image_object_get(Handle);
Interop.EvasObjectEvent preloadedCallback = new Interop.EvasObjectEvent(this, evasObj, Interop.Evas.ObjectCallbackType.ImagePreloaded);
preloadedCallback.On += (s, e) =>
Interop.SmartEvent loadError = new Interop.SmartEvent(this, Handle, "load,error");
loadError.On += (s, e) =>
{
preloadedCallback.Dispose();
loadError.Dispose();
LoadingFailed?.Invoke(this, EventArgs.Empty);
if (tcs != null && !tcs.Task.IsCompleted)
{
tcs.SetResult(true);
tcs.SetResult(false);
}
};

return await tcs.Task;
}
bool ret = Interop.Elementary.elm_image_file_set(Handle, file, null);
if (!ret)
{
throw new InvalidOperationException("Failed to set file to Image");
}

return tcs.Task;
}

protected override IntPtr CreateHandle(EvasObject parent)
public Task<bool> LoadAsync(Uri uri, CancellationToken cancellationToken = default(CancellationToken))
{
return Interop.Elementary.elm_image_add(parent.Handle);
if (uri == null)
throw new ArgumentNullException("uri");

return LoadAsync(uri.IsFile ? uri.LocalPath : uri.AbsoluteUri, cancellationToken);
}

void LoadFromFileAsync(string file)
public async Task<bool> LoadAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken))
{
if (stream == null)
throw new ArgumentNullException("stream");

Interop.Elementary.elm_image_async_open_set(Handle, true);
Interop.Elementary.elm_image_preload_disabled_set(Handle, false);
bool ret = Interop.Elementary.elm_image_file_set(Handle, file, null);
if (!ret)
{
throw new InvalidOperationException("Failed to set file to Image");
}

// FIXME: Due to the bug of EFL, the preload callback should be set after elm_image_file_set().
var evasObj = Interop.Elementary.elm_image_object_get(Handle);
var preloadedCallback = new Interop.EvasObjectEvent(this, evasObj, Interop.Evas.ObjectCallbackType.ImagePreloaded);
preloadedCallback.On += (s, e) =>
var tcs = new TaskCompletionSource<bool>();

cancellationToken.Register(() =>
{
preloadedCallback.Dispose();
LoadingCompleted?.Invoke(this, EventArgs.Empty);
};
}
if (tcs != null && !tcs.Task.IsCompleted)
{
tcs.SetCanceled();
}
});

void LoadFromUriAsync(string path)
{
Interop.Elementary.elm_image_preload_disabled_set(Handle, true);
Interop.SmartEvent downloadDone = new Interop.SmartEvent(this, Handle, "download,done");
downloadDone.On += (s, e) =>
Interop.SmartEvent loadReady = new Interop.SmartEvent(this, Handle, "load,ready");
loadReady.On += (s, e) =>
{
downloadDone.Dispose();
loadReady.Dispose();
LoadingCompleted?.Invoke(this, EventArgs.Empty);
if (tcs != null && !tcs.Task.IsCompleted)
{
tcs.SetResult(true);
}
};
Interop.SmartEvent downloadError = new Interop.SmartEvent(this, Handle, "download,error");
downloadError.On += (s, e) =>

Interop.SmartEvent loadError = new Interop.SmartEvent(this, Handle, "load,error");
loadError.On += (s, e) =>
{
downloadError.Dispose();
loadError.Dispose();
LoadingFailed?.Invoke(this, EventArgs.Empty);
if (tcs != null && !tcs.Task.IsCompleted)
{
tcs.SetResult(false);
}
};

bool ret = Interop.Elementary.elm_image_file_set(Handle, path, null);
if (!ret)
MemoryStream memstream = new MemoryStream();
await stream.CopyToAsync(memstream);

unsafe
{
throw new InvalidOperationException("Failed to set file to Image");
byte[] dataArr = memstream.ToArray();
fixed (byte* data = &dataArr[0])
{
bool ret = Interop.Elementary.elm_image_memfile_set(Handle, data, dataArr.Length, IntPtr.Zero, IntPtr.Zero);
if (!ret)
{
return false;
}
}
}

return await tcs.Task;
}

protected override IntPtr CreateHandle(EvasObject parent)
{
return Interop.Elementary.elm_image_add(parent.Handle);
}
}

Expand Down
5 changes: 4 additions & 1 deletion src/ElmSharp/Interop/Interop.Elementary.Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ internal static partial class Elementary
[DllImport(Libraries.Elementary)]
internal static extern IntPtr elm_image_add(IntPtr obj);

[DllImport(Libraries.Elementary)]
internal static extern void elm_image_async_open_set(IntPtr obj, bool async);

[DllImport(Libraries.Elementary)]
internal static extern IntPtr elm_image_object_get(IntPtr obj);

Expand All @@ -28,7 +31,7 @@ internal static partial class Elementary
[DllImport(Libraries.Elementary)]
internal static extern bool elm_image_file_set(IntPtr obj, string file, string group);

[DllImport(Libraries.Elementary)]
[DllImport(Libraries.Elementary, EntryPoint = "elm_image_file_get")]
internal static extern void _elm_image_file_get(IntPtr obj, out IntPtr file, out IntPtr group);
internal static string elm_image_file_get(IntPtr obj)
{
Expand Down
Loading

0 comments on commit d5858a0

Please sign in to comment.