0ef2d904ec9f671b7116e513638cd9151544a1bc
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / XamlBinding / ImageSource.cs
1 using System;
2 using System.IO;
3 using System.Reflection;
4 using System.Threading;
5 using System.Threading.Tasks;
6
7 namespace Tizen.NUI.Binding
8 {
9         [TypeConverter(typeof(ImageSourceConverter))]
10         internal abstract class ImageSource : Element
11         {
12                 readonly object _synchandle = new object();
13                 CancellationTokenSource _cancellationTokenSource;
14
15                 TaskCompletionSource<bool> _completionSource;
16
17                 readonly WeakEventManager _weakEventManager = new WeakEventManager();
18
19                 protected ImageSource()
20                 {
21                 }
22
23                 protected CancellationTokenSource CancellationTokenSource
24                 {
25                         get { return _cancellationTokenSource; }
26                         private set
27                         {
28                                 if (_cancellationTokenSource == value)
29                                         return;
30                                 if (_cancellationTokenSource != null)
31                                         _cancellationTokenSource.Cancel();
32                                 _cancellationTokenSource = value;
33                         }
34                 }
35
36                 bool IsLoading
37                 {
38                         get { return _cancellationTokenSource != null; }
39                 }
40
41                 public virtual Task<bool> Cancel()
42                 {
43                         if (!IsLoading)
44                                 return Task.FromResult(false);
45
46                         var tcs = new TaskCompletionSource<bool>();
47                         TaskCompletionSource<bool> original = Interlocked.CompareExchange(ref _completionSource, tcs, null);
48                         if (original == null)
49                         {
50                                 _cancellationTokenSource.Cancel();
51                         }
52                         else
53                                 tcs = original;
54
55                         return tcs.Task;
56                 }
57
58                 public static ImageSource FromFile(string file)
59                 {
60                         return new FileImageSource { File = file };
61                 }
62
63                 public static ImageSource FromResource(string resource, Type resolvingType)
64                 {
65                         return FromResource(resource, resolvingType.GetTypeInfo().Assembly);
66                 }
67
68                 public static ImageSource FromResource(string resource, Assembly sourceAssembly = null)
69                 {
70 #if NETSTANDARD2_0
71                         sourceAssembly = sourceAssembly ?? Assembly.GetCallingAssembly();
72 #else
73                         if (sourceAssembly == null)
74                         {
75                                 MethodInfo callingAssemblyMethod = typeof(Assembly).GetTypeInfo().GetDeclaredMethod("GetCallingAssembly");
76                                 if (callingAssemblyMethod != null)
77                                 {
78                                         sourceAssembly = (Assembly)callingAssemblyMethod.Invoke(null, new object[0]);
79                                 }
80                                 else
81                                 {
82                                         Internals.Log.Warning("Warning", "Can not find CallingAssembly, pass resolvingType to FromResource to ensure proper resolution");
83                                         return null;
84                                 }
85                         }
86 #endif
87                         return FromStream(() => sourceAssembly.GetManifestResourceStream(resource));
88                 }
89
90                 public static ImageSource FromStream(Func<Stream> stream)
91                 {
92                         // return new StreamImageSource { Stream = token => Task.Run(stream, token) };
93                         return null;
94                 }
95
96                 public static ImageSource FromUri(Uri uri)
97                 {
98                         if (!uri.IsAbsoluteUri)
99                                 throw new ArgumentException("uri is relative");
100                         // return new UriImageSource { Uri = uri };
101                         return null;
102                 }
103
104                 public static implicit operator ImageSource(string source)
105                 {
106                         Uri uri;
107                         return Uri.TryCreate(source, UriKind.Absolute, out uri) && uri.Scheme != "file" ? FromUri(uri) : FromFile(source);
108                 }
109
110                 public static implicit operator ImageSource(Uri uri)
111                 {
112                         if (!uri.IsAbsoluteUri)
113                                 throw new ArgumentException("uri is relative");
114                         return FromUri(uri);
115                 }
116
117                 protected void OnLoadingCompleted(bool cancelled)
118                 {
119                         if (!IsLoading || _completionSource == null)
120                                 return;
121
122                         TaskCompletionSource<bool> tcs = Interlocked.Exchange(ref _completionSource, null);
123                         if (tcs != null)
124                                 tcs.SetResult(cancelled);
125
126                         lock (_synchandle)
127                         {
128                                 CancellationTokenSource = null;
129                         }
130                 }
131
132                 protected void OnLoadingStarted()
133                 {
134                         lock (_synchandle)
135                         {
136                                 CancellationTokenSource = new CancellationTokenSource();
137                         }
138                 }
139
140                 protected void OnSourceChanged()
141                 {
142                         _weakEventManager.HandleEvent(this, EventArgs.Empty, nameof(SourceChanged));
143                 }
144
145                 internal event EventHandler SourceChanged
146                 {
147                         add { _weakEventManager.AddEventHandler(nameof(SourceChanged), value); }
148                         remove { _weakEventManager.RemoveEventHandler(nameof(SourceChanged), value); }
149                 }
150         }
151 }