/*
* Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
namespace Tizen.Applications.ComponentBased.Common
{
///
/// The class for supporting multi-components based application model.
///
/// 6
public abstract class ComponentBasedApplication : Application
{
private const string LogTag = "Tizen.Applications";
private Dictionary _componentFactories = new Dictionary();
private Interop.CBApplication.CBAppLifecycleCallbacks _callbacks;
///
/// Initializes the ComponentBasedApplicationBase class.
///
/// The component type information.
/// The key should be a class type of FrameComponent or SubComponent subclass.
/// The value should be a component id which is declared in tizen-manifest.xml.
///
/// 6
public ComponentBasedApplication(IDictionary typeInfo)
{
_callbacks.OnInit = new Interop.CBApplication.CBAppInitCallback(OnInitNative);
_callbacks.OnFinished = new Interop.CBApplication.CBAppFiniCallback(OnFinishedNative);
_callbacks.OnRun = new Interop.CBApplication.CBAppRunCallback(OnRunNative);
_callbacks.OnExit = new Interop.CBApplication.CBAppExitCallback(OnExitNative);
_callbacks.OnCreate = new Interop.CBApplication.CBAppCreateCallback(OnCreateNative);
_callbacks.OnTerminate = new Interop.CBApplication.CBAppTerminateCallback(OnTerminateNative);
foreach (var component in typeInfo)
{
RegisterComponent(component.Key, component.Value);
}
}
///
/// Registers a component.
///
/// Class type
/// Component ID
/// Thrown when component type is already added or not sub-class of FrameComponent or ServiceComponent
/// 6
public void RegisterComponent(Type compType, string compId)
{
if (_componentFactories.ContainsKey(compType))
{
throw new ArgumentException("Already exist type");
}
if (typeof(FrameComponent).IsAssignableFrom(compType))
{
Log.Info(LogTag, "Add frame component");
_componentFactories.Add(compType, new FrameComponentStateManager(compType, compId, this));
}
else if (typeof(ServiceComponent).IsAssignableFrom(compType))
{
Log.Info(LogTag, "Add service component");
_componentFactories.Add(compType, new ServiceComponentStateManager(compType, compId, this));
}
else
{
throw new ArgumentException("compType must be sub type of FrameComponent or ServiceComponent", "compType");
}
}
///
/// Runs the application's main loop.
///
/// Arguments from commandline.
/// Thrown when component type is already added to the component.
/// 6
public override void Run(string[] args)
{
base.Run(args);
string[] argsClone = new string[args.Length + 1];
if (args.Length > 1)
{
args.CopyTo(argsClone, 1);
}
argsClone[0] = string.Empty;
Interop.CBApplication.ErrorCode err = Interop.CBApplication.BaseMain(argsClone.Length, argsClone, ref _callbacks, IntPtr.Zero);
if (err != Interop.CBApplication.ErrorCode.None)
{
Log.Error(LogTag, "Failed to run the application. Err = " + err);
throw new InvalidOperationException("Fail to run application : err(" + err + ")");
}
}
///
/// Exits the main loop of the application.
///
/// 6
public override void Exit()
{
Interop.CBApplication.BaseExit();
}
private IntPtr OnCreateNative(IntPtr data)
{
Log.Debug(LogTag, "On create");
IntPtr nativeComponentFactoryMap = IntPtr.Zero;
foreach (KeyValuePair entry in _componentFactories)
{
nativeComponentFactoryMap = entry.Value.Bind(nativeComponentFactoryMap);
}
return nativeComponentFactoryMap;
}
private void OnTerminateNative(IntPtr data)
{
}
private void OnRunNative(IntPtr data)
{
OnRun();
}
private void OnExitNative(IntPtr data)
{
OnExit();
}
private void OnInitNative(int argc, string[] argv, IntPtr userData)
{
OnInit(argv);
}
private void OnFinishedNative(IntPtr data)
{
OnFinished();
}
///
/// This method will be called before running main-loop
///
///
/// 6
protected virtual void OnInit(string[] args)
{
}
///
/// This method will be called after exiting main-loop
///
/// 6
protected virtual void OnFinished()
{
}
///
/// This method will be called to start main-loop
///
/// 6
protected abstract void OnRun();
///
/// This method will be called to exit main-loop
///
/// 6
protected virtual void OnExit()
{
}
}
}