/*
* Copyright (c) 2021 Samsung Electronics Co., Ltd.
*
* 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.Runtime.InteropServices;
using System;
using System.ComponentModel;
namespace Tizen.NUI
{
///
/// Singleton class.
/// ProcessorController handles ProcessorCallbacks those are requested to be called for each end of event process.
/// If there are works those required to be called after all of the event process for the efficiency, add them ProcessorController.
/// The calling order is not guaranteed but ProcessorCallbackes of LayoutController those are added by using AddLayoutControllerProcessor,
/// are called after ordinaly ProcessCallbacks added by AddProcessor.
///
/// The added callbacks will be called every time of event tick.
/// If the callback is not be wanted to be called anymore, remove it.
///
internal sealed class ProcessorController : Disposable
{
private static ProcessorController instance = null;
private bool initialied = false;
private ProcessorController() : this(Interop.ProcessorController.New(), true)
{
}
internal ProcessorController(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
{
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void ProcessorEventHandler();
private ProcessorEventHandler processorCallback = null;
private uint onceEventIndex;
// Double buffered once event processing
private EventHandler[] internalProcessorOnceEvent;
public event EventHandler ProcessorOnceEvent
{
add
{
internalProcessorOnceEvent[onceEventIndex] += value;
}
remove
{
internalProcessorOnceEvent[onceEventIndex] -= value;
}
}
public event EventHandler ProcessorEvent;
public event EventHandler LayoutProcessorEvent;
public bool Initialized => initialied;
public static ProcessorController Instance
{
get
{
if (instance == null)
{
instance = new ProcessorController();
}
return instance;
}
}
public void Initialize()
{
if (initialied == false)
{
initialied = true;
Interop.ProcessorController.Initialize(SwigCPtr);
onceEventIndex = 0u;
internalProcessorOnceEvent = new EventHandler[2];
internalProcessorOnceEvent[0] = null;
internalProcessorOnceEvent[1] = null;
processorCallback = new ProcessorEventHandler(Process);
Interop.ProcessorController.SetCallback(SwigCPtr, processorCallback);
NDalicPINVOKE.ThrowExceptionIfExists();
}
}
public void Process()
{
// Let us add once event into 1 index during 0 event invoke
onceEventIndex = 1;
internalProcessorOnceEvent[0]?.Invoke(this, null);
internalProcessorOnceEvent[0] = null;
ProcessorEvent?.Invoke(this, null);
LayoutProcessorEvent?.Invoke(this, null);
// Let us add once event into 0 index during 1 event invoke
// Note : To avoid ImageView's properties mismatched problem,
// We need to invoke events now which attached during internalProcessorOnceEvent[0] and LayoutProcessor.
onceEventIndex = 0;
internalProcessorOnceEvent[1]?.Invoke(this, null);
internalProcessorOnceEvent[1] = null;
}
///
/// Dispose ProcessorController.
///
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void Dispose(DisposeTypes type)
{
Interop.ProcessorController.RemoveCallback(SwigCPtr, processorCallback);
internalProcessorOnceEvent[0] = null;
internalProcessorOnceEvent[1] = null;
ProcessorEvent = null;
LayoutProcessorEvent = null;
GC.SuppressFinalize(this);
base.Dispose(type);
}
///
/// Awake ProcessorController.
/// It will call ProcessController.processorCallback and ProcessController.processorPostCallback hardly.
///
///
/// When event thread is not in idle state, This function will be ignored.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public void Awake()
{
Interop.ProcessorController.Awake(SwigCPtr);
NDalicPINVOKE.ThrowExceptionIfExists();
}
} // class ProcessorController
} // namespace Tizen.NUI