[DllImport(Libraries.Application, EntryPoint = "app_control_create", CallingConvention = CallingConvention.Cdecl)]
internal static extern int Create(out SafeAppControlHandle handle);
- [DllImport(Libraries.Application, EntryPoint = "app_control_destroy", CallingConvention = CallingConvention.Cdecl)]
- private static extern int DangerousDestroy(IntPtr handle);
-
[DllImport(Libraries.Application, EntryPoint = "app_control_get_app_id", CallingConvention = CallingConvention.Cdecl)]
internal static extern int GetAppId(IntPtr app_control, out IntPtr app_id);
[DllImport(Libraries.Application, EntryPoint = "app_control_get_mime", CallingConvention = CallingConvention.Cdecl)]
internal static extern int GetMime(SafeAppControlHandle handle, out string mime);
+ [DllImport(Libraries.Application, EntryPoint = "app_control_destroy", CallingConvention = CallingConvention.Cdecl)]
+ private static extern int DangerousDestroy(IntPtr handle);
+
internal sealed class SafeAppControlHandle : SafeHandle
{
public SafeAppControlHandle() : base(IntPtr.Zero, true)
public override bool IsInvalid
{
- get { return handle == IntPtr.Zero; }
+ get { return this.handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
{
- DangerousDestroy(handle);
- SetHandle(IntPtr.Zero);
+ AppControl.DangerousDestroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
return true;
}
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void AppControlCallback(IntPtr appControl, IntPtr userData);
+ [DllImport(Libraries.Application, EntryPoint = "ui_app_main", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int UIAppMain(int argc, string[] argv, ref UIAppLifecycleCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.Application, EntryPoint = "ui_app_exit", CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void UIAppExit();
+
[StructLayoutAttribute(LayoutKind.Sequential)]
internal struct UIAppLifecycleCallbacks
{
public AppResumeCallback OnResume;
public AppControlCallback OnAppControl;
}
-
- [DllImport(Libraries.Application, EntryPoint = "ui_app_main", CallingConvention = CallingConvention.Cdecl)]
- internal static extern int UIAppMain(int argc, string[] argv, ref UIAppLifecycleCallbacks callback, IntPtr userData);
-
- [DllImport(Libraries.Application, EntryPoint = "ui_app_exit", CallingConvention = CallingConvention.Cdecl)]
- internal static extern void UIAppExit();
}
}
/// you entered into with Samsung.
-using System.Text;
using System.Runtime.InteropServices;
+using System.Text;
internal static partial class Interop
{
private const int MaxMimeLength = 128;
private const string FileSchemaPrefix = "file://";
- [DllImport(Libraries.Aul, CallingConvention = CallingConvention.Cdecl)]
- private static extern int aul_get_mime_from_file(string filename, StringBuilder mimetype, int len);
-
internal static string GetMimeFromUri(string uri)
{
StringBuilder sb = new StringBuilder(MaxMimeLength);
- int err = aul_get_mime_from_file(
- uri.StartsWith(FileSchemaPrefix) ? uri.Substring(FileSchemaPrefix.Length) : uri,
- sb, MaxMimeLength);
+ int err = aul_get_mime_from_file(uri.StartsWith(FileSchemaPrefix) ? uri.Substring(FileSchemaPrefix.Length) : uri, sb, MaxMimeLength);
if (err == 0)
{
return sb.ToString();
return null;
}
}
+
+ [DllImport(Libraries.Aul, CallingConvention = CallingConvention.Cdecl)]
+ private static extern int aul_get_mime_from_file(string filename, StringBuilder mimetype, int len);
}
}
internal static extern int GetString(IntPtr handle, string key, out IntPtr value);
[DllImport(Libraries.Bundle, EntryPoint = "bundle_add_byte", CallingConvention = CallingConvention.Cdecl)]
- unsafe internal static extern int AddByte(IntPtr handle, string key, byte* value, int size);
+ internal static extern unsafe int AddByte(IntPtr handle, string key, byte* value, int size);
[DllImport(Libraries.Bundle, EntryPoint = "bundle_get_byte", CallingConvention = CallingConvention.Cdecl)]
internal static extern int GetByte(IntPtr handle, string key, out IntPtr value, out int size);
internal static class UnsafeCode
{
- unsafe internal static void AddItem(IntPtr handle, string key, byte[] value, int offset, int count)
+ internal static unsafe void AddItem(IntPtr handle, string key, byte[] value, int offset, int count)
{
fixed (byte* pointer = value)
{
using System;
-using System.Text;
using System.Runtime.InteropServices;
internal static partial class Interop
using System;
-
using Tizen.UI;
namespace Tizen.Applications
/// </summary>
public abstract class Actor : Context
{
- internal Guid TaskId { get; set; }
-
- private enum ActorState
- {
- None = 0,
- Created = 1,
- Started = 2,
- Resumed = 3,
- Pasued = 4
- }
-
private ActorState _state = ActorState.None;
/// <summary>
///
/// </summary>
- internal protected Page MainPage { get; set; }
+ public event EventHandler Created;
/// <summary>
///
/// </summary>
- protected virtual void OnCreate() { }
+ public event EventHandler Started;
/// <summary>
///
/// </summary>
- protected virtual void OnStart() { }
+ public event EventHandler Resumed;
- /// <summary>
+ /// <summary>
///
/// </summary>
- protected virtual void OnPause() { }
+ public event EventHandler Paused;
/// <summary>
///
/// </summary>
- protected virtual void OnResume() { }
+ public event EventHandler Destroyed;
+
+ private enum ActorState
+ {
+ None = 0,
+ Created = 1,
+ Started = 2,
+ Resumed = 3,
+ Pasued = 4
+ }
+
+ internal Guid TaskId { get; set; }
/// <summary>
///
/// </summary>
- protected virtual void OnDestroy() { }
-
- internal void Create()
+ internal protected Page MainPage { get; set; }
+
+ internal void OnCreate(Guid taskId, AppControl control)
{
if (_state != ActorState.Created)
{
- OnCreate();
+ TaskId = taskId;
+ _control = control;
_state = ActorState.Created;
+ if (Created != null)
+ {
+ Created(this, EventArgs.Empty);
+ }
}
}
- internal void Start()
+ internal void OnStart()
{
if (_state != ActorState.Started)
{
- OnStart();
_state = ActorState.Started;
+ if (Started != null)
+ {
+ Started(this, EventArgs.Empty);
+ }
}
}
- internal void Pause()
+ internal void OnPause()
{
if (_state != ActorState.Pasued)
{
- OnPause();
_state = ActorState.Pasued;
+ if (Paused != null)
+ {
+ Paused(this, EventArgs.Empty);
+ }
}
}
- internal void Resume()
+ internal void OnResume()
{
if (_state != ActorState.Resumed)
{
- OnResume();
_state = ActorState.Resumed;
+ if (Resumed != null)
+ {
+ Resumed(this, EventArgs.Empty);
+ }
MainPage.Show();
}
}
- internal void Destroy()
+ internal void OnDestroy()
{
if (_state != ActorState.None)
{
- OnDestroy();
_state = ActorState.None;
+ if (Destroyed != null)
+ {
+ Destroyed(this, EventArgs.Empty);
+ }
}
}
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="actor"></param>
- /// <param name="control"></param>
- protected void StartActor(Actor actor, AppControl control)
- {
- throw new NotImplementedException();
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="actorType"></param>
- /// <param name="control"></param>
- protected override void StartActor(Type actorType, AppControl control)
- {
-
- Application.StartActor(TaskId, actorType, control);
- }
-
- /// <summary>
- ///
- /// </summary>
- protected override void Finish()
- {
- Application.StopActor(this);
- }
}
}
/// <summary>
///
/// </summary>
- public static class Operations
+ /// <param name="operation"></param>
+ /// <param name="mime"></param>
+ /// <param name="uri"></param>
+ public AppControl(string operation, string mime, string uri)
+ {
+ _operation = operation;
+ _mime = mime;
+ _uri = uri;
+ }
+
+ internal AppControl(IntPtr appControlHandle)
{
- /// <summary>
- /// An explicit launch for a homescreen application.
- /// </summary>
- public const string Main = "http://tizen.org/appcontrol/operation/main";
-
- /// <summary>
- /// An explicit launch for an application that excludes a homescreen application.
- /// </summary>
- public const string Default = "http://tizen.org/appcontrol/operation/default";
-
- /// <summary>
- /// Provides an editable access to the given data.
- /// </summary>
- public const string Edit = "http://tizen.org/appcontrol/operation/edit";
-
- /// <summary>
- /// Displays the data.
- /// </summary>
- public const string View = "http://tizen.org/appcontrol/operation/view";
-
- /// <summary>
- /// Picks items.
- /// </summary>
- public const string Pick = "http://tizen.org/appcontrol/operation/pick";
-
- /// <summary>
- /// Creates contents.
- /// </summary>
- public const string CreateContent = "http://tizen.org/appcontrol/operation/create_content";
-
- /// <summary>
- /// Performs a call to someone.
- /// </summary>
- public const string Call = "http://tizen.org/appcontrol/operation/call";
-
- /// <summary>
- /// Delivers some data to someone else.
- /// </summary>
- public const string Send = "http://tizen.org/appcontrol/operation/send";
-
- /// <summary>
- /// Delivers text data to someone else.
- /// </summary>
- public const string SendText = "http://tizen.org/appcontrol/operation/send_text";
-
- /// <summary>
- /// Shares an item with someone else.
- /// </summary>
- public const string Share = "http://tizen.org/appcontrol/operation/share";
-
- /// <summary>
- /// Shares multiple items with someone else.
- /// </summary>
- public const string MultiShare = "http://tizen.org/appcontrol/operation/multi_share";
-
- /// <summary>
- /// Shares text data with someone else.
- /// </summary>
- public const string ShareText = "http://tizen.org/appcontrol/operation/share_text";
-
- /// <summary>
- /// Dials a number. This shows a UI with the number to be dialed, allowing the user to explicitly initiate the call.
- /// </summary>
- public const string Dial = "http://tizen.org/appcontrol/operation/dial";
-
- /// <summary>
- /// Performs a search.
- /// </summary>
- public const string Search = "http://tizen.org/appcontrol/operation/search";
-
- /// <summary>
- /// Downloads items.
- /// </summary>
- public const string Download = "http://tizen.org/appcontrol/operation/download";
-
- /// <summary>
- /// Prints contents.
- /// </summary>
- public const string Print = "http://tizen.org/appcontrol/operation/print";
-
- /// <summary>
- /// Composes a message.
- /// </summary>
- public const string Compose = "http://tizen.org/appcontrol/operation/compose";
-
- /// <summary>
- /// Can be launched by interested System-Event.
- /// </summary>
- public const string LaunchOnEvent = "http://tizen.org/appcontrol/operation/launch_on_event";
-
- /// <summary>
- /// Adds an item.
- /// </summary>
- public const string Add = "http://tizen.org/appcontrol/operation/add";
-
- /// <summary>
- /// Captures images by camera applications.
- /// </summary>
- public const string ImageCapture = "http://tizen.org/appcontrol/operation/image_capture";
-
- /// <summary>
- /// Captures videos by camera applications.
- /// </summary>
- public const string VideoCapture = "http://tizen.org/appcontrol/operation/video_capture";
-
- /// <summary>
- /// Shows system settings.
- /// </summary>
- public const string Setting = "http://tizen.org/appcontrol/operation/setting";
-
- /// <summary>
- /// Shows settings to enable Bluetooth.
- /// </summary>
- public const string SettingBluetoothEnable = "http://tizen.org/appcontrol/operation/setting/bt_enable";
-
- /// <summary>
- /// Shows settings to configure Bluetooth visibility.
- /// </summary>
- public const string SettingBluetoothVisibility = "http://tizen.org/appcontrol/operation/setting/bt_visibility";
-
- /// <summary>
- /// Shows settings to allow configuration of current location sources.
- /// </summary>
- public const string SettingLocation = "http://tizen.org/appcontrol/operation/setting/location";
-
- /// <summary>
- /// Shows NFC settings.
- /// </summary>
- public const string SettingNfc = "http://tizen.org/appcontrol/operation/setting/nfc";
-
- /// <summary>
- /// Shows settings to allow configuration of Wi-Fi.
- /// </summary>
- public const string SettingWifi = "http://tizen.org/appcontrol/operation/setting/wifi";
+ var handle = new Interop.AppControl.SafeAppControlHandle(appControlHandle);
+ Interop.AppControl.GetOperation(handle, out _operation);
+ Interop.AppControl.GetMime(handle, out _mime);
+ Interop.AppControl.GetUri(handle, out _uri);
}
/// <summary>
/// </summary>
public string Uri { get { return _uri; } }
- internal AppControl(IntPtr appControlHandle)
- {
- var handle = new Interop.AppControl.SafeAppControlHandle(appControlHandle);
- Interop.AppControl.GetOperation(handle, out _operation);
- Interop.AppControl.GetMime(handle, out _mime);
- Interop.AppControl.GetUri(handle, out _uri);
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="operation"></param>
- /// <param name="mime"></param>
- /// <param name="uri"></param>
- public AppControl(string operation, string mime, string uri)
- {
- _operation = operation;
- _mime = mime;
- _uri = uri;
- }
-
internal bool IsLaunchOperation()
{
if (_operation == null) return false;
get { return false; }
}
}
+
+ /// <summary>
+ ///
+ /// </summary>
+ public static class Operations
+ {
+ /// <summary>
+ /// An explicit launch for a homescreen application.
+ /// </summary>
+ public const string Main = "http://tizen.org/appcontrol/operation/main";
+
+ /// <summary>
+ /// An explicit launch for an application that excludes a homescreen application.
+ /// </summary>
+ public const string Default = "http://tizen.org/appcontrol/operation/default";
+
+ /// <summary>
+ /// Provides an editable access to the given data.
+ /// </summary>
+ public const string Edit = "http://tizen.org/appcontrol/operation/edit";
+
+ /// <summary>
+ /// Displays the data.
+ /// </summary>
+ public const string View = "http://tizen.org/appcontrol/operation/view";
+
+ /// <summary>
+ /// Picks items.
+ /// </summary>
+ public const string Pick = "http://tizen.org/appcontrol/operation/pick";
+
+ /// <summary>
+ /// Creates contents.
+ /// </summary>
+ public const string CreateContent = "http://tizen.org/appcontrol/operation/create_content";
+
+ /// <summary>
+ /// Performs a call to someone.
+ /// </summary>
+ public const string Call = "http://tizen.org/appcontrol/operation/call";
+
+ /// <summary>
+ /// Delivers some data to someone else.
+ /// </summary>
+ public const string Send = "http://tizen.org/appcontrol/operation/send";
+
+ /// <summary>
+ /// Delivers text data to someone else.
+ /// </summary>
+ public const string SendText = "http://tizen.org/appcontrol/operation/send_text";
+
+ /// <summary>
+ /// Shares an item with someone else.
+ /// </summary>
+ public const string Share = "http://tizen.org/appcontrol/operation/share";
+
+ /// <summary>
+ /// Shares multiple items with someone else.
+ /// </summary>
+ public const string MultiShare = "http://tizen.org/appcontrol/operation/multi_share";
+
+ /// <summary>
+ /// Shares text data with someone else.
+ /// </summary>
+ public const string ShareText = "http://tizen.org/appcontrol/operation/share_text";
+
+ /// <summary>
+ /// Dials a number. This shows a UI with the number to be dialed, allowing the user to explicitly initiate the call.
+ /// </summary>
+ public const string Dial = "http://tizen.org/appcontrol/operation/dial";
+
+ /// <summary>
+ /// Performs a search.
+ /// </summary>
+ public const string Search = "http://tizen.org/appcontrol/operation/search";
+
+ /// <summary>
+ /// Downloads items.
+ /// </summary>
+ public const string Download = "http://tizen.org/appcontrol/operation/download";
+
+ /// <summary>
+ /// Prints contents.
+ /// </summary>
+ public const string Print = "http://tizen.org/appcontrol/operation/print";
+
+ /// <summary>
+ /// Composes a message.
+ /// </summary>
+ public const string Compose = "http://tizen.org/appcontrol/operation/compose";
+
+ /// <summary>
+ /// Can be launched by interested System-Event.
+ /// </summary>
+ public const string LaunchOnEvent = "http://tizen.org/appcontrol/operation/launch_on_event";
+
+ /// <summary>
+ /// Adds an item.
+ /// </summary>
+ public const string Add = "http://tizen.org/appcontrol/operation/add";
+
+ /// <summary>
+ /// Captures images by camera applications.
+ /// </summary>
+ public const string ImageCapture = "http://tizen.org/appcontrol/operation/image_capture";
+
+ /// <summary>
+ /// Captures videos by camera applications.
+ /// </summary>
+ public const string VideoCapture = "http://tizen.org/appcontrol/operation/video_capture";
+
+ /// <summary>
+ /// Shows system settings.
+ /// </summary>
+ public const string Setting = "http://tizen.org/appcontrol/operation/setting";
+
+ /// <summary>
+ /// Shows settings to enable Bluetooth.
+ /// </summary>
+ public const string SettingBluetoothEnable = "http://tizen.org/appcontrol/operation/setting/bt_enable";
+
+ /// <summary>
+ /// Shows settings to configure Bluetooth visibility.
+ /// </summary>
+ public const string SettingBluetoothVisibility = "http://tizen.org/appcontrol/operation/setting/bt_visibility";
+
+ /// <summary>
+ /// Shows settings to allow configuration of current location sources.
+ /// </summary>
+ public const string SettingLocation = "http://tizen.org/appcontrol/operation/setting/location";
+
+ /// <summary>
+ /// Shows NFC settings.
+ /// </summary>
+ public const string SettingNfc = "http://tizen.org/appcontrol/operation/setting/nfc";
+
+ /// <summary>
+ /// Shows settings to allow configuration of Wi-Fi.
+ /// </summary>
+ public const string SettingWifi = "http://tizen.org/appcontrol/operation/setting/wifi";
+ }
}
/// <summary>
///
/// </summary>
- public string Operation { get { return _operation; } }
+ /// <param name="operation"></param>
+ /// <param name="mime"></param>
+ /// <param name="uri"></param>
+ public AppControlFilter(string operation, string mime = null, string uri = null)
+ {
+ _operation = operation;
+ _mime = mime;
+ _uri = uri;
+ }
/// <summary>
///
/// </summary>
- public string Mime { get { return _mime; } }
+ public string Operation { get { return _operation; } }
/// <summary>
///
/// </summary>
- public string Uri { get { return _uri; } }
+ public string Mime { get { return _mime; } }
/// <summary>
///
/// </summary>
- /// <param name="operation"></param>
- /// <param name="mime"></param>
- /// <param name="uri"></param>
- public AppControlFilter(string operation, string mime = null, string uri = null)
- {
- _operation = operation;
- _mime = mime;
- _uri = uri;
- }
+ public string Uri { get { return _uri; } }
/// <summary>
///
return hash;
}
+ internal bool IsMatch(AppControl e)
+ {
+ string mime = e.Mime;
+ if (String.IsNullOrEmpty(mime) && !String.IsNullOrEmpty(e.Uri))
+ {
+ mime = Interop.Aul.GetMimeFromUri(e.Uri);
+ }
+ return _operation == e.Operation && IsMimeMatched(mime) && IsUriMatched(e.Uri);
+ }
+
private bool IsMimeMatched(string mime)
{
if (_mime == "*" || _mime == "*/*")
}
return _uri == uri;
}
-
- internal bool IsMatch(AppControl e)
- {
- string mime = e.Mime;
- if (String.IsNullOrEmpty(mime) && !String.IsNullOrEmpty(e.Uri))
- {
- mime = Interop.Aul.GetMimeFromUri(e.Uri);
- }
- return _operation == e.Operation && IsMimeMatched(mime) && IsUriMatched(e.Uri);
- }
}
}
{
private static readonly Dictionary<AppControlFilter, Type> s_filterMap = new Dictionary<AppControlFilter, Type>();
private static readonly List<Service> s_serviceList = new List<Service>();
- private static readonly List<Actor> s_actorList = new List<Actor>();
-
- private static Actor ForegroundActor
- {
- get
- {
- return s_actorList.LastOrDefault(null);
- }
- }
-
- private static readonly Window s_window = null;
+ private static readonly ActorStack s_actorStack = new ActorStack();
+ private static Window s_window = null;
/// <summary>
/// Occurs when the application starts.
/// </summary>
public static event EventHandler Exited = delegate { };
+ private static Actor ForegroundActor
+ {
+ get
+ {
+ return s_actorStack.Peek();
+ }
+ }
+
/// <summary>
/// Runs the application's main loop.
/// </summary>
{
if (ForegroundActor != null)
{
- ForegroundActor.Pause();
+ ForegroundActor.OnPause();
}
};
ops.OnResume = (userData) =>
{
if (ForegroundActor != null)
{
- ForegroundActor.Resume();
+ ForegroundActor.OnResume();
}
};
ops.OnAppControl = (appControlHandle, userData) =>
AppControl appControl = new AppControl(appControlHandle);
if (appControl.IsService)
{
- foreach (var item in s_filterMap)
+ Type found = FindServiceInFilters(appControl);
+ if (found != null)
{
- if (item.Key.IsMatch(appControl) && item.Value.IsSubclassOf(typeof(Service)))
- {
- StartService(item.Value, appControl);
- break;
- }
+ //StartService(found, appControl);
}
}
else
{
- foreach (var item in s_filterMap)
+ Type found = FindActorInFilters(appControl);
+ if (found != null)
{
- if (item.Key.IsMatch(appControl) && item.Value.IsSubclassOf(typeof(Actor)))
- {
- if (ForegroundActor == null || !appControl.IsLaunchOperation())
- {
- StartActor(Guid.Empty, item.Value, appControl);
- }
- break;
- }
+ //StartActor(null, )
}
}
};
}
/// <summary>
- /// Hides the application.
- /// </summary>
- public static void Hide()
- {
- if (s_window != null)
- s_window.InActive();
- }
-
- /// <summary>
/// Exits the main loop of application.
/// </summary>
public static void Exit()
RegisterContext(serviceType, filters);
}
- private static void RegisterContext(Type contextType, AppControlFilter[] filters)
+ internal static void StartActor(Context caller, Type actorType, Context.ActorFlags flags, AppControl control)
{
- foreach (var prop in contextType.GetProperties())
+ if (caller == null && actorType == null)
{
- foreach (var attr in prop.GetCustomAttributes(false))
- {
- var filter = attr as AppControlFilter;
- if (filter != null)
- {
- s_filterMap.Add(filter, contextType);
- }
- }
+ throw new ArgumentNullException("actorType");
}
- if (filters != null)
+
+ Actor targetActor = null;
+
+ Actor callerActor = caller as Actor;
+ if (callerActor != null && ForegroundActor != callerActor)
{
- foreach (var filter in filters)
- {
- s_filterMap.Add(filter, contextType);
- }
+ throw new InvalidOperationException("StartActor() should be called from the foreground Actor.");
}
- }
- internal static void StartActor(Guid taskId, Type actorType, AppControl control)
- {
- if (!actorType.IsSubclassOf(typeof(Actor)))
+ if (actorType == null)
{
- throw new ArgumentException(actorType.FullName + " is not a subclass of Actor.");
+ actorType = FindActorInFilters(control);
+ if (actorType == null)
+ {
+ throw new ArgumentException("Could not find the matched Actor.", "control");
+ }
}
- if (taskId != Guid.Empty && ForegroundActor != null && taskId != ForegroundActor.TaskId)
+ if (callerActor != null && !IsFlagSet(flags, Context.ActorFlags.NewInstance))
{
- throw new InvalidOperationException("StartActor() should be called from the foreground task.");
+ targetActor = s_actorStack.FindInForegroundTask(actorType);
}
- Actor actor = (Actor)Activator.CreateInstance(actorType);
- actor.TaskId = taskId == Guid.Empty ? Guid.NewGuid() : taskId;
- actor._control = control;
- actor.Create();
-
- if (ForegroundActor != null)
+ if (s_window == null)
{
- ForegroundActor.Pause();
+ s_window = new Window();
}
- s_actorList.Add(actor);
- actor.Start();
-
if (!s_window.Visible)
{
s_window.Active();
s_window.Show();
}
- actor.Resume();
- }
-
- internal static void StartActor(Actor actor, AppControl control)
- {
- if (ForegroundActor == null)
- {
- throw new ArgumentNullException("ForegroundActor", "The Actor stack is empty.");
- }
- if (actor.TaskId != ForegroundActor.TaskId)
+ if (targetActor == null)
{
- throw new InvalidOperationException("StartActor() should be called from the foreground task.");
+ targetActor = (Actor)Activator.CreateInstance(actorType);
+ targetActor.OnCreate(callerActor != null ? callerActor.TaskId : Guid.NewGuid(), control);
+ s_actorStack.Push(targetActor);
}
-
- while (actor != ForegroundActor)
+ else
{
- Actor popped = ForegroundActor;
- s_actorList.Remove(popped);
- popped.Pause();
- popped.Destroy();
+ if (IsFlagSet(flags, Context.ActorFlags.ClearTop))
+ {
+ while (targetActor != ForegroundActor)
+ {
+ Actor popped = s_actorStack.Pop();
+ popped.OnPause();
+ popped.OnDestroy();
+ }
+ }
+ else if (IsFlagSet(flags, Context.ActorFlags.MoveToTop))
+ {
+ if (ForegroundActor != targetActor)
+ {
+ ForegroundActor.OnPause();
+ s_actorStack.MoveToTop(targetActor);
+ }
+ }
}
- actor.Resume();
+ ForegroundActor.OnStart();
+ ForegroundActor.OnResume();
}
internal static void StopActor(Actor actor)
{
if (ForegroundActor == null)
{
- throw new ArgumentNullException("ForegroundActor", "The Actor stack is empty.");
+ throw new InvalidOperationException("The Actor stack is empty.");
}
Guid prevForegroundTaskId = ForegroundActor.TaskId;
- s_actorList.Remove(actor);
- actor.Pause();
- actor.Destroy();
+ s_actorStack.Remove(actor);
+ actor.OnPause();
+ actor.OnDestroy();
if (actor.TaskId == prevForegroundTaskId)
{
if (ForegroundActor.TaskId == actor.TaskId)
{
- ForegroundActor.Resume();
+ ForegroundActor.OnResume();
}
else
{
- if (s_actorList.Count == 0 && s_serviceList.Count == 0)
+ if (s_actorStack.Count == 0 && s_serviceList.Count == 0)
{
Exit();
}
- else {
- Hide();
+ else
+ {
+ s_window.Hide();
}
}
}
internal static void StartService(Type serviceType, AppControl control)
{
- if (!serviceType.IsSubclassOf(typeof(Service)))
+ if (serviceType == null)
{
- throw new ArgumentException(serviceType.FullName + " is not a subclass of Service.");
+ serviceType = FindServiceInFilters(control);
+ if (serviceType == null)
+ {
+ throw new ArgumentException("Could not find the matched Service.", "control");
+ }
+ }
+ else
+ {
+ if (!serviceType.IsSubclassOf(typeof(Service)))
+ {
+ throw new ArgumentException(serviceType.FullName + " is not a subclass of Service.", "serviceType");
+ }
}
Service svc = s_serviceList.Find(s => s.GetType() == serviceType);
{
svc = (Service)Activator.CreateInstance(serviceType);
s_serviceList.Add(svc);
- svc.Create();
+ svc.OnCreate(control);
}
- svc._control = control;
- svc.Start();
+ svc.OnStart();
}
internal static void StopService(Type serviceType)
Service svc = s_serviceList.Find(s => s.GetType() == serviceType);
if (svc != null)
{
- svc.Destroy();
+ svc.OnDestroy();
s_serviceList.Remove(svc);
if (ForegroundActor == null && s_serviceList.Count == 0)
{
}
}
}
+
+ internal static void Finish(Context caller)
+ {
+ if (caller is Actor)
+ {
+ StopActor(caller as Actor);
+ }
+ else if (caller is Service)
+ {
+ // TODO: check the value of GetType()
+ StopService(caller.GetType());
+ }
+ }
+
+ private static Type FindActorInFilters(AppControl control)
+ {
+ foreach (var item in s_filterMap)
+ {
+ if (item.Key.IsMatch(control) && item.Value.IsSubclassOf(typeof(Actor)))
+ {
+ return item.Value;
+ }
+ }
+ return null;
+ }
+
+ private static Type FindServiceInFilters(AppControl control)
+ {
+ foreach (var item in s_filterMap)
+ {
+ if (item.Key.IsMatch(control) && item.Value.IsSubclassOf(typeof(Service)))
+ {
+ return item.Value;
+ }
+ }
+ return null;
+ }
+
+ private static void RegisterContext(Type contextType, AppControlFilter[] filters)
+ {
+ foreach (var prop in contextType.GetProperties())
+ {
+ foreach (var attr in prop.GetCustomAttributes(false))
+ {
+ var filter = attr as AppControlFilter;
+ if (filter != null)
+ {
+ s_filterMap.Add(filter, contextType);
+ }
+ }
+ }
+ if (filters != null)
+ {
+ foreach (var filter in filters)
+ {
+ s_filterMap.Add(filter, contextType);
+ }
+ }
+ }
+
+ private static bool IsFlagSet(Context.ActorFlags flags, Context.ActorFlags values)
+ {
+ return (values & flags) == values;
+ }
+
+
+ private class ActorStack
+ {
+ private readonly List<Actor> _actorList;
+
+ public int Count
+ {
+ get
+ {
+ return _actorList.Count;
+ }
+ }
+
+ public ActorStack()
+ {
+ _actorList = new List<Actor>();
+ }
+
+ public Actor Peek()
+ {
+ return _actorList.LastOrDefault(null);
+ }
+
+ public void Push(Actor item)
+ {
+ _actorList.Add(item);
+ }
+
+ public Actor Pop()
+ {
+ Actor last = Peek();
+ _actorList.Remove(last);
+ return last;
+ }
+
+ public void Remove(Actor actor)
+ {
+ _actorList.Remove(actor);
+ }
+
+ public Actor FindInForegroundTask(Type actorType)
+ {
+ return _actorList.Find(s => s.GetType() == actorType && s.TaskId == Peek().TaskId);
+ }
+
+ public void MoveToTop(Actor actor)
+ {
+ _actorList.Remove(actor);
+ _actorList.Add(actor);
+ }
+ }
}
}
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
private bool _disposed = false;
private readonly List<string> _keys;
+ /// <summary>
+ /// The Bundle constructor.
+ /// </summary>
+ public Bundle()
+ {
+ _keys = new List<string>();
+ _handle = Interop.Bundle.Create();
+ }
+
private enum BundleTypeProperty
{
Array = 0x0100,
return _keys;
}
}
-
- /// <summary>
- /// The Bundle constructor.
- /// </summary>
- public Bundle()
- {
- _keys = new List<string>();
- _handle = Interop.Bundle.Create();
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (!_disposed)
- {
- if (disposing)
- {
- // to be used if there are any other disposable objects
- }
- if (_handle != IntPtr.Zero)
- {
- Interop.Bundle.Free(_handle);
- _handle = IntPtr.Zero;
- }
-
- _disposed = true;
- }
- }
-
- ~Bundle()
- {
- Dispose(false);
- }
-
+
/// <summary>
/// Releases any unmanaged resources used by this object.
/// </summary>
}
}
- private void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
- {
- managedArray = new string[size];
- IntPtr[] IntPtrArray = new IntPtr[size];
-
- Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
-
- for (int iterator = 0; iterator < size; iterator++)
- {
- managedArray[iterator] = Marshal.PtrToStringAuto(IntPtrArray[iterator]);
- }
- }
-
/// <summary>
/// Gets the value of a bundle item with a specified key.
/// </summary>
switch (type)
{
case (int)BundleType.String:
- // get string
- IntPtr stringPtr;
- Interop.Bundle.GetString(_handle, key, out stringPtr);
- string stringResult = Marshal.PtrToStringAuto(stringPtr);
- return stringResult;
+ // get string
+ IntPtr stringPtr;
+ Interop.Bundle.GetString(_handle, key, out stringPtr);
+ string stringResult = Marshal.PtrToStringAuto(stringPtr);
+ return stringResult;
case (int)BundleType.StringArray:
- // get string array
- IntPtr stringArrayPtr;
- int stringArraySize;
- stringArrayPtr = Interop.Bundle.GetStringArray(_handle, key, out stringArraySize);
- string[] stringArray;
- IntPtrToStringArray(stringArrayPtr, stringArraySize, out stringArray);
- return stringArray;
+ // get string array
+ IntPtr stringArrayPtr;
+ int stringArraySize;
+ stringArrayPtr = Interop.Bundle.GetStringArray(_handle, key, out stringArraySize);
+ string[] stringArray;
+ IntPtrToStringArray(stringArrayPtr, stringArraySize, out stringArray);
+ return stringArray;
case (int)BundleType.Byte:
case (int)BundleType.ByteArray:
- // get byte array
- IntPtr byteArrayPtr;
- int byteArraySize;
- Interop.Bundle.GetByte(_handle, key, out byteArrayPtr, out byteArraySize);
- byte[] byteArray = new byte[byteArraySize];
- Marshal.Copy(byteArrayPtr, byteArray, 0, byteArraySize);
- return byteArray;
+ // get byte array
+ IntPtr byteArrayPtr;
+ int byteArraySize;
+ Interop.Bundle.GetByte(_handle, key, out byteArrayPtr, out byteArraySize);
+ byte[] byteArray = new byte[byteArraySize];
+ Marshal.Copy(byteArrayPtr, byteArray, 0, byteArraySize);
+ return byteArray;
default:
- return "PROBLEM"; // TODO: Handle this
+ return "PROBLEM"; // TODO: Handle this
}
}
else
// TODO: handle when key does not exist
}
}
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="disposing"></param>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposed)
+ {
+ if (disposing)
+ {
+ // to be used if there are any other disposable objects
+ }
+ if (_handle != IntPtr.Zero)
+ {
+ Interop.Bundle.Free(_handle);
+ _handle = IntPtr.Zero;
+ }
+
+ _disposed = true;
+ }
+ }
+
+ ~Bundle()
+ {
+ Dispose(false);
+ }
+
+ private void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
+ {
+ managedArray = new string[size];
+ IntPtr[] IntPtrArray = new IntPtr[size];
+
+ Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
+
+ for (int iterator = 0; iterator < size; iterator++)
+ {
+ managedArray[iterator] = Marshal.PtrToStringAuto(IntPtrArray[iterator]);
+ }
+ }
}
}
public abstract class Context
{
internal AppControl _control;
+
+ [Flags]
+ public enum ActorFlags
+ {
+ NewInstance = 1,
+ ClearTop = 2,
+ MoveToTop = 4,
+ }
/// <summary>
///
/// </summary>
/// <param name="actorType"></param>
/// <param name="control"></param>
- protected abstract void StartActor(Type actorType, AppControl control);
+ protected void StartActor(Type actorType, AppControl control, ActorFlags flags = ActorFlags.NewInstance)
+ {
+ Application.StartActor(this, actorType, ActorFlags.NewInstance, control);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
+ /// <param name="control"></param>
+ /// <param name="flags"></param>
+ protected void StartActor(AppControl control, ActorFlags flags = ActorFlags.NewInstance)
+ {
+ Application.StartActor(this, null, ActorFlags.NewInstance, control);
+ }
/// <summary>
///
/// <summary>
///
/// </summary>
+ /// <param name="control"></param>
+ protected void StartService(AppControl control)
+ {
+ Application.StartService(null, control);
+ }
+
+ /// <summary>
+ ///
+ /// </summary>
/// <param name="serviceType"></param>
protected void StopService(Type serviceType)
{
/// <summary>
///
/// </summary>
- protected abstract void Finish();
+ protected void Finish()
+ {
+ Application.Finish(this);
+ }
/// <summary>
///
/// <summary>
///
/// </summary>
- protected virtual void OnCreate() { }
+ public event EventHandler Created;
/// <summary>
///
/// </summary>
- protected virtual void OnStart() { }
+ public event EventHandler Started;
/// <summary>
///
/// </summary>
- protected virtual void OnDestroy() { }
+ public event EventHandler Destroyed;
- internal void Create()
+ internal void OnCreate(AppControl control)
{
- OnCreate();
+ _control = control;
+ if (Created != null)
+ {
+ Created(this, EventArgs.Empty);
+ }
}
- internal void Start()
+ internal void OnStart()
{
- OnStart();
+ if (Started != null)
+ {
+ Started(this, EventArgs.Empty);
+ }
}
- internal void Destroy()
+ internal void OnDestroy()
{
- OnDestroy();
- }
-
- /// <summary>
- ///
- /// </summary>
- /// <param name="actorType"></param>
- /// <param name="control"></param>
- protected override void StartActor(Type actorType, AppControl control)
- {
- Application.StartActor(Guid.Empty, actorType, control);
- }
-
- /// <summary>
- ///
- /// </summary>
- protected override void Finish()
- {
- Application.StopService(GetType());
+ if (Destroyed != null)
+ {
+ Destroyed(this, EventArgs.Empty);
+ }
}
}
}
{
internal class TizenSynchronizationContext : SynchronizationContext
{
- public static void Initialize()
- {
- SetSynchronizationContext(new TizenSynchronizationContext());
- }
- private Interop.Glib.GSourceFunc _wrapperHandler;
- private Object _transactionLock = new Object();
+ private readonly Interop.Glib.GSourceFunc _wrapperHandler;
+ private readonly Object _transactionLock = new Object();
+ private readonly Dictionary<int, Action> _handlerMap = new Dictionary<int, Action>();
private int _transactionID = 0;
- private Dictionary<int, Action> _handlerMap = new Dictionary<int, Action>();
private TizenSynchronizationContext()
{
_wrapperHandler = new Interop.Glib.GSourceFunc(Handler);
}
+ public static void Initialize()
+ {
+ SetSynchronizationContext(new TizenSynchronizationContext());
+ }
+
public override void Post(SendOrPostCallback d, object state)
{
Post(() =>