TizenRefApp-8266 [Call UI] Add UCL to application 14/121714/1
authorIgor Olshevskyi <i.olshevskyi@samsung.com>
Tue, 28 Mar 2017 12:33:53 +0000 (15:33 +0300)
committerIgor Olshevskyi <i.olshevskyi@samsung.com>
Tue, 28 Mar 2017 12:57:01 +0000 (15:57 +0300)
Change-Id: I200e6556c863ad1c401eb965518fbb70727b3473

111 files changed:
.cproject
ucl/inc/ucl/appfw/IInstance.h [new file with mode: 0644]
ucl/inc/ucl/appfw/IInstanceAppControlExt.h [new file with mode: 0644]
ucl/inc/ucl/appfw/IInstanceContext.h [new file with mode: 0644]
ucl/inc/ucl/appfw/InstanceManagerBase.h [new file with mode: 0644]
ucl/inc/ucl/appfw/SysEventProvider.h [new file with mode: 0644]
ucl/inc/ucl/appfw/SysEventProvider.hpp [new file with mode: 0644]
ucl/inc/ucl/appfw/UIApp.h [new file with mode: 0644]
ucl/inc/ucl/appfw/types.h [new file with mode: 0644]
ucl/inc/ucl/config.h [new file with mode: 0644]
ucl/inc/ucl/gui/EdjeWidget.h [new file with mode: 0644]
ucl/inc/ucl/gui/EdjeWidget.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/ElmWidget.h [new file with mode: 0644]
ucl/inc/ucl/gui/ElmWidget.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/Layout.h [new file with mode: 0644]
ucl/inc/ucl/gui/Layout.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/NaviItem.h [new file with mode: 0644]
ucl/inc/ucl/gui/NaviItem.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/Naviframe.h [new file with mode: 0644]
ucl/inc/ucl/gui/Naviframe.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/StyledWidget.h [new file with mode: 0644]
ucl/inc/ucl/gui/StyledWidget.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/Widget.h [new file with mode: 0644]
ucl/inc/ucl/gui/Widget.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/WidgetItem.h [new file with mode: 0644]
ucl/inc/ucl/gui/WidgetItem.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/Window.h [new file with mode: 0644]
ucl/inc/ucl/gui/Window.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/helpers.h [new file with mode: 0644]
ucl/inc/ucl/gui/helpers.hpp [new file with mode: 0644]
ucl/inc/ucl/gui/stdTheme.h [new file with mode: 0644]
ucl/inc/ucl/gui/stdTheme/common.h [new file with mode: 0644]
ucl/inc/ucl/gui/stdTheme/layout.h [new file with mode: 0644]
ucl/inc/ucl/gui/types.h [new file with mode: 0644]
ucl/inc/ucl/gui/types.hpp [new file with mode: 0644]
ucl/inc/ucl/misc/Aspect.h [new file with mode: 0644]
ucl/inc/ucl/misc/Aspect.hpp [new file with mode: 0644]
ucl/inc/ucl/misc/Event.h [new file with mode: 0644]
ucl/inc/ucl/misc/Event.hpp [new file with mode: 0644]
ucl/inc/ucl/misc/HashMap.h [new file with mode: 0644]
ucl/inc/ucl/misc/HashMap.hpp [new file with mode: 0644]
ucl/inc/ucl/misc/SharedObject.h [new file with mode: 0644]
ucl/inc/ucl/misc/SharedObject.hpp [new file with mode: 0644]
ucl/inc/ucl/misc/TString.h [new file with mode: 0644]
ucl/inc/ucl/misc/TString.hpp [new file with mode: 0644]
ucl/inc/ucl/misc/Variant.h [new file with mode: 0644]
ucl/inc/ucl/misc/Variant.hpp [new file with mode: 0644]
ucl/inc/ucl/misc/smartDelegation.h [new file with mode: 0644]
ucl/inc/ucl/misc/smartDelegation/WeakDelegate.h [new file with mode: 0644]
ucl/inc/ucl/misc/smartDelegation/WeakDelegate.hpp [new file with mode: 0644]
ucl/inc/ucl/misc/smartDelegation/macro.h [new file with mode: 0644]
ucl/inc/ucl/misc/smartDelegation/shortMacro.h [new file with mode: 0644]
ucl/inc/ucl/util/delegation.h [new file with mode: 0644]
ucl/inc/ucl/util/delegation/BaseDelegate.h [new file with mode: 0644]
ucl/inc/ucl/util/delegation/BaseDelegate.hpp [new file with mode: 0644]
ucl/inc/ucl/util/delegation/BaseDelegate2.h [new file with mode: 0644]
ucl/inc/ucl/util/delegation/BaseDelegate2.hpp [new file with mode: 0644]
ucl/inc/ucl/util/delegation/Callback.h [new file with mode: 0644]
ucl/inc/ucl/util/delegation/Callback.hpp [new file with mode: 0644]
ucl/inc/ucl/util/delegation/Delegate.h [new file with mode: 0644]
ucl/inc/ucl/util/delegation/Delegate.hpp [new file with mode: 0644]
ucl/inc/ucl/util/delegation/Delegate2.h [new file with mode: 0644]
ucl/inc/ucl/util/delegation/Delegate2.hpp [new file with mode: 0644]
ucl/inc/ucl/util/delegation/helpers.h [new file with mode: 0644]
ucl/inc/ucl/util/delegation/macro.h [new file with mode: 0644]
ucl/inc/ucl/util/delegation/shortMacro.h [new file with mode: 0644]
ucl/inc/ucl/util/helpers.h [new file with mode: 0644]
ucl/inc/ucl/util/helpers.hpp [new file with mode: 0644]
ucl/inc/ucl/util/logging.h [new file with mode: 0644]
ucl/inc/ucl/util/memory.h [new file with mode: 0644]
ucl/inc/ucl/util/memory/BaseRef.h [new file with mode: 0644]
ucl/inc/ucl/util/memory/BaseRef.hpp [new file with mode: 0644]
ucl/inc/ucl/util/memory/RefCountObj.h [new file with mode: 0644]
ucl/inc/ucl/util/memory/RefCountObj.hpp [new file with mode: 0644]
ucl/inc/ucl/util/memory/RefCountObjBase.h [new file with mode: 0644]
ucl/inc/ucl/util/memory/RefCountObjBase.hpp [new file with mode: 0644]
ucl/inc/ucl/util/memory/SharedRef.h [new file with mode: 0644]
ucl/inc/ucl/util/memory/SharedRef.hpp [new file with mode: 0644]
ucl/inc/ucl/util/memory/WeakRef.h [new file with mode: 0644]
ucl/inc/ucl/util/memory/WeakRef.hpp [new file with mode: 0644]
ucl/inc/ucl/util/memory/helpers.h [new file with mode: 0644]
ucl/inc/ucl/util/memory/macro.h [new file with mode: 0644]
ucl/inc/ucl/util/shortLogs.h [new file with mode: 0644]
ucl/inc/ucl/util/threading.h [new file with mode: 0644]
ucl/inc/ucl/util/threading/CondVar.h [new file with mode: 0644]
ucl/inc/ucl/util/threading/CondVar.hpp [new file with mode: 0644]
ucl/inc/ucl/util/threading/Mutex.h [new file with mode: 0644]
ucl/inc/ucl/util/threading/Mutex.hpp [new file with mode: 0644]
ucl/inc/ucl/util/threading/MutexLock.h [new file with mode: 0644]
ucl/inc/ucl/util/threading/MutexLock.hpp [new file with mode: 0644]
ucl/inc/ucl/util/threading/Thread.h [new file with mode: 0644]
ucl/inc/ucl/util/threading/Thread.hpp [new file with mode: 0644]
ucl/inc/ucl/util/types.h [new file with mode: 0644]
ucl/inc/ucl/util/types/Result.h [new file with mode: 0644]
ucl/inc/ucl/util/types/Result.hpp [new file with mode: 0644]
ucl/inc/ucl/util/types/baseTypes.h [new file with mode: 0644]
ucl/inc/ucl/util/types/classTypes.h [new file with mode: 0644]
ucl/src/appfw/InstanceManagerBase.cpp [new file with mode: 0644]
ucl/src/appfw/SysEventProvider.cpp [new file with mode: 0644]
ucl/src/appfw/UIApp.cpp [new file with mode: 0644]
ucl/src/common.h [new file with mode: 0644]
ucl/src/gui/EdjeWidget.cpp [new file with mode: 0644]
ucl/src/gui/ElmWidget.cpp [new file with mode: 0644]
ucl/src/gui/Layout.cpp [new file with mode: 0644]
ucl/src/gui/Naviframe.cpp [new file with mode: 0644]
ucl/src/gui/Widget.cpp [new file with mode: 0644]
ucl/src/gui/WidgetItem.cpp [new file with mode: 0644]
ucl/src/gui/Window.cpp [new file with mode: 0644]
ucl/src/misc/Variant.cpp [new file with mode: 0644]
ucl/src/util/logging.cpp [new file with mode: 0644]
ucl/src/util/types/Result.cpp [new file with mode: 0644]

index 292e139f294c105c34a2127e726f2e826ed8ac37..137ec08fd06a332f5bbe6e44980fb114d7efb874 100644 (file)
--- a/.cproject
+++ b/.cproject
                                                        <targetPlatform binaryParser="org.eclipse.cdt.core.ELF" id="org.tizen.nativeide.target.sbi.gnu.platform.base.299151930" osList="linux,win32" superClass="org.tizen.nativeide.target.sbi.gnu.platform.base"/>
                                                        <builder autoBuildTarget="all" buildPath="${workspace_loc:/call-ui}/Debug" enableAutoBuild="true" id="org.tizen.nativecore.target.sbi.gnu.builder.287909858" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Tizen Application Builder" superClass="org.tizen.nativecore.target.sbi.gnu.builder"/>
                                                        <tool id="org.tizen.nativecore.tool.sbi.gnu.archiver.850939844" name="Archiver" superClass="org.tizen.nativecore.tool.sbi.gnu.archiver"/>
-                                                       <tool command="clang++" id="org.tizen.nativecore.tool.sbi.gnu.cpp.compiler.66050065" name="C++ Compiler" superClass="org.tizen.nativecore.tool.sbi.gnu.cpp.compiler">
+                                                       <tool command="i386-linux-gnueabi-g++" id="org.tizen.nativecore.tool.sbi.gnu.cpp.compiler.66050065" name="C++ Compiler" superClass="org.tizen.nativecore.tool.sbi.gnu.cpp.compiler">
                                                                <option id="gnu.cpp.compiler.option.optimization.level.1977572256" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
                                                                <option defaultValue="gnu.cpp.compiler.debugging.level.max" id="sbi.gnu.cpp.compiler.option.debugging.level.core.1003532466" name="Debug level" superClass="sbi.gnu.cpp.compiler.option.debugging.level.core" valueType="enumerated"/>
                                                                <option defaultValue="false" id="sbi.gnu.cpp.compiler.option.misc.pic.core.58197076" name="-fPIC option" superClass="sbi.gnu.cpp.compiler.option.misc.pic.core" valueType="boolean"/>
                                                                <option id="sbi.gnu.cpp.compiler.option.1780411914" name="Tizen-Target" superClass="sbi.gnu.cpp.compiler.option" valueType="userObjs">
-                                                                       <listOptionValue builtIn="false" value="wearable-3.0-emulator.core_llvm37.i386.core.app"/>
+                                                                       <listOptionValue builtIn="false" value="wearable-3.0-emulator.core_gcc49.i386.core.app"/>
                                                                </option>
                                                                <option id="sbi.gnu.cpp.compiler.option.frameworks_inc.core.2060575755" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.cpp.compiler.option.frameworks_inc.core" valueType="includePath">
                                                                        <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/libxml2&quot;"/>
                                                                </option>
                                                                <option id="gnu.cpp.compiler.option.include.paths.79290911" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
                                                                        <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/ucl/inc}&quot;"/>
                                                                </option>
                                                                <option id="sbi.gnu.cpp.compiler.option.frameworks.core.1469916614" name="Tizen-Frameworks" superClass="sbi.gnu.cpp.compiler.option.frameworks.core" valueType="userObjs">
                                                                        <listOptionValue builtIn="false" value="Native_API"/>
                                                                </option>
-                                                               <option id="gnu.cpp.compiler.option.dialect.std.2098907038" superClass="gnu.cpp.compiler.option.dialect.std" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
+                                                               <option id="gnu.cpp.compiler.option.dialect.std.2098907038" name="Language standard" superClass="gnu.cpp.compiler.option.dialect.std" value="gnu.cpp.compiler.dialect.c++11" valueType="enumerated"/>
                                                                <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.27127097" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
                                                        </tool>
-                                                       <tool command="clang" id="org.tizen.nativecore.tool.sbi.gnu.c.compiler.1049599195" name="C Compiler" superClass="org.tizen.nativecore.tool.sbi.gnu.c.compiler">
+                                                       <tool command="i386-linux-gnueabi-gcc" id="org.tizen.nativecore.tool.sbi.gnu.c.compiler.1049599195" name="C Compiler" superClass="org.tizen.nativecore.tool.sbi.gnu.c.compiler">
                                                                <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.option.optimization.level.1400861396" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" valueType="enumerated"/>
                                                                <option defaultValue="gnu.c.debugging.level.max" id="sbi.gnu.c.compiler.option.debugging.level.core.1157370620" name="Debug level" superClass="sbi.gnu.c.compiler.option.debugging.level.core" valueType="enumerated"/>
                                                                <option defaultValue="false" id="sbi.gnu.c.compiler.option.misc.pic.core.1654013693" name="-fPIC option" superClass="sbi.gnu.c.compiler.option.misc.pic.core" valueType="boolean"/>
                                                                <option id="sbi.gnu.c.compiler.option.551225658" name="Tizen-Target" superClass="sbi.gnu.c.compiler.option" valueType="userObjs">
-                                                                       <listOptionValue builtIn="false" value="wearable-3.0-emulator.core_llvm37.i386.core.app"/>
+                                                                       <listOptionValue builtIn="false" value="wearable-3.0-emulator.core_gcc49.i386.core.app"/>
                                                                </option>
                                                                <option id="sbi.gnu.c.compiler.option.frameworks_inc.core.1481628386" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.c.compiler.option.frameworks_inc.core" valueType="includePath">
                                                                        <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/libxml2&quot;"/>
                                                                        <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/lib/glib-2.0/include&quot;"/>
                                                                </option>
                                                                <option id="sbi.gnu.c.compiler.option.frameworks_cflags.core.1586056041" name="Tizen-Frameworks-Other-Cflags" superClass="sbi.gnu.c.compiler.option.frameworks_cflags.core" valueType="stringList">
-                                                                       <listOptionValue builtIn="false" value="$(TC_COMPILER_MISC)"/>
-                                                                       <listOptionValue builtIn="false" value="$(RS_COMPILER_MISC)"/>
+                                                                       <listOptionValue builtIn="false" value="${TC_COMPILER_MISC}"/>
+                                                                       <listOptionValue builtIn="false" value="${RS_COMPILER_MISC}"/>
                                                                        <listOptionValue builtIn="false" value=" -fPIE"/>
-                                                                       <listOptionValue builtIn="false" value="--sysroot=&quot;$(SBI_SYSROOT)&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="--sysroot=&quot;${SBI_SYSROOT}&quot;"/>
                                                                </option>
                                                                <option id="gnu.c.compiler.option.include.paths.368004466" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
                                                                        <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/libxml2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/EGL&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/GLES&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/GLES2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/GLES3&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/KHR&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/SDL2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/appcore-agent&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/appcore-watch&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/appfw&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/badge&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/base&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/cairo&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/calendar-service2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/chromium-ewk&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ckm&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/contacts-svc&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/content&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/context-service&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/csr&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/dali&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/dali-toolkit&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/dbus-1.0&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/device&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/dlog&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-buffer-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-con-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-evas-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-file-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-imf-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-imf-evas-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-input-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-input-evas-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-ipc-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ector-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/e_dbus-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/edje-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eet-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/efl-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/efl-extension&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/efreet-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eina-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eina-1/eina&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eio-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eldbus-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/elementary-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/embryo-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/emile-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eo-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eom&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ethumb-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ethumb-client-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/evas-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/feedback&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/fontconfig&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/freetype2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/gio-unix-2.0&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/glib-2.0&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/harfbuzz&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/iotcon&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/json-glib-1.0&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/location&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/maps&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/media&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/media-content&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/messaging&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/metadata-editor&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/minizip&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/network&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/notification&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/nsd/&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/phonenumber-utils&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/sensor&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/storage&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/system&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/telephony&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/tzsh&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ui&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/vulkan&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/widget_service&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/widget_viewer_dali&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/widget_viewer_evas&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/yaca&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/lib/dbus-1.0/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/lib/glib-2.0/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/ucl/inc}&quot;"/>
                                                                </option>
                                                                <option id="sbi.gnu.c.compiler.option.frameworks.core.1478193049" name="Tizen-Frameworks" superClass="sbi.gnu.c.compiler.option.frameworks.core" valueType="userObjs">
                                                                        <listOptionValue builtIn="false" value="Native_API"/>
                                                                </option>
-                                                               <option id="gnu.c.compiler.option.dialect.std.1743559858" superClass="gnu.c.compiler.option.dialect.std" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
+                                                               <option id="gnu.c.compiler.option.dialect.std.1743559858" name="Language standard" superClass="gnu.c.compiler.option.dialect.std" value="gnu.c.compiler.dialect.default" valueType="enumerated"/>
                                                                <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.890993403" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
                                                        </tool>
                                                        <tool id="org.tizen.nativeide.tool.sbi.gnu.c.linker.base.1743186514" name="C Linker" superClass="org.tizen.nativeide.tool.sbi.gnu.c.linker.base"/>
-                                                       <tool command="clang++" id="org.tizen.nativecore.tool.sbi.gnu.cpp.linker.1743878166" name="C++ Linker" superClass="org.tizen.nativecore.tool.sbi.gnu.cpp.linker">
+                                                       <tool command="i386-linux-gnueabi-g++" id="org.tizen.nativecore.tool.sbi.gnu.cpp.linker.1743878166" name="C++ Linker" superClass="org.tizen.nativecore.tool.sbi.gnu.cpp.linker">
                                                                <option defaultValue="false" id="sbi.gnu.cpp.linker.option.shared_flag.core.1017885244" name="Linker.Shared" superClass="sbi.gnu.cpp.linker.option.shared_flag.core" valueType="boolean"/>
                                                                <option defaultValue="false" id="sbi.gnu.cpp.linker.option.noundefined.core.219138009" name="Report unresolved symbol references (-Wl,--no-undefined)" superClass="sbi.gnu.cpp.linker.option.noundefined.core" valueType="boolean"/>
                                                                <option id="sbi.gnu.cpp.linker.option.frameworks_lflags.core.588492684" name="Tizen-Frameworks-Other-Lflags" superClass="sbi.gnu.cpp.linker.option.frameworks_lflags.core" valueType="stringList">
-                                                                       <listOptionValue builtIn="false" value="$(TC_LINKER_MISC)"/>
-                                                                       <listOptionValue builtIn="false" value="$(RS_LINKER_MISC)"/>
+                                                                       <listOptionValue builtIn="false" value="${TC_LINKER_MISC}"/>
+                                                                       <listOptionValue builtIn="false" value="${RS_LINKER_MISC}"/>
                                                                        <listOptionValue builtIn="false" value="-pie -lpthread "/>
-                                                                       <listOptionValue builtIn="false" value="--sysroot=&quot;$(SBI_SYSROOT)&quot;"/>
-                                                                       <listOptionValue builtIn="false" value="-Xlinker --version-script=&quot;$(PROJ_PATH)/.exportMap&quot;"/>
-                                                                       <listOptionValue builtIn="false" value="-L&quot;$(SBI_SYSROOT)/usr/lib&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="--sysroot=&quot;${SBI_SYSROOT}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="-Xlinker --version-script=&quot;${PROJ_PATH}/.exportMap&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="-L&quot;${SBI_SYSROOT}/usr/lib&quot;"/>
                                                                        <listOptionValue builtIn="false" value="$(RS_LIBRARIES)"/>
                                                                </option>
                                                                <option id="gnu.cpp.link.option.paths.1778755627" name="Library search path (-L)" superClass="gnu.cpp.link.option.paths" valueType="libPaths">
                                        <sourceEntries>
                                                <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="inc"/>
                                                <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="res"/>
-                                               <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="shared"/>
                                                <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="ucl/inc"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="ucl/src"/>
                                        </sourceEntries>
                                </configuration>
                        </storageModule>
                                                        <targetPlatform binaryParser="org.eclipse.cdt.core.ELF" id="org.tizen.nativeide.target.sbi.gnu.platform.base.1547247838" osList="linux,win32" superClass="org.tizen.nativeide.target.sbi.gnu.platform.base"/>
                                                        <builder buildPath="${workspace_loc:/call-ui}/Release" id="org.tizen.nativecore.target.sbi.gnu.builder.1410224621" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Tizen Application Builder" superClass="org.tizen.nativecore.target.sbi.gnu.builder"/>
                                                        <tool id="org.tizen.nativecore.tool.sbi.gnu.archiver.519529023" name="Archiver" superClass="org.tizen.nativecore.tool.sbi.gnu.archiver"/>
-                                                       <tool command="clang++" id="org.tizen.nativecore.tool.sbi.gnu.cpp.compiler.2053654917" name="C++ Compiler" superClass="org.tizen.nativecore.tool.sbi.gnu.cpp.compiler">
+                                                       <tool command="i386-linux-gnueabi-g++" id="org.tizen.nativecore.tool.sbi.gnu.cpp.compiler.2053654917" name="C++ Compiler" superClass="org.tizen.nativecore.tool.sbi.gnu.cpp.compiler">
                                                                <option id="gnu.cpp.compiler.option.optimization.level.1574455899" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
                                                                <option defaultValue="gnu.cpp.compiler.debugging.level.none" id="sbi.gnu.cpp.compiler.option.debugging.level.core.1268930725" name="Debug level" superClass="sbi.gnu.cpp.compiler.option.debugging.level.core" valueType="enumerated"/>
                                                                <option defaultValue="false" id="sbi.gnu.cpp.compiler.option.misc.pic.core.1954110782" name="-fPIC option" superClass="sbi.gnu.cpp.compiler.option.misc.pic.core" valueType="boolean"/>
                                                                <option id="sbi.gnu.cpp.compiler.option.1348701994" name="Tizen-Target" superClass="sbi.gnu.cpp.compiler.option" valueType="userObjs">
-                                                                       <listOptionValue builtIn="false" value="wearable-3.0-emulator.core_llvm37.i386.core.app"/>
+                                                                       <listOptionValue builtIn="false" value="wearable-3.0-emulator.core_gcc49.i386.core.app"/>
                                                                </option>
                                                                <option id="sbi.gnu.cpp.compiler.option.frameworks_inc.core.1432667313" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.cpp.compiler.option.frameworks_inc.core" valueType="includePath">
                                                                        <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/libxml2&quot;"/>
                                                                </option>
                                                                <option id="gnu.cpp.compiler.option.include.paths.382544999" name="Include paths (-I)" superClass="gnu.cpp.compiler.option.include.paths" valueType="includePath">
                                                                        <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/ucl/inc}&quot;"/>
                                                                </option>
                                                                <option id="sbi.gnu.cpp.compiler.option.frameworks.core.863139267" name="Tizen-Frameworks" superClass="sbi.gnu.cpp.compiler.option.frameworks.core" valueType="userObjs">
                                                                        <listOptionValue builtIn="false" value="Native_API"/>
                                                                </option>
                                                                <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1592357038" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
                                                        </tool>
-                                                       <tool command="clang" id="org.tizen.nativecore.tool.sbi.gnu.c.compiler.2007452919" name="C Compiler" superClass="org.tizen.nativecore.tool.sbi.gnu.c.compiler">
+                                                       <tool command="i386-linux-gnueabi-gcc" id="org.tizen.nativecore.tool.sbi.gnu.c.compiler.2007452919" name="C Compiler" superClass="org.tizen.nativecore.tool.sbi.gnu.c.compiler">
                                                                <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.option.optimization.level.1436418716" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" valueType="enumerated"/>
                                                                <option defaultValue="gnu.c.debugging.level.default" id="sbi.gnu.c.compiler.option.debugging.level.core.1220862817" name="Debug level" superClass="sbi.gnu.c.compiler.option.debugging.level.core" valueType="enumerated"/>
                                                                <option defaultValue="false" id="sbi.gnu.c.compiler.option.misc.pic.core.1659164857" name="-fPIC option" superClass="sbi.gnu.c.compiler.option.misc.pic.core" valueType="boolean"/>
                                                                <option id="sbi.gnu.c.compiler.option.207590264" name="Tizen-Target" superClass="sbi.gnu.c.compiler.option" valueType="userObjs">
-                                                                       <listOptionValue builtIn="false" value="wearable-3.0-emulator.core_llvm37.i386.core.app"/>
+                                                                       <listOptionValue builtIn="false" value="wearable-3.0-emulator.core_gcc49.i386.core.app"/>
                                                                </option>
                                                                <option id="sbi.gnu.c.compiler.option.frameworks_inc.core.1440527129" name="Tizen-Frameworks-Include-Path" superClass="sbi.gnu.c.compiler.option.frameworks_inc.core" valueType="includePath">
                                                                        <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/libxml2&quot;"/>
                                                                </option>
                                                                <option id="gnu.c.compiler.option.include.paths.1553190282" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
                                                                        <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/inc}&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/libxml2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/EGL&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/GLES&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/GLES2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/GLES3&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/KHR&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/SDL2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/appcore-agent&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/appcore-watch&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/appfw&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/badge&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/base&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/cairo&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/calendar-service2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/chromium-ewk&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ckm&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/contacts-svc&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/content&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/context-service&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/csr&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/dali&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/dali-toolkit&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/dbus-1.0&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/device&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/dlog&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-buffer-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-con-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-evas-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-file-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-imf-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-imf-evas-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-input-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-input-evas-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ecore-ipc-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ector-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/e_dbus-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/edje-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eet-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/efl-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/efl-extension&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/efreet-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eina-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eina-1/eina&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eio-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eldbus-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/elementary-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/embryo-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/emile-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eo-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/eom&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ethumb-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ethumb-client-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/evas-1&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/feedback&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/fontconfig&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/freetype2&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/gio-unix-2.0&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/glib-2.0&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/harfbuzz&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/iotcon&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/json-glib-1.0&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/location&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/maps&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/media&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/media-content&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/messaging&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/metadata-editor&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/minizip&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/network&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/notification&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/nsd/&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/phonenumber-utils&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/sensor&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/storage&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/system&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/telephony&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/tzsh&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/ui&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/vulkan&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/widget_service&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/widget_viewer_dali&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/widget_viewer_evas&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/include/yaca&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/lib/dbus-1.0/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${SBI_SYSROOT}/usr/lib/glib-2.0/include&quot;"/>
+                                                                       <listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/ucl/inc}&quot;"/>
                                                                </option>
                                                                <option id="sbi.gnu.c.compiler.option.frameworks.core.1251626395" name="Tizen-Frameworks" superClass="sbi.gnu.c.compiler.option.frameworks.core" valueType="userObjs">
                                                                        <listOptionValue builtIn="false" value="Native_API"/>
                                                                <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1638821188" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
                                                        </tool>
                                                        <tool id="org.tizen.nativeide.tool.sbi.gnu.c.linker.base.1576764897" name="C Linker" superClass="org.tizen.nativeide.tool.sbi.gnu.c.linker.base"/>
-                                                       <tool command="clang++" id="org.tizen.nativecore.tool.sbi.gnu.cpp.linker.1286451421" name="C++ Linker" superClass="org.tizen.nativecore.tool.sbi.gnu.cpp.linker">
+                                                       <tool command="i386-linux-gnueabi-g++" id="org.tizen.nativecore.tool.sbi.gnu.cpp.linker.1286451421" name="C++ Linker" superClass="org.tizen.nativecore.tool.sbi.gnu.cpp.linker">
                                                                <option defaultValue="false" id="sbi.gnu.cpp.linker.option.shared_flag.core.1339073080" name="Linker.Shared" superClass="sbi.gnu.cpp.linker.option.shared_flag.core" valueType="boolean"/>
                                                                <option defaultValue="false" id="sbi.gnu.cpp.linker.option.noundefined.core.515331444" name="Report unresolved symbol references (-Wl,--no-undefined)" superClass="sbi.gnu.cpp.linker.option.noundefined.core" valueType="boolean"/>
                                                                <option id="sbi.gnu.cpp.linker.option.frameworks_lflags.core.101022172" name="Tizen-Frameworks-Other-Lflags" superClass="sbi.gnu.cpp.linker.option.frameworks_lflags.core" valueType="stringList">
                                        <sourceEntries>
                                                <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="inc"/>
                                                <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="res"/>
-                                               <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="shared"/>
                                                <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="src"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="ucl/inc"/>
+                                               <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="ucl/src"/>
                                        </sourceEntries>
                                </configuration>
                        </storageModule>
                </scannerConfigBuildInfo>
        </storageModule>
        <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
-       <storageModule moduleId="refreshScope"/>
+       <storageModule moduleId="refreshScope" versionNumber="2">
+               <configuration configurationName="Multiple configurations">
+                       <resource resourceType="PROJECT" workspacePath="/call-ui"/>
+               </configuration>
+               <configuration configurationName="Debug">
+                       <resource resourceType="PROJECT" workspacePath="/call-ui"/>
+               </configuration>
+               <configuration configurationName="Release">
+                       <resource resourceType="PROJECT" workspacePath="/call-ui"/>
+               </configuration>
+       </storageModule>
 </cproject>
diff --git a/ucl/inc/ucl/appfw/IInstance.h b/ucl/inc/ucl/appfw/IInstance.h
new file mode 100644 (file)
index 0000000..7d69f33
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __UCL_APPFW_I_INSTANCE_H__
+#define __UCL_APPFW_I_INSTANCE_H__
+
+#include "IInstanceContext.h"
+
+namespace ucl {
+
+       class IInstance;
+       using IInstanceUPtr = std::unique_ptr<IInstance>;
+
+       class IInstance : public Polymorphic {
+       public:
+               virtual Result onCreate(IInstanceContext *context) = 0;
+               virtual void onPause() = 0;
+               virtual void onResume() = 0;
+       };
+}
+
+#endif // __UCL_APPFW_I_INSTANCE_H__
diff --git a/ucl/inc/ucl/appfw/IInstanceAppControlExt.h b/ucl/inc/ucl/appfw/IInstanceAppControlExt.h
new file mode 100644 (file)
index 0000000..da05a7f
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __UCL_APPFW_I_INSTANCE_APP_CONTROL_EXT_H__
+#define __UCL_APPFW_I_INSTANCE_APP_CONTROL_EXT_H__
+
+#include "types.h"
+
+namespace ucl {
+
+       class IInstanceAppControlExt : public Polymorphic {
+       public:
+               virtual void onAppControl(app_control_h appControl) = 0;
+       };
+}
+
+#endif // __UCL_APPFW_I_INSTANCE_APP_CONTROL_EXT_H__
diff --git a/ucl/inc/ucl/appfw/IInstanceContext.h b/ucl/inc/ucl/appfw/IInstanceContext.h
new file mode 100644 (file)
index 0000000..59765eb
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __UCL_APPFW_I_INSTANCE_CONTEXT_H__
+#define __UCL_APPFW_I_INSTANCE_CONTEXT_H__
+
+#include "types.h"
+
+#include "ucl/gui/Window.h"
+
+namespace ucl {
+
+       class IInstanceContext : public Polymorphic {
+       public:
+               virtual AppType getAppType() const = 0;
+               virtual WindowSRef getWindow() = 0;
+               virtual void exitApp() = 0;
+       };
+}
+
+#endif // __UCL_APPFW_I_INSTANCE_CONTEXT_H__
diff --git a/ucl/inc/ucl/appfw/InstanceManagerBase.h b/ucl/inc/ucl/appfw/InstanceManagerBase.h
new file mode 100644 (file)
index 0000000..27decbd
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __UCL_APPFW_INSTANCE_MANAGER_BASE_H__
+#define __UCL_APPFW_INSTANCE_MANAGER_BASE_H__
+
+#include "IInstance.h"
+#include "SysEventProvider.h"
+
+namespace ucl {
+
+       class InstanceManagerBase : public Polymorphic {
+       public:
+               InstanceManagerBase(AppParams appParams);
+               virtual ~InstanceManagerBase();
+
+               const AppParams &getAppParams() const;
+
+               void setSysEventProvider(SysEventProviderUPtr provider);
+
+               virtual IInstance *newInstance() const = 0;
+
+       protected:
+               SysEventProvider &getSysEventProvider() const;
+
+       private:
+               const AppParams m_appParams;
+               SysEventProviderUPtr m_sysEventProvider;
+       };
+}
+
+#endif // __UCL_APPFW_INSTANCE_MANAGER_BASE_H__
diff --git a/ucl/inc/ucl/appfw/SysEventProvider.h b/ucl/inc/ucl/appfw/SysEventProvider.h
new file mode 100644 (file)
index 0000000..8223ffe
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef __UCL_APPFW_SYS_EVENT_PROVIDER_H__
+#define __UCL_APPFW_SYS_EVENT_PROVIDER_H__
+
+#include <list>
+
+#include "types.h"
+
+namespace ucl {
+
+       class SysEventProvider : public NonCopyable {
+       public:
+               using EventHandlerAddFunc = int (*)(app_event_handler_h *,
+                               app_event_type_e, app_event_cb, void *);
+               using EventHandlerDelFunc = int (*)(app_event_handler_h);
+
+       public:
+               SysEventProvider(EventHandlerAddFunc addFunc,
+                               EventHandlerDelFunc delFunc);
+               ~SysEventProvider();
+
+               void addEventHandler(SysEventHandler handler);
+               void delEventHandler(SysEventHandler handler);
+
+       private:
+               int addEventHandler(app_event_handler_h *handler,
+                               app_event_type_e appEvent, app_event_cb cb, void *data);
+               int delEventHandler(app_event_handler_h handler);
+
+               void dispatch(SysEvent sysEvent);
+
+       private:
+               class EventProxy;
+               using EventProxies = std::list<EventProxy>;
+
+       private:
+               const EventHandlerAddFunc m_addFunc;
+               const EventHandlerDelFunc m_delFunc;
+               EventProxies m_eventProxies;
+               Event<SysEventHandler> m_event;
+       };
+}
+
+#include "SysEventProvider.hpp"
+
+#endif // __UCL_APPFW_SYS_EVENT_PROVIDER_H__
diff --git a/ucl/inc/ucl/appfw/SysEventProvider.hpp b/ucl/inc/ucl/appfw/SysEventProvider.hpp
new file mode 100644 (file)
index 0000000..8d6708f
--- /dev/null
@@ -0,0 +1,12 @@
+namespace ucl {
+
+       inline void SysEventProvider::addEventHandler(SysEventHandler handler)
+       {
+               m_event += handler;
+       }
+
+       inline void SysEventProvider::delEventHandler(SysEventHandler handler)
+       {
+               m_event -= handler;
+       }
+}
diff --git a/ucl/inc/ucl/appfw/UIApp.h b/ucl/inc/ucl/appfw/UIApp.h
new file mode 100644 (file)
index 0000000..ccd628a
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef __UCL_APPFW_UI_APP_H__
+#define __UCL_APPFW_UI_APP_H__
+
+#include "IInstanceContext.h"
+
+#include "InstanceManagerBase.h"
+
+namespace ucl {
+
+       class UIApp : private IInstanceContext {
+       public:
+               UIApp(InstanceManagerBase &instanceMgr);
+               virtual ~UIApp();
+
+               int run(int argc, char *argv[]);
+
+       private:
+               bool onCreate();
+               void onTerminate();
+               void onPause();
+               void onResume();
+               void onAppControl(app_control_h appControl);
+
+               Result configParams();
+               Result createWindow();
+
+               void initSysEventManager();
+               Result createInstance();
+
+               // IInstanceContext //
+
+               virtual AppType getAppType() const final override;
+               virtual WindowSRef getWindow() final override;
+               virtual void exitApp() final override;
+
+       private:
+               InstanceManagerBase &m_instanceMgr;
+               WindowSRef m_window;
+               IInstanceUPtr m_instance;
+       };
+}
+
+#endif // __UCL_APPFW_UI_APP_H__
diff --git a/ucl/inc/ucl/appfw/types.h b/ucl/inc/ucl/appfw/types.h
new file mode 100644 (file)
index 0000000..17f5b6e
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __UCL_APPFW_TYPES_H__
+#define __UCL_APPFW_TYPES_H__
+
+#include <app_common.h>
+#include <app_control.h>
+
+#include "ucl/util/types.h"
+#include "ucl/util/delegation.h"
+
+#include "ucl/misc/HashMap.h"
+#include "ucl/misc/Event.h"
+
+namespace ucl {
+
+       enum class AppType {
+               UI,
+               WIDGET,
+               WATCH
+       };
+
+       enum class AppParam {
+               BASE_SCALE,
+               ACCELERATION_PREFERENECE,
+               WINDOW_TYPE,
+               WINDOW_NAME
+       };
+
+       using AppParams = HashMap<AppParam, Variant>;
+
+       class SysEventProvider;
+       using SysEventProviderUPtr = std::unique_ptr<SysEventProvider>;
+
+       enum class SysEvent {
+               LANGUAGE_CHANGED,
+               REGION_FMT_CHANGED,
+               LOW_MEMORY,
+               LOW_BATTERY,
+               ORIENTATION_CHANGED,
+               SUSPEND_STATE_CHANGED,
+               UPDATE_REQUESTED
+       };
+
+       using SysEventHandler = Delegate<void(SysEvent)>;
+}
+
+#endif // __UCL_APPFW_TYPES_H__
diff --git a/ucl/inc/ucl/config.h b/ucl/inc/ucl/config.h
new file mode 100644 (file)
index 0000000..588a0ee
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __UCL_CONFIG_H__
+#define __UCL_CONFIG_H__
+
+#ifdef _DEBUG
+#define UCL_DEBUG
+#endif
+
+#define UCL_DEFINE_GET_UCL_RESULT_DATA 1
+
+#define UCL_LOG_LEVEL_VERBOSE 6
+#define UCL_LOG_LEVEL_DEBUG   5
+#define UCL_LOG_LEVEL_INFO    4
+#define UCL_LOG_LEVEL_WARNING 3
+#define UCL_LOG_LEVEL_ERROR   2
+#define UCL_LOG_LEVEL_FATAL   1
+
+#ifdef UCL_DEBUG
+#define UCL_MAX_LOG_LEVEL UCL_LOG_LEVEL_VERBOSE
+#else
+#define UCL_MAX_LOG_LEVEL UCL_LOG_LEVEL_INFO
+#endif
+
+#define UCL_DEFAULT_LOG_TAG "UCL"
+
+#define UCL_INCLUDE_DELEGATION_SHORT_MACRO_H 0
+#define UCL_INCLUDE_SMART_DELEGATION_SHORT_MACRO_H 0
+
+#endif // __UCL_CONFIG_H__
diff --git a/ucl/inc/ucl/gui/EdjeWidget.h b/ucl/inc/ucl/gui/EdjeWidget.h
new file mode 100644 (file)
index 0000000..4724e86
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef __UCL_GUI_EDJE_WIDGET_H__
+#define __UCL_GUI_EDJE_WIDGET_H__
+
+#include "ElmWidget.h"
+
+namespace ucl {
+
+       UCL_DECLARE_REF_ALIASES(EdjeWidget);
+
+       class EdjeWidget : public ElmWidget {
+       public:
+               void setText(const TString &value);
+               void setPartText(EdjePart part, const TString &value);
+
+               TString getText() const;
+               TString getPartText(EdjePart part) const;
+
+               void setContent(Evas_Object *content);
+               void setPartContent(EdjePart part, Evas_Object *content);
+               Evas_Object *unsetContent();
+               Evas_Object *unsetPartContent(EdjePart part);
+
+               Evas_Object *getContent() const;
+               Evas_Object *getPartContent(EdjePart part) const;
+
+               void emitSignal(EdjeSignal signal, EdjeSignalSrc source);
+
+       protected:
+               EdjeWidget(RefCountObjBase *rc, Evas_Object *eo, bool isOwner = false);
+       };
+}
+
+#include "EdjeWidget.hpp"
+
+#endif // __UCL_GUI_EDJE_WIDGET_H__
diff --git a/ucl/inc/ucl/gui/EdjeWidget.hpp b/ucl/inc/ucl/gui/EdjeWidget.hpp
new file mode 100644 (file)
index 0000000..ee75045
--- /dev/null
@@ -0,0 +1,55 @@
+namespace ucl {
+
+       inline EdjeWidget::EdjeWidget(RefCountObjBase *const rc,
+                       Evas_Object *const eo, const bool isOwner) :
+               ElmWidget(rc, eo, isOwner)
+       {
+       }
+
+       inline TString EdjeWidget::getText() const
+       {
+               return elm_object_text_get(getEo());
+       }
+
+       inline TString EdjeWidget::getPartText(const EdjePart part) const
+       {
+               return elm_object_part_text_get(getEo(), part.name);
+       }
+
+       inline void EdjeWidget::setContent(Evas_Object *const content)
+       {
+               elm_object_content_set(getEo(), content);
+       }
+
+       inline void EdjeWidget::setPartContent(const EdjePart part,
+                       Evas_Object *const content)
+       {
+               elm_object_part_content_set(getEo(), part.name, content);
+       }
+
+       inline Evas_Object *EdjeWidget::unsetContent()
+       {
+               return elm_object_content_unset(getEo());
+       }
+
+       inline Evas_Object *EdjeWidget::unsetPartContent(const EdjePart part)
+       {
+               return elm_object_part_content_unset(getEo(), part.name);
+       }
+
+       inline Evas_Object *EdjeWidget::getContent() const
+       {
+               return elm_object_content_get(getEo());
+       }
+
+       inline Evas_Object *EdjeWidget::getPartContent(const EdjePart part) const
+       {
+               return elm_object_part_content_get(getEo(), part.name);
+       }
+
+       inline void EdjeWidget::emitSignal(const EdjeSignal signal,
+                       const EdjeSignalSrc source)
+       {
+               elm_object_signal_emit(getEo(), signal.name, source.name);
+       }
+}
diff --git a/ucl/inc/ucl/gui/ElmWidget.h b/ucl/inc/ucl/gui/ElmWidget.h
new file mode 100644 (file)
index 0000000..108bbd5
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef __UCL_GUI_ELM_WIDGET_H__
+#define __UCL_GUI_ELM_WIDGET_H__
+
+#include "Widget.h"
+
+namespace ucl {
+
+       UCL_DECLARE_REF_ALIASES(ElmWidget);
+
+       class ElmWidget : public Widget {
+       public:
+               friend class RefCountObj<ElmWidget>;
+               using Widget::Widget;
+
+               void setEnabled(bool value);
+               bool isEnabled() const;
+
+       protected:
+               virtual void setFocusedImpl(bool value) final override;
+               virtual bool isFocusedImpl() const final override;
+       };
+
+       // Non-member functions //
+
+       void enable(ElmWidget &widget);
+       void disable(ElmWidget &widget);
+}
+
+#include "ElmWidget.hpp"
+
+#endif // __UCL_GUI_ELM_WIDGET_H__
diff --git a/ucl/inc/ucl/gui/ElmWidget.hpp b/ucl/inc/ucl/gui/ElmWidget.hpp
new file mode 100644 (file)
index 0000000..3febf5f
--- /dev/null
@@ -0,0 +1,24 @@
+namespace ucl {
+
+       inline void ElmWidget::setEnabled(const bool value)
+       {
+               elm_object_disabled_set(getEo(), toEina(!value));
+       }
+
+       inline bool ElmWidget::isEnabled() const
+       {
+               return !elm_object_disabled_get(getEo());
+       }
+
+       // Non-member functions //
+
+       inline void enable(ElmWidget &widget)
+       {
+               widget.setEnabled(true);
+       }
+
+       inline void disable(ElmWidget &widget)
+       {
+               widget.setEnabled(false);
+       }
+}
diff --git a/ucl/inc/ucl/gui/Layout.h b/ucl/inc/ucl/gui/Layout.h
new file mode 100644 (file)
index 0000000..a068416
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __UCL_GUI_LAYOUT_H__
+#define __UCL_GUI_LAYOUT_H__
+
+#include "EdjeWidget.h"
+
+namespace ucl {
+
+       UCL_DECLARE_REF_ALIASES(Layout);
+
+       class Layout : public EdjeWidget {
+       public:
+               class Builder {
+               public:
+                       Builder();
+                       Builder &setTheme(const LayoutTheme &value);
+                       Builder &setEdjeFile(std::string filePath, EdjeGroup group);
+                       Builder &setIsOwner(bool value);
+                       Builder &setNeedBindToEo(bool value);
+                       LayoutSRef build(Widget &parent) const;
+               private:
+                       LayoutTheme m_theme;
+                       std::string m_edjeFilePath;
+                       EdjeGroup m_edjeGroup;
+                       bool m_isOwner;
+                       bool m_needBindToEo;
+               };
+
+       public:
+               friend class RefCountObj<Layout>;
+               using EdjeWidget::EdjeWidget;
+               explicit Layout(Evas_Object *eo, bool isOwner = false);
+
+               void setTheme(const LayoutTheme &theme);
+               void setEdjeFile(const std::string &filePath, EdjeGroup group);
+       };
+}
+
+#include "Layout.hpp"
+
+#endif // __UCL_GUI_LAYOUT_H__
diff --git a/ucl/inc/ucl/gui/Layout.hpp b/ucl/inc/ucl/gui/Layout.hpp
new file mode 100644 (file)
index 0000000..bfad60c
--- /dev/null
@@ -0,0 +1,54 @@
+namespace ucl {
+
+       // Layout::Builder //
+
+       inline Layout::Builder::Builder() :
+               m_isOwner(false),
+               m_needBindToEo(true)
+       {
+       }
+
+       inline Layout::Builder &Layout::Builder::setTheme(const LayoutTheme &theme)
+       {
+               m_theme = theme;
+               return *this;
+       }
+
+       inline Layout::Builder &Layout::Builder::setEdjeFile(
+                       std::string filePath, const EdjeGroup group)
+       {
+               m_edjeFilePath = std::move(filePath);
+               m_edjeGroup = group;
+               return *this;
+       }
+
+       inline Layout::Builder &Layout::Builder::setIsOwner(const bool value)
+       {
+               m_isOwner = value;
+               return *this;
+       }
+
+       inline Layout::Builder &Layout::Builder::setNeedBindToEo(const bool value)
+       {
+               m_needBindToEo = value;
+               return *this;
+       }
+
+       // Layout //
+
+       inline Layout::Layout(Evas_Object *const eo, const bool isOwner) :
+               EdjeWidget(nullptr, eo, isOwner)
+       {
+       }
+
+       inline void Layout::setTheme(const LayoutTheme &theme)
+       {
+               elm_layout_theme_set(getEo(), theme.klass, theme.group, theme.style);
+       }
+
+       inline void Layout::setEdjeFile(const std::string &filePath,
+                       const EdjeGroup group)
+       {
+               elm_layout_file_set(getEo(), filePath.c_str(), group.name);
+       }
+}
diff --git a/ucl/inc/ucl/gui/NaviItem.h b/ucl/inc/ucl/gui/NaviItem.h
new file mode 100644 (file)
index 0000000..941d510
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef __UCL_GUI_NAVI_ITEM_H__
+#define __UCL_GUI_NAVI_ITEM_H__
+
+#include "WidgetItem.h"
+
+namespace ucl {
+
+       class NaviItem : public WidgetItem {
+       public:
+               using PopHandler = Delegate<Eina_Bool(Elm_Object_Item *)>;
+
+       public:
+               using WidgetItem::WidgetItem;
+
+               void setPopHandler(const PopHandler &handler) const;
+
+               void popTo() const;
+               void promote() const;
+
+               void setTitleEnabled(bool value, bool useTransition = false) const;
+               bool isTitleEnabled() const;
+
+               void setTitle(const TString &title) const;
+       };
+}
+
+#include "NaviItem.hpp"
+
+#endif // __UCL_GUI_NAVI_ITEM_H__
diff --git a/ucl/inc/ucl/gui/NaviItem.hpp b/ucl/inc/ucl/gui/NaviItem.hpp
new file mode 100644 (file)
index 0000000..db2705b
--- /dev/null
@@ -0,0 +1,40 @@
+namespace ucl {
+
+       inline void NaviItem::setPopHandler(const PopHandler &handler) const
+       {
+               elm_naviframe_item_pop_cb_set(getIt(),
+                               handler.getStubA(), handler.getData());
+       }
+
+       inline void NaviItem::popTo() const
+       {
+               elm_naviframe_item_pop_to(getIt());
+       }
+
+       inline void NaviItem::promote() const
+       {
+               elm_naviframe_item_promote(getIt());
+       }
+
+       inline void NaviItem::setTitleEnabled(
+                       const bool value, const bool useTransition) const
+       {
+               elm_naviframe_item_title_enabled_set(getIt(),
+                               toEina(value), toEina(useTransition));
+       }
+
+       inline bool NaviItem::isTitleEnabled() const
+       {
+               return elm_naviframe_item_title_enabled_get(getIt());
+       }
+
+       inline void NaviItem::setTitle(const TString &title) const
+       {
+               if (isEmpty(title)) {
+                       setTitleEnabled(false);
+               } else {
+                       setText(title);
+                       setTitleEnabled(true);
+               }
+       }
+}
diff --git a/ucl/inc/ucl/gui/Naviframe.h b/ucl/inc/ucl/gui/Naviframe.h
new file mode 100644 (file)
index 0000000..0f2aa2a
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __UCL_GUI_NAVIFRAME_H__
+#define __UCL_GUI_NAVIFRAME_H__
+
+#include <vector>
+
+#include "StyledWidget.h"
+#include "NaviItem.h"
+
+namespace ucl {
+
+       UCL_DECLARE_REF_ALIASES(Naviframe);
+
+       class Naviframe : public StyledWidget {
+       public:
+               static constexpr SmartEvent TRANSITION_FINISHED {"transition,finished"};
+
+               class Builder {
+               public:
+                       Builder();
+                       Builder &setStyle(ElmStyle value);
+                       Builder &setIsOwner(bool value);
+                       Builder &setNeedBindToEo(bool value);
+                       NaviframeSRef build(Widget &parent) const;
+               private:
+                       ElmStyle m_style;
+                       bool m_isOwner;
+                       bool m_needBindToEo;
+               };
+
+       public:
+               friend class RefCountObj<Naviframe>;
+               using StyledWidget::StyledWidget;
+
+               void setAutoBackBtn(bool value);
+               bool isAutoBackBtn() const;
+
+               void setPreservePop(bool value);
+               bool isPreservePop() const;
+
+               void setEventsEnabledOnTransition(bool value);
+               bool isEventsEnabledOnTransition() const;
+
+               Evas_Object *pop();
+
+               NaviItem push(const TString &title, Evas_Object *backBtn,
+                               Evas_Object *moreBtn, Evas_Object *content, ElmStyle style);
+               NaviItem push(const TString &title, Evas_Object *content);
+               NaviItem push(Evas_Object *content);
+
+               NaviItem insertAfter(const TString &title, NaviItem after,
+                               Evas_Object *backBtn, Evas_Object *moreBtn,
+                               Evas_Object *content, ElmStyle style);
+               NaviItem insertAfter(const TString &title, NaviItem after,
+                               Evas_Object *content);
+               NaviItem insertAfter(NaviItem after,
+                               Evas_Object *content);
+
+               NaviItem insertBefore(const TString &title, NaviItem before,
+                               Evas_Object *backBtn, Evas_Object *moreBtn,
+                               Evas_Object *content, ElmStyle style);
+               NaviItem insertBefore(const TString &title, NaviItem before,
+                               Evas_Object *content);
+               NaviItem insertBefore(NaviItem before,
+                               Evas_Object *content);
+
+               NaviItem getTopItem()const;
+               NaviItem getBottomItem() const;
+               std::vector<NaviItem> getItems() const;
+       };
+}
+
+#include "Naviframe.hpp"
+
+#endif // __UCL_GUI_NAVIFRAME_H__
diff --git a/ucl/inc/ucl/gui/Naviframe.hpp b/ucl/inc/ucl/gui/Naviframe.hpp
new file mode 100644 (file)
index 0000000..7141377
--- /dev/null
@@ -0,0 +1,161 @@
+namespace ucl {
+
+       // Naviframe::Builder //
+
+       inline Naviframe::Builder::Builder() :
+               m_isOwner(false),
+               m_needBindToEo(true)
+       {
+       }
+
+       inline Naviframe::Builder &Naviframe::Builder::setStyle(
+                       const ElmStyle value)
+       {
+               m_style = value;
+               return *this;
+       }
+
+       inline Naviframe::Builder &Naviframe::Builder::setIsOwner(const bool value)
+       {
+               m_isOwner = value;
+               return *this;
+       }
+
+       inline Naviframe::Builder &Naviframe::Builder::setNeedBindToEo(
+                       const bool value)
+       {
+               m_needBindToEo = value;
+               return *this;
+       }
+
+       // Naviframe //
+
+       inline void Naviframe::setAutoBackBtn(const bool value)
+       {
+               elm_naviframe_prev_btn_auto_pushed_set(getEo(), toEina(value));
+       }
+
+       inline bool Naviframe::isAutoBackBtn() const
+       {
+               return elm_naviframe_prev_btn_auto_pushed_get(getEo());
+       }
+
+       inline void Naviframe::setPreservePop(const bool value)
+       {
+               elm_naviframe_content_preserve_on_pop_set(getEo(), toEina(value));
+       }
+
+       inline bool Naviframe::isPreservePop() const
+       {
+               return elm_naviframe_content_preserve_on_pop_get(getEo());
+       }
+
+       inline void Naviframe::setEventsEnabledOnTransition(const bool value)
+       {
+               elm_naviframe_event_enabled_set(getEo(), toEina(value));
+       }
+
+       inline bool Naviframe::isEventsEnabledOnTransition() const
+       {
+               return elm_naviframe_event_enabled_get(getEo());
+       }
+
+       inline Evas_Object *Naviframe::pop()
+       {
+               return elm_naviframe_item_pop(getEo());
+       }
+
+       inline NaviItem Naviframe::push(const TString &title,
+                       Evas_Object *const backBtn, Evas_Object *const moreBtn,
+                       Evas_Object *const content, const ElmStyle style)
+       {
+               auto result = NaviItem(elm_naviframe_item_push(getEo(),
+                               nullptr, backBtn, moreBtn, content, style.name));
+               result.setTitle(title);
+               return result;
+       }
+
+       inline NaviItem Naviframe::push(const TString &title,
+                       Evas_Object *const content)
+       {
+               return push(title, nullptr, nullptr, content, nullptr);
+       }
+
+       inline NaviItem Naviframe::push(Evas_Object *const content)
+       {
+               return push(nullptr, nullptr, nullptr, content, nullptr);
+       }
+
+       inline NaviItem Naviframe::insertAfter(const TString &title,
+                       NaviItem after,
+                       Evas_Object *const backBtn, Evas_Object *const moreBtn,
+                       Evas_Object *const content, const ElmStyle style)
+       {
+               auto result = NaviItem(elm_naviframe_item_insert_after(getEo(),
+                               after, nullptr, backBtn, moreBtn, content, style.name));
+               result.setTitle(title);
+               return result;
+       }
+
+       inline NaviItem Naviframe::insertAfter(const TString &title,
+                       NaviItem after, Evas_Object *const content)
+       {
+               return insertAfter(title, after, nullptr, nullptr, content, nullptr);
+       }
+
+       inline NaviItem Naviframe::insertAfter(NaviItem after,
+                       Evas_Object *const content)
+       {
+               return insertAfter(nullptr, after, nullptr, nullptr, content, nullptr);
+       }
+
+       inline NaviItem Naviframe::insertBefore(const TString &title,
+                       NaviItem before,
+                       Evas_Object *const backBtn, Evas_Object *const moreBtn,
+                       Evas_Object *const content, const ElmStyle style)
+       {
+               auto result = NaviItem(elm_naviframe_item_insert_before(getEo(),
+                               before, nullptr, backBtn, moreBtn, content, style.name));
+               result.setTitle(title);
+               return result;
+       }
+
+       inline NaviItem Naviframe::insertBefore(const TString &title,
+                       NaviItem before, Evas_Object *const content)
+       {
+               return insertAfter(title, before, nullptr, nullptr, content, nullptr);
+       }
+
+       inline NaviItem Naviframe::insertBefore(NaviItem before,
+                       Evas_Object *const content)
+       {
+               return insertAfter(nullptr, before, nullptr, nullptr, content, nullptr);
+       }
+
+       inline NaviItem Naviframe::getTopItem()const
+       {
+               return NaviItem(elm_naviframe_top_item_get(getEo()));
+       }
+
+       inline NaviItem Naviframe::getBottomItem() const
+       {
+               return NaviItem(elm_naviframe_bottom_item_get(getEo()));
+       }
+
+       inline std::vector<NaviItem> Naviframe::getItems() const
+       {
+               std::vector<NaviItem> result;
+
+               Eina_List *const items = elm_naviframe_items_get(getEo());
+               Eina_List *l = nullptr;
+               void *data = nullptr;
+
+               EINA_LIST_FOREACH(items, l, data) {
+                       result.emplace_back(static_cast<Elm_Object_Item *>(data));
+               }
+
+               eina_list_free(items);
+
+               return result;
+       }
+}
diff --git a/ucl/inc/ucl/gui/StyledWidget.h b/ucl/inc/ucl/gui/StyledWidget.h
new file mode 100644 (file)
index 0000000..4b8a74c
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __UCL_GUI_STYLED_WIDGET_H__
+#define __UCL_GUI_STYLED_WIDGET_H__
+
+#include "EdjeWidget.h"
+
+namespace ucl {
+
+       UCL_DECLARE_REF_ALIASES(StyledWidget);
+
+       class StyledWidget : public EdjeWidget {
+       public:
+               friend class RefCountObj<StyledWidget>;
+               using EdjeWidget::EdjeWidget;
+               explicit StyledWidget(Evas_Object *eo, bool isOwner = false);
+
+               void setStyle(ElmStyle style);
+       };
+}
+
+#include "StyledWidget.hpp"
+
+#endif // __UCL_GUI_STYLED_WIDGET_H__
diff --git a/ucl/inc/ucl/gui/StyledWidget.hpp b/ucl/inc/ucl/gui/StyledWidget.hpp
new file mode 100644 (file)
index 0000000..033b2aa
--- /dev/null
@@ -0,0 +1,13 @@
+namespace ucl {
+
+       inline StyledWidget::StyledWidget(
+                       Evas_Object *const eo, const bool isOwner) :
+               EdjeWidget(nullptr, eo, isOwner)
+       {
+       }
+
+       inline void StyledWidget::setStyle(const ElmStyle style)
+       {
+               elm_object_style_set(getEo(), style.name);
+       }
+}
diff --git a/ucl/inc/ucl/gui/Widget.h b/ucl/inc/ucl/gui/Widget.h
new file mode 100644 (file)
index 0000000..6003ba9
--- /dev/null
@@ -0,0 +1,126 @@
+#ifndef __UCL_GUI_WIDGET_H__
+#define __UCL_GUI_WIDGET_H__
+
+#include <list>
+
+#include "types.h"
+
+#include "ucl/misc/SharedObject.h"
+
+namespace ucl {
+
+       UCL_DECLARE_REF_ALIASES(Widget);
+
+       class Widget : public SharedObject {
+       public:
+               static constexpr auto EXPAND = EVAS_HINT_EXPAND;
+               static constexpr auto FILL = EVAS_HINT_FILL;
+
+       public:
+               explicit Widget(Evas_Object *eo, bool isOwner = false);
+               virtual ~Widget();
+
+               void bindToEo();
+               void unbindFromEo();
+
+               void setIsOwner(bool value);
+
+               Evas_Object *getEo();
+               const Evas_Object *getEo() const;
+
+               operator Evas_Object *();
+               operator const Evas_Object *() const;
+
+               Evas *getEvas() const;
+
+               void addEventHandler(WidgetEvent event, WidgetEventHandler handler);
+               void addEventHandler(SmartEvent event, WidgetEventHandler handler);
+
+               void delEventHandler(WidgetEvent event, WidgetEventHandler handler);
+               void delEventHandler(SmartEvent event, WidgetEventHandler handler);
+
+               void markForDeletion();
+
+               void setVisible(bool value);
+               bool isVisible() const;
+
+               void setGeometry(int x, int y, int w, int h);
+               void move(int x, int y);
+               void resize(int w, int h);
+
+               void getGeometry(int *x, int *y, int *w, int *h) const;
+
+               void setWeight(double w, double h);
+               void setAlign(double w, double h);
+               void setMin(int w, int h);
+               void setMax(int w, int h);
+
+               void getWeight(double *w, double *h) const;
+               void getAlign(double *w, double *h) const;
+               void getMin(int *w, int *h) const;
+               void getMax(int *w, int *h) const;
+
+               void setFocused(bool value);
+               bool isFocused() const;
+
+       protected:
+               friend class RefCountObj<Widget>;
+               Widget(RefCountObjBase *rc, Evas_Object *eo, bool isOwner = false);
+
+               virtual void setFocusedImpl(bool value);
+               virtual bool isFocusedImpl() const;
+
+       private:
+               class EventProxy;
+               using EventProxies = std::list<EventProxy>;
+               using EventProxiesIt = EventProxies::iterator;
+
+       private:
+               void updateRefs();
+
+               void updateEoRef();
+               bool needKeepEoRef() const;
+               void updateSelfRef();
+               bool needKeepSelfRef() const;
+
+               void setSelfRefUnique(const bool value);
+
+               void onEoFree(Evas *e, Evas_Object *obj, void *event_info);
+
+               void delEventProxy(const EventProxiesIt it);
+
+       protected:
+               // This section MUST be protected!
+               // Signal to RefCountObj<T> to call onUniqueChanged()
+               enum { ENABLE_ON_UNIQUE_CHANGED_DISPATCH };
+               void onUniqueChanged(bool isUnique);
+
+       private:
+               Evas_Object *m_eo;
+               EventProxies m_eventProxies;
+               bool m_isOwner;
+               bool m_isBoundToEo;
+               bool m_isEoRefKept;
+               bool m_isSelfRefKept;
+               bool m_isSelfRefUnique;
+       };
+
+       // Non-member functions //
+
+       void getPosition(const Widget &widget, int &x, int &y);
+       void getSize(const Widget &widget, int &w, int &h);
+
+       void show(Widget &widget);
+       void hide(Widget &widget);
+
+       void focus(Widget &widget);
+       void unfocus(Widget &widget);
+
+       void expand(Widget &widget);
+       void fill(Widget &widget);
+       void expandAndFill(Widget &widget);
+}
+
+#include "Widget.hpp"
+
+#endif // __UCL_GUI_WIDGET_H__
diff --git a/ucl/inc/ucl/gui/Widget.hpp b/ucl/inc/ucl/gui/Widget.hpp
new file mode 100644 (file)
index 0000000..9ab4692
--- /dev/null
@@ -0,0 +1,184 @@
+namespace ucl { namespace { namespace impl {
+
+       constexpr auto WIDGET_DATA_NAME = "__WIDGET_DATA_NAME__";
+}}}
+
+namespace ucl {
+
+       inline Widget::Widget(Evas_Object *const eo, const bool isOwner) :
+               Widget(nullptr, eo, isOwner)
+       {
+       }
+
+       inline void Widget::setIsOwner(const bool value)
+       {
+               if (value != m_isOwner) {
+                       m_isOwner = value;
+                       updateRefs();
+               }
+       }
+
+       inline Evas_Object *Widget::getEo()
+       {
+               return m_eo;
+       }
+
+       inline const Evas_Object *Widget::getEo() const
+       {
+               return m_eo;
+       }
+
+       inline Widget::operator Evas_Object *()
+       {
+               return getEo();
+       }
+
+       inline Widget::operator const Evas_Object *() const
+       {
+               return getEo();
+       }
+
+       inline Evas *Widget::getEvas() const
+       {
+               return evas_object_evas_get(getEo());
+       }
+
+       inline void Widget::markForDeletion()
+       {
+               evas_object_del(getEo());
+       }
+
+       inline void Widget::setVisible(bool value)
+       {
+               if (value) {
+                       evas_object_show(getEo());
+               } else {
+                       evas_object_hide(getEo());
+               }
+       }
+
+       inline bool Widget::isVisible() const
+       {
+               return evas_object_visible_get(getEo());
+       }
+
+       inline void Widget::setGeometry(const int x, const int y,
+                       const int w, const int h)
+       {
+               evas_object_geometry_set(getEo(), x, y, w, h);
+       }
+
+       inline void Widget::move(const int x, const int y)
+       {
+               evas_object_move(getEo(), x, y);
+       }
+
+       inline void Widget::resize(const int w, const int h)
+       {
+               evas_object_resize(getEo(), w, h);
+       }
+
+       inline void Widget::getGeometry(int *const x, int *const y,
+                       int *const w, int *const h) const
+       {
+               evas_object_geometry_get(getEo(), x, y, w, h);
+       }
+
+       inline void Widget::setWeight(const double w, const double h)
+       {
+               evas_object_size_hint_weight_set(getEo(), w, h);
+       }
+
+       inline void Widget::setAlign(const double w, const double h)
+       {
+               evas_object_size_hint_align_set(getEo(), w, h);
+       }
+
+       inline void Widget::setMin(const int w, const int h)
+       {
+               evas_object_size_hint_min_set(getEo(), w, h);
+       }
+
+       inline void Widget::setMax(const int w, const int h)
+       {
+               evas_object_size_hint_max_set(getEo(), w, h);
+       }
+
+       inline void Widget::getWeight(double *const w, double *const h) const
+       {
+               evas_object_size_hint_weight_get(getEo(), w, h);
+       }
+
+       inline void Widget::getAlign(double *const w, double *const h) const
+       {
+               evas_object_size_hint_align_get(getEo(), w, h);
+       }
+
+       inline void Widget::getMin(int *const w, int *const h) const
+       {
+               evas_object_size_hint_min_get(getEo(), w, h);
+       }
+
+       inline void Widget::getMax(int *const w, int *const h) const
+       {
+               evas_object_size_hint_max_get(getEo(), w, h);
+       }
+
+       inline void Widget::setFocused(const bool value)
+       {
+               setFocusedImpl(value);
+       }
+
+       inline bool Widget::isFocused() const
+       {
+               return isFocusedImpl();
+       }
+
+       // Non-member functions //
+
+       inline void getPosition(const Widget &widget, int &x, int &y)
+       {
+               widget.getGeometry(&x, &y, nullptr, nullptr);
+       }
+
+       inline void getSize(const Widget &widget, int &w, int &h)
+       {
+               widget.getGeometry(nullptr, nullptr, &w, &h);
+       }
+
+       inline void show(Widget &widget)
+       {
+               widget.setVisible(true);
+       }
+
+       inline void hide(Widget &widget)
+       {
+               widget.setVisible(false);
+       }
+
+       inline void focus(Widget &widget)
+       {
+               widget.setFocused(true);
+       }
+
+       inline void unfocus(Widget &widget)
+       {
+               widget.setFocused(false);
+       }
+
+       inline void expand(Widget &widget)
+       {
+               widget.setWeight(Widget::EXPAND, Widget::EXPAND);
+       }
+
+       inline void fill(Widget &widget)
+       {
+               widget.setAlign(Widget::FILL, Widget::FILL);
+       }
+
+       inline void expandAndFill(Widget &widget)
+       {
+               expand(widget);
+               fill(widget);
+       }
+}
diff --git a/ucl/inc/ucl/gui/WidgetItem.h b/ucl/inc/ucl/gui/WidgetItem.h
new file mode 100644 (file)
index 0000000..859f324
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef __UCL_GUI_WIDGET_ITEM_H__
+#define __UCL_GUI_WIDGET_ITEM_H__
+
+#include "Widget.h"
+
+namespace ucl {
+
+       class WidgetItem {
+       public:
+               constexpr WidgetItem();
+               constexpr WidgetItem(nullptr_t);
+               explicit WidgetItem(Elm_Object_Item *it);
+
+               Elm_Object_Item *getIt() const;
+
+               operator Elm_Object_Item *() const;
+
+               void setDelCallback(Evas_Smart_Cb cb) const;
+
+               void del();
+
+               void setData(void *data) const;
+               void *getData() const;
+
+               void setEnabled(bool value) const;
+               bool isEnabled() const;
+
+               void setText(const TString &value) const;
+               void setPartText(EdjePart part, const TString &value) const;
+
+               TString getText() const;
+               TString getPartText(EdjePart part) const;
+
+               void setContent(Evas_Object *content) const;
+               void setPartContent(EdjePart part, Evas_Object *content) const;
+               Evas_Object *unsetContent() const;
+               Evas_Object *unsetPartContent(EdjePart part) const;
+
+               Evas_Object *getContent() const;
+               Evas_Object *getPartContent(EdjePart part) const;
+
+               void emitSignal(EdjeSignal signal, EdjeSignalSrc source) const;
+
+       private:
+               Elm_Object_Item *m_it;
+       };
+
+       // Non-member functions //
+
+       void enable(WidgetItem item);
+       void disable(WidgetItem item);
+
+       bool isValid(WidgetItem item);
+}
+
+#include "WidgetItem.hpp"
+
+#endif // __UCL_GUI_WIDGET_ITEM_H__
diff --git a/ucl/inc/ucl/gui/WidgetItem.hpp b/ucl/inc/ucl/gui/WidgetItem.hpp
new file mode 100644 (file)
index 0000000..95c42ad
--- /dev/null
@@ -0,0 +1,122 @@
+namespace ucl {
+
+       constexpr WidgetItem::WidgetItem() :
+               m_it(nullptr)
+       {
+       }
+
+       constexpr WidgetItem::WidgetItem(nullptr_t) :
+               WidgetItem()
+       {
+       }
+
+       inline WidgetItem::WidgetItem(Elm_Object_Item *const it) :
+               m_it(it)
+       {
+       }
+
+       inline Elm_Object_Item *WidgetItem::getIt() const
+       {
+               return m_it;
+       }
+
+       inline WidgetItem::operator Elm_Object_Item *() const
+       {
+               return m_it;
+       }
+
+       inline void WidgetItem::setDelCallback(const Evas_Smart_Cb cb) const
+       {
+               elm_object_item_del_cb_set(getIt(), cb);
+       }
+
+       inline void WidgetItem::del()
+       {
+               elm_object_item_del(m_it);
+               m_it = nullptr;
+       }
+
+       inline void WidgetItem::setData(void *const data) const
+       {
+               elm_object_item_data_set(getIt(), data);
+       }
+
+       inline void *WidgetItem::getData() const
+       {
+               return elm_object_item_data_get(getIt());
+       }
+
+       inline void WidgetItem::setEnabled(const bool value) const
+       {
+               elm_object_item_disabled_set(getIt(), toEina(!value));
+       }
+
+       inline bool WidgetItem::isEnabled() const
+       {
+               return (elm_object_item_disabled_get(getIt()) ? false : true);
+       }
+
+       inline TString WidgetItem::getText() const
+       {
+               return elm_object_item_text_get(getIt());
+       }
+
+       inline TString WidgetItem::getPartText(const EdjePart part) const
+       {
+               return elm_object_item_part_text_get(getIt(), part.name);
+       }
+
+       inline void WidgetItem::setContent(Evas_Object *const content) const
+       {
+               elm_object_item_content_set(getIt(), content);
+       }
+
+       inline void WidgetItem::setPartContent(const EdjePart part,
+                       Evas_Object *const content) const
+       {
+               elm_object_item_part_content_set(getIt(), part.name, content);
+       }
+
+       inline Evas_Object *WidgetItem::unsetContent() const
+       {
+               return elm_object_item_content_unset(getIt());
+       }
+
+       inline Evas_Object *WidgetItem::unsetPartContent(const EdjePart part) const
+       {
+               return elm_object_item_part_content_unset(getIt(), part.name);
+       }
+
+       inline Evas_Object *WidgetItem::getContent() const
+       {
+               return elm_object_item_content_get(getIt());
+       }
+
+       inline Evas_Object *WidgetItem::getPartContent(const EdjePart part) const
+       {
+               return elm_object_item_part_content_get(getIt(), part.name);
+       }
+
+       inline void WidgetItem::emitSignal(const EdjeSignal signal,
+                       const EdjeSignalSrc source) const
+       {
+               elm_object_item_signal_emit(getIt(), signal.name, source.name);
+       }
+
+       // Non-member functions //
+
+       inline void enable(WidgetItem item)
+       {
+               item.setEnabled(true);
+       }
+
+       inline void disable(WidgetItem item)
+       {
+               item.setEnabled(false);
+       }
+
+       inline bool isValid(WidgetItem item)
+       {
+               return !!item.getIt();
+       }
+}
diff --git a/ucl/inc/ucl/gui/Window.h b/ucl/inc/ucl/gui/Window.h
new file mode 100644 (file)
index 0000000..e0d49ed
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef __UCL_GUI_WINDOW_H__
+#define __UCL_GUI_WINDOW_H__
+
+#include <vector>
+
+#include "StyledWidget.h"
+
+namespace ucl {
+
+       UCL_DECLARE_REF_ALIASES(Window);
+
+       class Window : public ElmWidget {
+       public:
+               static constexpr SmartEvent ROTATION_CHANGED {"wm,rotation,changed"};
+
+               enum class Type {
+                       BASIC = ELM_WIN_BASIC
+               };
+
+               class Builder {
+               public:
+                       Builder();
+
+                       Builder &setWinEo(Evas_Object *value);
+
+                       Builder &setType(Type type);
+                       Builder &setName(std::string value);
+
+                       Builder &setTitle(std::string value);
+                       Builder &setSetIndicatorVisible(bool value);
+                       Builder &setRotations(std::vector<int> value);
+
+                       Builder &setIsOwner(bool value);
+                       Builder &setNeedBindToEo(bool value);
+
+                       WindowSRef build() const;
+               private:
+                       std::string m_name;
+                       std::string m_title;
+                       std::vector<int> m_rotations;
+                       Evas_Object *m_winEo;
+                       Type m_type;
+                       bool m_isIndicatorVisible;
+                       bool m_isOwner;
+                       bool m_isOwnerWasSet;
+                       bool m_needBindToEo;
+               };
+
+       public:
+               StyledWidget &getConformant();
+               const StyledWidget &getConformant() const;
+
+               void setTitle(const std::string &title);
+               std::string getTitle() const;
+
+               void setIndicatorVisible(bool value);
+               bool isIndicatorVisible() const;
+
+               bool isRotationsSupported() const;
+               void setRotations(const std::vector<int> &value);
+
+               void lower();
+
+       private:
+               friend class RefCountObj<Window>;
+               Window(RefCountObjBase *rc, Evas_Object *eo,
+                               bool isOwner, Evas_Object *conform);
+
+       private:
+               StyledWidget m_conform;
+       };
+
+       // Non-member functions //
+
+       // Window //
+
+       void showIndicator(Window &win);
+       void hideIndicator(Window &win);
+
+       // Window::Type //
+
+       bool isValid(Window::Type winType);
+}
+
+#include "Window.hpp"
+
+#endif // __UCL_GUI_WINDOW_H__
diff --git a/ucl/inc/ucl/gui/Window.hpp b/ucl/inc/ucl/gui/Window.hpp
new file mode 100644 (file)
index 0000000..eece848
--- /dev/null
@@ -0,0 +1,152 @@
+#include <algorithm>
+
+namespace ucl {
+
+       // Window::Builder //
+
+       inline Window::Builder::Builder() :
+               m_rotations({0}),
+               m_winEo(nullptr),
+               m_type(Type::BASIC),
+               m_isIndicatorVisible(false),
+               m_isOwner(false),
+               m_isOwnerWasSet(false),
+               m_needBindToEo(true)
+       {
+       }
+
+       inline Window::Builder &Window::Builder::setWinEo(Evas_Object *const value)
+       {
+               m_winEo = value;
+               return *this;
+       }
+
+       inline Window::Builder &Window::Builder::setType(const Type type)
+       {
+               m_type = type;
+               return *this;
+       }
+
+       inline Window::Builder &Window::Builder::setName(std::string value)
+       {
+               m_name = std::move(value);
+               return *this;
+       }
+
+       inline Window::Builder &Window::Builder::setTitle(std::string value)
+       {
+               m_title = std::move(value);
+               return *this;
+       }
+
+       inline Window::Builder &Window::Builder::setSetIndicatorVisible(
+                       const bool value)
+       {
+               m_isIndicatorVisible = value;
+               return *this;
+       }
+
+       inline Window::Builder &Window::Builder::setRotations(
+                       std::vector<int> value)
+       {
+               m_rotations = std::move(value);
+               return *this;
+       }
+
+       inline Window::Builder &Window::Builder::setIsOwner(const bool value)
+       {
+               m_isOwner = value;
+               m_isOwnerWasSet = true;
+               return *this;
+       }
+
+       inline Window::Builder &Window::Builder::setNeedBindToEo(const bool value)
+       {
+               m_needBindToEo = value;
+               return *this;
+       }
+
+       // Window //
+
+       inline Window::Window(RefCountObjBase *const rc, Evas_Object *const eo,
+                       const bool isOwner, Evas_Object *const conform) :
+               ElmWidget(rc, eo, isOwner),
+               m_conform(conform)
+       {
+       }
+
+       inline StyledWidget &Window::getConformant()
+       {
+               return m_conform;
+       }
+
+       inline const StyledWidget &Window::getConformant() const
+       {
+               return m_conform;
+       }
+
+       inline void Window::setTitle(const std::string &title)
+       {
+               elm_win_title_set(getEo(), title.c_str());
+       }
+
+       inline std::string Window::getTitle() const
+       {
+               return elm_win_title_get(getEo());
+       }
+
+       inline void Window::setIndicatorVisible(bool value)
+       {
+               if (value) {
+                       elm_win_indicator_mode_set(getEo(), ELM_WIN_INDICATOR_SHOW);
+               } else {
+                       elm_win_indicator_mode_set(getEo(), ELM_WIN_INDICATOR_HIDE);
+               }
+       }
+
+       inline bool Window::isIndicatorVisible() const
+       {
+               return (elm_win_indicator_mode_get(getEo()) == ELM_WIN_INDICATOR_SHOW);
+       }
+
+       inline bool Window::isRotationsSupported() const
+       {
+               return elm_win_wm_rotation_supported_get(getEo());
+       }
+
+       inline void Window::setRotations(const std::vector<int> &value)
+       {
+               elm_win_wm_rotation_available_rotations_set(getEo(),
+                               value.data(), value.size());
+       }
+
+       inline void Window::lower()
+       {
+               elm_win_lower(getEo());
+       }
+
+       // Non-member functions //
+
+       // Window //
+
+       inline void showIndicator(Window &win)
+       {
+               win.setIndicatorVisible(true);
+       }
+
+       inline void hideIndicator(Window &win)
+       {
+               win.setIndicatorVisible(false);
+       }
+
+       // Window::Type //
+
+       inline bool isValid(Window::Type winType)
+       {
+               switch (winType) {
+               case Window::Type::BASIC:
+                       return true;
+               }
+               return false;
+       }
+}
diff --git a/ucl/inc/ucl/gui/helpers.h b/ucl/inc/ucl/gui/helpers.h
new file mode 100644 (file)
index 0000000..68c9ff6
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef __UCL_GUI_HELPERS_H__
+#define __UCL_GUI_HELPERS_H__
+
+#include "Widget.h"
+
+namespace ucl {
+
+       // Converts Evas_Object to Widget pointer //
+
+       Widget *asWidget(Evas_Object *eo);
+       const Widget *asWidget(const Evas_Object *eo);
+
+       // Widget casting functions from Evas_Object //
+
+       template <class WIDGET_TYPE>
+       inline auto staticCast(Evas_Object *eo) ->
+                       decltype(static_cast<WIDGET_TYPE *>(asWidget(eo)))
+       {
+               return static_cast<WIDGET_TYPE *>(asWidget(eo));
+       }
+
+       template <class WIDGET_TYPE>
+       inline auto staticCast(const Evas_Object *eo) ->
+                       decltype(static_cast<WIDGET_TYPE *>(asWidget(eo)))
+       {
+               return static_cast<WIDGET_TYPE *>(asWidget(eo));
+       }
+
+       template <class WIDGET_TYPE>
+       inline auto dynamicCast(Evas_Object *eo) ->
+                       decltype(dynamic_cast<WIDGET_TYPE *>(asWidget(eo)))
+       {
+               return dynamic_cast<WIDGET_TYPE *>(asWidget(eo));
+       }
+
+       template <class WIDGET_TYPE>
+       inline auto dynamicCast(const Evas_Object *eo) ->
+                       decltype(dynamic_cast<WIDGET_TYPE *>(asWidget(eo)))
+       {
+               return dynamic_cast<WIDGET_TYPE *>(asWidget(eo));
+       }
+
+       template <class WIDGET_TYPE>
+       inline auto staticRefCast(Evas_Object *eo) ->
+                       decltype(asShared(staticCast<WIDGET_TYPE>(eo)))
+       {
+               return asShared(staticCast<WIDGET_TYPE>(eo));
+       }
+
+       template <class WIDGET_TYPE>
+       inline auto staticRefCast(const Evas_Object *eo) ->
+                       decltype(asShared(staticCast<WIDGET_TYPE>(eo)))
+       {
+               return asShared(staticCast<WIDGET_TYPE>(eo));
+       }
+
+       template <class WIDGET_TYPE>
+       inline auto dynamicRefCast(Evas_Object *eo) ->
+                       decltype(asShared(dynamicCast<WIDGET_TYPE>(eo)))
+       {
+               return asShared(dynamicCast<WIDGET_TYPE>(eo));
+       }
+
+       template <class WIDGET_TYPE>
+       inline auto dynamicRefCast(const Evas_Object *eo) ->
+                       decltype(asShared(dynamicCast<WIDGET_TYPE>(eo)))
+       {
+               return asShared(dynamicCast<WIDGET_TYPE>(eo));
+       }
+}
+
+#include "helpers.hpp"
+
+#endif // __UCL_GUI_HELPERS_H__
diff --git a/ucl/inc/ucl/gui/helpers.hpp b/ucl/inc/ucl/gui/helpers.hpp
new file mode 100644 (file)
index 0000000..abe3cf6
--- /dev/null
@@ -0,0 +1,15 @@
+namespace ucl {
+
+       inline Widget *asWidget(Evas_Object *eo)
+       {
+               return static_cast<Widget *>(
+                               evas_object_data_get(eo, impl::WIDGET_DATA_NAME));
+
+       }
+
+       inline const Widget *asWidget(const Evas_Object *eo)
+       {
+               return static_cast<const Widget *>(
+                               evas_object_data_get(eo, impl::WIDGET_DATA_NAME));
+       }
+}
diff --git a/ucl/inc/ucl/gui/stdTheme.h b/ucl/inc/ucl/gui/stdTheme.h
new file mode 100644 (file)
index 0000000..ad77e4a
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __UCL_GUI_STD_THEME_H__
+#define __UCL_GUI_STD_THEME_H__
+
+#include "stdTheme/common.h"
+#include "stdTheme/layout.h"
+
+#endif // __UCL_GUI_STD_THEME_H__
diff --git a/ucl/inc/ucl/gui/stdTheme/common.h b/ucl/inc/ucl/gui/stdTheme/common.h
new file mode 100644 (file)
index 0000000..5fbdb0b
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __UCL_GUI_STD_THEME_COMMON_H__
+#define __UCL_GUI_STD_THEME_COMMON_H__
+
+#include "ucl/gui/types.h"
+
+namespace ucl {
+
+       // Styles //
+
+       constexpr ElmStyle STYLE_DEFAULT {"default"};
+
+       // Parts //
+
+       constexpr EdjePart PART_TEXT    {"elm.text"};
+       constexpr EdjePart PART_CONTENT {"elm.swallow.content"};
+}
+
+#endif // __UCL_GUI_STD_THEME_COMMON_H__
diff --git a/ucl/inc/ucl/gui/stdTheme/layout.h b/ucl/inc/ucl/gui/stdTheme/layout.h
new file mode 100644 (file)
index 0000000..6f4144e
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __UCL_GUI_STD_THEME_LAYOUT_H__
+#define __UCL_GUI_STD_THEME_LAYOUT_H__
+
+#include "common.h"
+
+namespace ucl {
+
+       constexpr LayoutTheme LAYOUT_DEFAULT {"layout", "application", "default"};
+}
+
+#endif // __UCL_GUI_STD_THEME_LAYOUT_H__
diff --git a/ucl/inc/ucl/gui/types.h b/ucl/inc/ucl/gui/types.h
new file mode 100644 (file)
index 0000000..f14ea3d
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef __UCL_GUI_TYPES_H__
+#define __UCL_GUI_TYPES_H__
+
+#include <Elementary.h>
+
+#include "ucl/util/types.h"
+#include "ucl/util/memory.h"
+#include "ucl/util/delegation.h"
+
+#include "ucl/misc/smartDelegation.h"
+#include "ucl/misc/Aspect.h"
+#include "ucl/misc/TString.h"
+
+namespace ucl {
+
+       // Aspects //
+
+       struct EdjePart : Aspect<EdjePart> { using Aspect::Aspect; };
+       struct EdjeGroup : Aspect<EdjeGroup> { using Aspect::Aspect; };
+
+       struct EdjeSignal : Aspect<EdjeSignal> { using Aspect::Aspect; };
+       struct EdjeSignalSrc : Aspect<EdjeSignalSrc> { using Aspect::Aspect; };
+
+       struct ElmStyle : Aspect<ElmStyle> { using Aspect::Aspect; };
+
+       struct SmartEvent : Aspect<SmartEvent> { using Aspect::Aspect; };
+
+       // WidgetEventHandler //
+
+       class Widget;
+
+       using WidgetEventHandler =
+                       WeakDelegate<void(Widget &widget, void *eventInfo)>;
+
+       // WidgetEvent //
+
+       enum class WidgetEvent {
+               DEL  = EVAS_CALLBACK_DEL,
+               FREE = EVAS_CALLBACK_FREE,
+
+               MOUSE_IN    = EVAS_CALLBACK_MOUSE_IN,
+               MOUSE_OUT   = EVAS_CALLBACK_MOUSE_OUT,
+               MOUSE_DOWN  = EVAS_CALLBACK_MOUSE_DOWN,
+               MOUSE_UP    = EVAS_CALLBACK_MOUSE_UP,
+               MOUSE_MOVE  = EVAS_CALLBACK_MOUSE_MOVE,
+               MOUSE_WHEEL = EVAS_CALLBACK_MOUSE_WHEEL,
+
+               MULTI_DOWN = EVAS_CALLBACK_MULTI_DOWN,
+               MULTI_UP   = EVAS_CALLBACK_MULTI_UP,
+               MULTI_MOVE = EVAS_CALLBACK_MULTI_MOVE,
+
+               MOVE    = EVAS_CALLBACK_MOVE,
+               RESIZE  = EVAS_CALLBACK_RESIZE,
+               RESTACK = EVAS_CALLBACK_RESTACK,
+
+               CHANGED_SIZE_HINTS = EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+
+               KEY_DOWN  = EVAS_CALLBACK_KEY_DOWN,
+               KEY_UP    = EVAS_CALLBACK_KEY_UP,
+               FOCUS_IN  = EVAS_CALLBACK_FOCUS_IN,
+               FOCUS_OUT = EVAS_CALLBACK_FOCUS_OUT,
+
+               SHOW = EVAS_CALLBACK_SHOW,
+               HIDE = EVAS_CALLBACK_HIDE,
+
+               HOLD = EVAS_CALLBACK_HOLD,
+
+               IMAGE_PRELOADED = EVAS_CALLBACK_IMAGE_PRELOADED
+       };
+
+       // LayoutTheme //
+
+       struct LayoutTheme {
+               const char *klass;
+               const char *group;
+               const char *style;
+
+               constexpr LayoutTheme();
+               constexpr LayoutTheme(nullptr_t);
+               constexpr LayoutTheme(const char *klass,
+                               const char *group, const char *style);
+       };
+
+       // LayoutTheme non-member functions //
+
+       constexpr bool isValid(const LayoutTheme &value);
+}
+
+#include "types.hpp"
+
+#endif // __UCL_GUI_TYPES_H__
diff --git a/ucl/inc/ucl/gui/types.hpp b/ucl/inc/ucl/gui/types.hpp
new file mode 100644 (file)
index 0000000..ed7ba8d
--- /dev/null
@@ -0,0 +1,34 @@
+#include "ucl/util/helpers.h"
+
+namespace ucl {
+
+       // LayoutTheme //
+
+       constexpr LayoutTheme::LayoutTheme() :
+               klass(nullptr),
+               group(nullptr),
+               style(nullptr)
+       {
+       }
+
+       constexpr LayoutTheme::LayoutTheme(nullptr_t) :
+               LayoutTheme()
+       {
+       }
+
+       constexpr LayoutTheme::LayoutTheme(const char *klass,
+                       const char *group, const char *style) :
+               klass(klass),
+               group(group),
+               style(style)
+       {
+       }
+
+       // LayoutTheme non-member functions //
+
+       constexpr bool isValid(const LayoutTheme &value)
+       {
+               return (isNotEmpty(value.klass) && isNotEmpty(value.group) &&
+                                       isNotEmpty(value.style));
+       }
+}
diff --git a/ucl/inc/ucl/misc/Aspect.h b/ucl/inc/ucl/misc/Aspect.h
new file mode 100644 (file)
index 0000000..4a0f782
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef __UCL_MISC_ASPECT_H__
+#define __UCL_MISC_ASPECT_H__
+
+#include "ucl/util/types.h"
+
+namespace ucl {
+
+       template <class CHILD>
+       struct Aspect {
+               const char *name;
+
+               constexpr Aspect();
+               constexpr Aspect(nullptr_t);
+               explicit constexpr Aspect(const char *name);
+
+               constexpr operator const char *() const;
+       };
+
+       // Non-member functions //
+
+       template <class CHILD>
+       constexpr bool isValid(Aspect<CHILD> aspect);
+
+       template <class CHILD>
+       constexpr bool operator==(Aspect<CHILD> lhs, Aspect<CHILD> rhs);
+       template <class CHILD>
+       constexpr bool operator!=(Aspect<CHILD> lhs, Aspect<CHILD> rhs);
+}
+
+#include "Aspect.hpp"
+
+#endif // __UCL_MISC_ASPECT_H__
diff --git a/ucl/inc/ucl/misc/Aspect.hpp b/ucl/inc/ucl/misc/Aspect.hpp
new file mode 100644 (file)
index 0000000..18adcb2
--- /dev/null
@@ -0,0 +1,50 @@
+#include <cstring>
+
+#include "ucl/util/helpers.h"
+
+namespace ucl {
+
+       template <class CHILD>
+       constexpr Aspect<CHILD>::Aspect() :
+               name(nullptr)
+       {
+       }
+
+       template <class CHILD>
+       constexpr Aspect<CHILD>::Aspect(nullptr_t) :
+               Aspect()
+       {
+       }
+
+       template <class CHILD>
+       constexpr Aspect<CHILD>::Aspect(const char *name) :
+               name(name)
+       {
+       }
+
+       template <class CHILD>
+       constexpr Aspect<CHILD>::operator const char *() const
+       {
+               return name;
+       }
+
+       // Non-member functions //
+
+       template <class CHILD>
+       constexpr bool isValid(const Aspect<CHILD> aspect)
+       {
+               return isNotEmpty(aspect);
+       }
+
+       template <class CHILD>
+       constexpr bool operator==(Aspect<CHILD> lhs, Aspect<CHILD> rhs)
+       {
+               return (strCmpSafe(lhs.name, rhs.name) == 0);
+       }
+
+       template <class CHILD>
+       constexpr bool operator!=(Aspect<CHILD> lhs, Aspect<CHILD> rhs)
+       {
+               return (strCmpSafe(lhs.name, rhs.name) != 0);
+       }
+}
diff --git a/ucl/inc/ucl/misc/Event.h b/ucl/inc/ucl/misc/Event.h
new file mode 100644 (file)
index 0000000..5ebc4f8
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef __UCL_MISC_EVENT_H__
+#define __UCL_MISC_EVENT_H__
+
+#include <vector>
+
+#include "ucl/util/types.h"
+
+namespace ucl {
+
+       template <class DELEGATE>
+       class Event {
+       public:
+               Event();
+
+               template <class DELEGATE2>
+               void operator+=(DELEGATE2 &&delegate);
+               template <class DELEGATE2>
+               void operator-=(const DELEGATE2 &delegate);
+
+               bool isEmpty() const;
+
+               template <class ...ARGS>
+               void invoke(ARGS &&...args);
+               template <class PREDICATE, class ...ARGS>
+               void invokePred(PREDICATE &&pred, ARGS &&...args);
+
+       private:
+               template <class DO_INVOKE, class ...ARGS>
+               void invokeImpl(const DO_INVOKE &doInvoke, ARGS &&...args);
+
+               void lock();
+               void unlock();
+               bool isLocked() const;
+
+               void defrag();
+
+       private:
+               std::vector<DELEGATE> m_delegates;
+               int m_lockCount;
+               bool m_isFragmented;
+       };
+}
+
+#include "Event.hpp"
+
+#endif // __UCL_MISC_EVENT_H__
diff --git a/ucl/inc/ucl/misc/Event.hpp b/ucl/inc/ucl/misc/Event.hpp
new file mode 100644 (file)
index 0000000..17c0a53
--- /dev/null
@@ -0,0 +1,140 @@
+#include <algorithm>
+
+namespace ucl { namespace { namespace impl {
+
+       template <class PREDICATE, class DELEGATE, class ...ARGS>
+       auto doInvokePred(PREDICATE &&pred,
+                       const DELEGATE &delegate, ARGS &&...args) ->
+                               decltype(pred(delegate(std::forward<ARGS>(args)...)))
+       {
+               return pred(delegate(std::forward<ARGS>(args)...));
+       }
+
+       template <class DELEGATE, class PREDICATE, class ...ARGS>
+       auto doInvokePred(PREDICATE &&pred,
+                       const DELEGATE &delegate, ARGS &&...args) -> decltype(pred())
+       {
+               delegate(std::forward<ARGS>(args)...);
+               return pred();
+       }
+}}}
+
+namespace ucl {
+
+       template <class DELEGATE>
+       Event<DELEGATE>::Event() :
+               m_lockCount(0),
+               m_isFragmented(false)
+       {
+       }
+
+       template <class DELEGATE>
+       template <class DELEGATE2>
+       void Event<DELEGATE>::operator+=(DELEGATE2 &&delegate)
+       {
+               if (delegate && std::find(m_delegates.begin(), m_delegates.end(),
+                               delegate) == m_delegates.end()) {
+                       m_delegates.emplace_back(std::forward<DELEGATE2>(delegate));
+               }
+       }
+
+       template <class DELEGATE>
+       template <class DELEGATE2>
+       void Event<DELEGATE>::operator-=(const DELEGATE2 &delegate)
+       {
+               const auto it = std::find(
+                               m_delegates.begin(), m_delegates.end(), delegate);
+               if (it != m_delegates.end()) {
+                       if (isLocked()) {
+                               *it = {};
+                               m_isFragmented = true;
+                       } else {
+                               m_delegates.erase(it);
+                       }
+               }
+       }
+
+       template <class DELEGATE>
+       bool Event<DELEGATE>::isEmpty() const
+       {
+               return (isLocked() ? false : m_delegates.empty());
+       }
+
+       template <class DELEGATE>
+       template <class ...ARGS>
+       void Event<DELEGATE>::invoke(ARGS &&...args)
+       {
+               invokeImpl(
+                       [](const DELEGATE &delegate, ARGS &&...args)
+                       {
+                               delegate(std::forward<ARGS>(args)...);
+                               return true;
+                       },
+                       std::forward<ARGS>(args)...);
+       }
+
+       template <class DELEGATE>
+       template <class PREDICATE, class ...ARGS>
+       void Event<DELEGATE>::invokePred(PREDICATE &&pred, ARGS &&...args)
+       {
+               invokeImpl(
+                       [&pred](const DELEGATE &delegate, ARGS &&...args)
+                       {
+                               return impl::doInvokePred(std::forward<PREDICATE>(pred),
+                                               delegate, std::forward<ARGS>(args)...);
+                       },
+                       std::forward<ARGS>(args)...);
+       }
+
+       template <class DELEGATE>
+       template <class DO_INVOKE, class ...ARGS>
+       void Event<DELEGATE>::invokeImpl(const DO_INVOKE &doInvoke, ARGS &&...args)
+       {
+               lock();
+               for (size_t i = 0; i < m_delegates.size(); ++i) {
+                       const auto &delegate = m_delegates[i];
+                       if (delegate) {
+                               if (!doInvoke(delegate, std::forward<ARGS>(args)...)) {
+                                       break;
+                               }
+                       } else {
+                               m_isFragmented = true;
+                       }
+               }
+               unlock();
+               defrag();
+       }
+
+       template <class DELEGATE>
+       void Event<DELEGATE>::lock()
+       {
+               ++m_lockCount;
+       }
+
+       template <class DELEGATE>
+       void Event<DELEGATE>::unlock()
+       {
+               --m_lockCount;
+       }
+
+       template <class DELEGATE>
+       bool Event<DELEGATE>::isLocked() const
+       {
+               return (m_lockCount > 0);
+       }
+
+       template <class DELEGATE>
+       void Event<DELEGATE>::defrag()
+       {
+               if (m_isFragmented) {
+                       m_isFragmented = false;
+                       m_delegates.erase(
+                               std::remove_if(m_delegates.begin(), m_delegates.end(),
+                                       [](const DELEGATE &delegate) -> bool
+                                       {
+                                               return !delegate;
+                                       }),
+                               m_delegates.end());
+               }
+       }
+}
diff --git a/ucl/inc/ucl/misc/HashMap.h b/ucl/inc/ucl/misc/HashMap.h
new file mode 100644 (file)
index 0000000..ac6d455
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __UCL_MISC_HASH_MAP_H__
+#define __UCL_MISC_HASH_MAP_H__
+
+#include <unordered_map>
+
+#include "Variant.h"
+
+namespace ucl {
+
+       template <class KEY, class VALUE>
+       class HashMap;
+
+       template <class VALUE>
+       using Dict = HashMap<std::string, VALUE>;
+
+       using VarDict = Dict<Variant>;
+
+       template <class KEY, class VALUE>
+       class HashMap {
+       public:
+               template <class VALUE2>
+               HashMap &set(const KEY &key, VALUE2 &&value);
+               HashMap &unset(const KEY &key);
+
+               template <class VALUE2>
+               bool get(const KEY &key, VALUE2 &value) const;
+               VALUE get(const KEY &key) const;
+
+       private:
+               template <class ENUM_CLASS>
+               struct EnumClassHash {
+                       size_t operator()(ENUM_CLASS key) const {
+                               return static_cast<size_t>(key);
+                       }
+               };
+
+               using Hash = typename std::conditional<std::is_enum<KEY>::value,
+                               EnumClassHash<KEY>, std::hash<KEY>>::type;
+
+       private:
+               std::unordered_map<KEY, VALUE, Hash> m_map;
+       };
+}
+
+#include "HashMap.hpp"
+
+#endif // __UCL_MISC_HASH_MAP_H__
diff --git a/ucl/inc/ucl/misc/HashMap.hpp b/ucl/inc/ucl/misc/HashMap.hpp
new file mode 100644 (file)
index 0000000..8b64692
--- /dev/null
@@ -0,0 +1,43 @@
+namespace ucl {
+
+       template <class KEY, class VALUE>
+       template <class VALUE2>
+       HashMap<KEY, VALUE> &HashMap<KEY, VALUE>::
+                       set(const KEY &key, VALUE2 &&value)
+       {
+               m_map.emplace(key, std::forward<VALUE2>(value));
+               return *this;
+       }
+
+       template <class KEY, class VALUE>
+       HashMap<KEY, VALUE> &HashMap<KEY, VALUE>::
+                       unset(const KEY &key)
+       {
+               m_map.erase(key);
+               return *this;
+       }
+
+       template <class KEY, class VALUE>
+       template <class VALUE2>
+       bool HashMap<KEY, VALUE>::
+                       get(const KEY &key, VALUE2 &value) const
+       {
+               const auto it = m_map.find(key);
+               if (it == m_map.end()) {
+                       return false;
+               }
+               value = it->second;
+               return true;
+       }
+
+       template <class KEY, class VALUE>
+       VALUE HashMap<KEY, VALUE>::
+                       get(const KEY &key) const
+       {
+               const auto it = m_map.find(key);
+               if (it == m_map.end()) {
+                       return {};
+               }
+               return it->second;
+       }
+}
diff --git a/ucl/inc/ucl/misc/SharedObject.h b/ucl/inc/ucl/misc/SharedObject.h
new file mode 100644 (file)
index 0000000..a62fefd
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __UCL_MISC_SHARED_OBJECT_H__
+#define __UCL_MISC_SHARED_OBJECT_H__
+
+#include "ucl/util/types.h"
+#include "ucl/util/memory.h"
+
+namespace ucl {
+
+       UCL_DECLARE_REF_ALIASES(SharedObject);
+
+       class SharedObject : public NonCopyable {
+       public:
+               template <class T>
+               SharedRef<T> asShared();
+               template <class T>
+               WeakRef<T> asWeak();
+
+               template <class T>
+               SharedRef<const T> asShared() const;
+               template <class T>
+               WeakRef<const T> asWeak() const;
+
+               SharedObjectSRef asShared();
+               SharedObjectWRef asWeak();
+
+               SharedObjectSCRef asShared() const;
+               SharedObjectWCRef asWeak() const;
+
+       protected:
+               SharedObject(RefCountObjBase *rc);
+               ~SharedObject() = default;
+
+       protected:
+               RefCountObjBase *const m_rc;
+       };
+
+       // Non-member functions //
+
+       template <class T>
+       SharedRef<T> asShared(T *obj);
+       template <class T>
+       WeakRef<T> asWeak(T *obj);
+}
+
+#include "SharedObject.hpp"
+
+#endif // __UCL_MISC_SHARED_OBJECT_H__
diff --git a/ucl/inc/ucl/misc/SharedObject.hpp b/ucl/inc/ucl/misc/SharedObject.hpp
new file mode 100644 (file)
index 0000000..75a09a2
--- /dev/null
@@ -0,0 +1,81 @@
+namespace ucl {
+
+       inline SharedObject::SharedObject(RefCountObjBase *const rc) :
+               m_rc(rc)
+       {
+       }
+
+       template <class T>
+       inline SharedRef<T> SharedObject::asShared()
+       {
+               if (!m_rc) {
+                       return {};
+               }
+               return {m_rc, static_cast<T *>(this)};
+       }
+
+       template <class T>
+       inline WeakRef<T> SharedObject::asWeak()
+       {
+               if (!m_rc) {
+                       return {};
+               }
+               return {m_rc, static_cast<T *>(this)};
+       }
+
+       template <class T>
+       inline SharedRef<const T> SharedObject::asShared() const
+       {
+               if (!m_rc) {
+                       return {};
+               }
+               return {m_rc, static_cast<const T *>(this)};
+       }
+
+       template <class T>
+       inline WeakRef<const T> SharedObject::asWeak() const
+       {
+               if (!m_rc) {
+                       return {};
+               }
+               return {m_rc, static_cast<const T *>(this)};
+       }
+
+       inline SharedObjectSRef SharedObject::asShared()
+       {
+               return asShared<SharedObject>();
+       }
+
+       inline SharedObjectWRef SharedObject::asWeak()
+       {
+               return asWeak<SharedObject>();
+       }
+
+       inline SharedObjectSCRef SharedObject::asShared() const
+       {
+               return asShared<SharedObject>();
+       }
+
+       inline SharedObjectWCRef SharedObject::asWeak() const
+       {
+               return asWeak<SharedObject>();
+       }
+
+       // Non-member functions //
+
+       template <class T>
+       inline SharedRef<T> asShared(T *obj)
+       {
+               return (obj ?
+                               obj->asShared<typename std::remove_cv<T>::type>() :
+                               SharedRef<T>());
+       }
+
+       template <class T>
+       inline WeakRef<T> asWeak(T *obj)
+       {
+               return (obj ?
+                               obj->asWeak<typename std::remove_cv<T>::type>() :
+                               WeakRef<T>());
+       }
+}
diff --git a/ucl/inc/ucl/misc/TString.h b/ucl/inc/ucl/misc/TString.h
new file mode 100644 (file)
index 0000000..60e03c8
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef __UCL_MISC_T_STRING_H__
+#define __UCL_MISC_T_STRING_H__
+
+#include "ucl/util/types.h"
+
+namespace ucl {
+
+       class TString {
+       public:
+               TString();
+
+               /**
+                * Constructs TString from std::string and domain
+                *
+                * @param str     Text string or string id if translatable.
+                * @param domain  Valid domain name or "" for default domain,
+                *                nullptr - if string is not translatable
+                */
+               TString(const std::string &str, const char *domain);
+               TString(const std::string &str, bool translatable = false);
+
+               TString(std::string &&str, const char *domain);
+               TString(std::string &&str, bool translatable = false);
+
+               TString(const char *str, const char *domain);
+               TString(const char *str, bool translatable = false);
+
+               bool isEmpty() const;
+
+               bool isTranslatable() const;
+               bool hasDomain() const;
+               const char *getDomain() const;
+
+               const std::string &getStr() const;
+               operator const std::string &() const;
+
+               const char *getCStr() const;
+               operator const char *() const;
+
+               const char *translate() const;
+
+               template <typename ...ARGS>
+               TString format(ARGS ...args) const;
+
+       private:
+               const char *doTranslate(const char *strId) const;
+
+       private:
+               std::string m_str;
+               const char *m_domain;
+       };
+}
+
+#include "TString.hpp"
+
+#endif // __UCL_MISC_T_STRING_H__
diff --git a/ucl/inc/ucl/misc/TString.hpp b/ucl/inc/ucl/misc/TString.hpp
new file mode 100644 (file)
index 0000000..9806848
--- /dev/null
@@ -0,0 +1,130 @@
+#include <libintl.h>
+#include <app_i18n.h>
+
+#include "ucl/util/helpers.h"
+
+namespace ucl {
+
+       inline TString::TString() :
+               m_domain(nullptr)
+       {
+       }
+
+       inline TString::TString(const std::string &str, const char *const domain) :
+               m_str(str),
+               m_domain(m_str.empty() ? nullptr : domain)
+       {
+       }
+
+       inline TString::TString(const std::string &str, const bool translatable) :
+               TString(str, (translatable ? "" : nullptr))
+       {
+       }
+
+       inline TString::TString(std::string &&str, const char *const domain) :
+               m_str(std::move(str)),
+               m_domain(m_str.empty() ? nullptr : domain)
+       {
+       }
+
+       inline TString::TString(std::string &&str, const bool translatable) :
+               TString(std::move(str), (translatable ? "" : nullptr))
+       {
+       }
+
+       inline TString::TString(const char *const str, const char *const domain) :
+               TString(std::string(nz(str)), domain)
+       {
+       }
+
+       inline TString::TString(const char *const str, const bool translatable) :
+               TString(std::string(nz(str)), (translatable ? "" : nullptr))
+       {
+       }
+
+       inline bool TString::isEmpty() const
+       {
+               return m_str.empty();
+       }
+
+       inline const std::string &TString::getStr() const
+       {
+               return m_str;
+       }
+
+       inline TString::operator const std::string &() const
+       {
+               return m_str;
+       }
+
+       inline const char *TString::getCStr() const
+       {
+               return m_str.c_str();
+       }
+
+       inline TString::operator const char *() const
+       {
+               return m_str.c_str();
+       }
+
+       inline bool TString::isTranslatable() const
+       {
+               return (m_domain != nullptr);
+       }
+
+       inline bool TString::hasDomain() const
+       {
+               return isNotEmpty(m_domain);
+       }
+
+       inline const char *TString::getDomain() const
+       {
+               return m_domain;
+       }
+
+       inline const char *TString::translate() const
+       {
+               if (!m_domain) {
+                       return getCStr();
+               }
+               return doTranslate(getCStr());
+       }
+
+       inline const char *TString::doTranslate(const char *const strId) const
+       {
+               if (m_domain[0] == '\0') {
+                       return i18n_get_text(strId);
+               }
+               return dgettext(m_domain, strId);
+       }
+
+       template <typename ...ARGS>
+       inline TString TString::format(ARGS ...args) const
+       {
+               constexpr auto STR_LEN_ADJUST = 1.7f;
+
+               const char *fmt = m_str.c_str();
+               size_t fmtLen = m_str.length();
+
+               if (m_domain) {
+                       fmt = doTranslate(fmt);
+                       fmtLen = strlen(fmt);
+               }
+
+               size_t strLen = static_cast<size_t>(fmtLen * STR_LEN_ADJUST);
+
+               std::string result;
+
+               while (1) {
+                       result.resize(strLen);
+                       const size_t n = snprintf(&result[0], strLen, fmt, args...);
+                       if (n < strLen) {
+                               result.resize(n);
+                               break;
+                       }
+                       strLen = n + 1;
+               }
+
+               return {result, false};
+       }
+}
diff --git a/ucl/inc/ucl/misc/Variant.h b/ucl/inc/ucl/misc/Variant.h
new file mode 100644 (file)
index 0000000..d8e2a37
--- /dev/null
@@ -0,0 +1,148 @@
+#ifndef __UCL_MISC_VARIANT_H__
+#define __UCL_MISC_VARIANT_H__
+
+#include <array>
+#include <vector>
+#include <initializer_list>
+
+#include "ucl/util/types.h"
+
+namespace ucl {
+
+       class Variant;
+
+       using VarVector = std::vector<Variant>;
+
+       template <size_t N>
+       using VarArray = std::array<Variant, N>;
+
+       struct VarInitList {
+               VarInitList(const std::initializer_list<Variant> &il) : il(il) {}
+               const std::initializer_list<Variant> &il;
+       };
+
+       class Variant {
+       public:
+               enum Type {
+                       TYPE_NIL,
+                       TYPE_BOOLEAN,
+                       TYPE_INTEGER,
+                       TYPE_FLOAT,
+                       TYPE_DOUBLE,
+                       TYPE_STRING,
+                       TYPE_ARRAY
+               };
+
+       private:
+               // Helper to wrap "const char *" and manage its lifetime
+               class CStr : NonCopyable {
+               public:
+                       CStr(const char *ptr);
+                       CStr(const char *ptr, bool isOwner) noexcept;
+                       CStr(CStr &&s);
+                       ~CStr() noexcept;
+                       const char *get() const noexcept;
+                       operator const char *() const noexcept;
+               private:
+                       const char *const m_ptr;
+                       bool m_isOwner;
+               };
+
+       public:
+               friend void swap(Variant &x, Variant &y) noexcept;
+
+               friend bool operator==(const Variant &lhs, const Variant &rhs) noexcept;
+               friend bool operator!=(const Variant &lhs, const Variant &rhs) noexcept;
+
+       public:
+               Variant() noexcept;
+               Variant(nullptr_t) noexcept;
+
+               Variant(bool aBool) noexcept;
+               Variant(int anInt) noexcept;
+               Variant(float aFloat) noexcept;
+               Variant(double aDouble) noexcept;
+
+               Variant(const char *aString);
+               Variant(const char *aString, int length);
+               Variant(const std::string &aString);
+
+               Variant(nullptr_t, int arrayLength);
+               Variant(const Variant *anArray, int length);
+               Variant(const VarVector &anArray);
+               template <size_t N>
+               Variant(const VarArray<N> &anArray);
+               Variant(const VarInitList &anArray);
+
+               ~Variant();
+
+               Variant(const Variant &v);
+               Variant(Variant &&v) noexcept;
+
+               Variant &operator=(Variant v);
+
+               Type getType() const noexcept;
+               int getLength() const noexcept;
+               bool isEmpty() const noexcept;
+
+               bool asBool() const noexcept;
+               int asInt() const noexcept;
+               float asFloat() const noexcept;
+               double asDouble() const noexcept;
+
+               CStr asString() const noexcept;
+
+               Variant *asArray() noexcept;
+               const Variant *asArray() const noexcept;
+
+               Variant *begin() noexcept;
+               Variant *end() noexcept;
+               const Variant *begin() const noexcept;
+               const Variant *end() const noexcept;
+
+               Variant &operator[](int index) noexcept;
+               const Variant &operator[](int index) const noexcept;
+
+               explicit operator bool() const noexcept;
+               explicit operator int() const noexcept;
+               explicit operator float() const noexcept;
+               explicit operator double() const noexcept;
+
+               bool operator==(Variant::Type rhs) const noexcept;
+               bool operator!=(Variant::Type rhs) const noexcept;
+
+       private:
+               const char *getStr() const noexcept;
+
+       public:
+               union {
+                       uint8_t m_type;
+                       struct {
+                               uint64_t qw1;
+                               uint64_t qw2;
+                       } m_raw;
+                       struct { uint8_t type; bool value; } m_aBool;
+                       struct { uint8_t type; int value; } m_anInt;
+                       struct { uint8_t type; float value; } m_aFloat;
+                       struct { uint8_t type; double value; } m_aDouble;
+                       struct {
+                               uint8_t type;
+                               char buffer[sizeof(m_raw) - 1];
+                       } m_aSmallStr;
+                       struct {
+                               uint8_t type;
+                               int length;
+                               char *data;
+                       } m_aString;
+                       struct {
+                               uint8_t type;
+                               int length;
+                               Variant *data;
+                       } m_anArray;
+               };
+       };
+}
+
+#include "Variant.hpp"
+
+#endif // __UCL_MISC_VARIANT_H__
diff --git a/ucl/inc/ucl/misc/Variant.hpp b/ucl/inc/ucl/misc/Variant.hpp
new file mode 100644 (file)
index 0000000..4c1dcbb
--- /dev/null
@@ -0,0 +1,272 @@
+#include <cstring>
+
+namespace ucl { namespace { namespace impl {
+
+       constexpr auto TYPE_MASK = 0x0F;
+
+       constexpr auto FLAG_SMALL_STR = 0x80;
+       constexpr auto TYPE_SMALL_STR = (Variant::TYPE_STRING | FLAG_SMALL_STR);
+
+       constexpr auto TMP_STR_BUFF_SIZE = 32;
+}}}
+
+namespace ucl {
+
+       // Variant::CStr //
+
+       inline Variant::CStr::CStr(const char *const ptr) :
+               m_ptr(strdup(ptr)),
+               m_isOwner(true)
+       {
+       }
+
+       inline Variant::CStr::CStr(const char *const ptr,
+                       const bool isOwner) noexcept :
+               m_ptr(ptr),
+               m_isOwner(isOwner)
+       {
+       }
+
+       inline Variant::CStr::CStr(CStr &&s) :
+               m_ptr(s.m_ptr),
+               m_isOwner(s.m_isOwner)
+       {
+               s.m_isOwner = false;
+       }
+
+       inline Variant::CStr::~CStr() noexcept
+       {
+               if (m_isOwner) {
+                       free(const_cast<char *>(m_ptr));
+               }
+       }
+
+       inline const char *Variant::CStr::get() const noexcept
+       {
+               return m_ptr;
+       }
+
+       inline Variant::CStr::operator const char *() const noexcept
+       {
+               return m_ptr;
+       }
+
+       // Variant //
+
+       inline Variant::Variant() noexcept :
+               m_type(TYPE_NIL)
+       {
+       }
+
+       inline Variant::Variant(nullptr_t) noexcept :
+               Variant()
+       {
+       }
+
+       inline Variant::Variant(const bool aBool) noexcept :
+               m_type(TYPE_BOOLEAN)
+       {
+               m_aBool.value = aBool;
+       }
+
+       inline Variant::Variant(const int anInt) noexcept :
+               m_type(TYPE_INTEGER)
+       {
+               m_anInt.value = anInt;
+       }
+
+       inline Variant::Variant(const float aFloat) noexcept :
+               m_type(TYPE_FLOAT)
+       {
+               m_aFloat.value = aFloat;
+       }
+
+       inline Variant::Variant(const double aDouble) noexcept :
+               m_type(TYPE_DOUBLE)
+       {
+               m_aDouble.value = aDouble;
+       }
+
+       inline Variant::Variant(const char *const aString) :
+               Variant(aString, -1)
+       {
+       }
+
+       inline Variant::Variant(const std::string &aString) :
+               Variant(aString.c_str(), aString.size())
+       {
+       }
+
+       inline Variant::Variant(const VarVector &anArray) :
+               Variant(anArray.data(), anArray.size())
+       {
+       }
+
+       template <size_t N>
+       inline Variant::Variant(const VarArray<N> &anArray) :
+               Variant(anArray.data(), anArray.size())
+       {
+       }
+
+       inline Variant::Variant(const VarInitList &anArray) :
+               Variant(anArray.il.begin(), anArray.il.size())
+       {
+       }
+
+       inline Variant::~Variant()
+       {
+               switch (m_type) {
+               case TYPE_STRING:
+                       free(m_aString.data);
+                       break;
+               case TYPE_ARRAY:
+                       delete[] m_anArray.data;
+                       break;
+               }
+       }
+
+       inline Variant::Variant(Variant &&v) noexcept :
+               m_type(v.m_type)
+       {
+               switch (m_type) {
+               case TYPE_NIL:
+                       break;
+               case TYPE_STRING:
+                       m_aString.data = v.m_aString.data;
+                       m_aString.length = v.m_aString.length;
+                       v.m_type = TYPE_NIL;
+                       break;
+               case TYPE_ARRAY:
+                       m_anArray.data = v.m_anArray.data;
+                       m_anArray.length = v.m_anArray.length;
+                       v.m_type = TYPE_NIL;
+                       break;
+               default:
+                       m_raw = v.m_raw;
+                       break;
+               }
+       }
+
+       inline Variant &Variant::operator=(Variant v)
+       {
+               swap(*this, v);
+               return *this;
+       }
+
+       inline Variant::Type Variant::getType() const noexcept
+       {
+               return Type(m_type & impl::TYPE_MASK);
+       }
+
+       inline int Variant::getLength() const noexcept
+       {
+               switch (m_type) {
+               case TYPE_NIL:
+                       return 0;
+               case TYPE_STRING:
+                       return m_aString.length;
+               case TYPE_ARRAY:
+                       return m_anArray.length;
+               case impl::TYPE_SMALL_STR:
+                       return strlen(m_aSmallStr.buffer);
+               }
+               return 1;
+       }
+
+       inline bool Variant::isEmpty() const noexcept
+       {
+               return (getLength() == 0);
+       }
+
+       inline const char *Variant::getStr() const noexcept
+       {
+               return ((m_type == TYPE_STRING) ? m_aString.data : m_aSmallStr.buffer);
+       }
+
+       inline Variant *Variant::asArray() noexcept
+       {
+               return begin();
+       }
+
+       inline const Variant *Variant::asArray() const noexcept
+       {
+               return begin();
+       }
+
+       inline Variant *Variant::begin() noexcept
+       {
+               return ((m_type == TYPE_ARRAY) ? m_anArray.data : this);
+       }
+
+       inline Variant *Variant::end() noexcept
+       {
+               return ((m_type == TYPE_ARRAY) ?
+                               (m_anArray.data + m_anArray.length) : (this + 1));
+       }
+
+       inline const Variant *Variant::begin() const noexcept
+       {
+               return const_cast<Variant *>(this)->begin();
+       }
+
+       inline const Variant *Variant::end() const noexcept
+       {
+               return const_cast<Variant *>(this)->end();
+       }
+
+       inline Variant &Variant::operator[](int index) noexcept
+       {
+               return asArray()[index];
+       }
+
+       inline const Variant &Variant::operator[](int index) const noexcept
+       {
+               return asArray()[index];
+       }
+
+       inline Variant::operator bool() const noexcept
+       {
+               return asBool();
+       }
+
+       inline Variant::operator int() const noexcept
+       {
+               return asInt();
+       }
+
+       inline Variant::operator float() const noexcept
+       {
+               return asFloat();
+       }
+
+       inline Variant::operator double() const noexcept
+       {
+               return asDouble();
+       }
+
+       inline bool Variant::operator==(const Variant::Type rhs) const noexcept
+       {
+               return (m_type == rhs);
+       }
+
+       inline bool Variant::operator!=(const Variant::Type rhs) const noexcept
+       {
+               return (m_type != rhs);
+       }
+
+       // Non-member functions //
+
+       inline void swap(Variant &x, Variant &y) noexcept
+       {
+               static_assert(sizeof(Variant) == sizeof(Variant::m_raw),
+                               "Invalid Variant data structure!");
+               static_assert(std::is_standard_layout<Variant>::value,
+                               "Variant has not standard layout!");
+               std::swap(x.m_raw, y.m_raw);
+       }
+
+       inline bool operator!=(const Variant &lhs, const Variant &rhs) noexcept
+       {
+               return !(lhs == rhs);
+       }
+}
diff --git a/ucl/inc/ucl/misc/smartDelegation.h b/ucl/inc/ucl/misc/smartDelegation.h
new file mode 100644 (file)
index 0000000..6f249a0
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef __UCL_MISC_SMART_DELEGATION_H__
+#define __UCL_MISC_SMART_DELEGATION_H__
+
+#include "smartDelegation/WeakDelegate.h"
+
+#include "smartDelegation/macro.h"
+
+#if (UCL_INCLUDE_SMART_DELEGATION_SHORT_MACRO_H)
+#include "smartDelegation/shortMacro.h"
+#endif
+
+#endif // __UCL_MISC_SMART_DELEGATION_H__
diff --git a/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.h b/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.h
new file mode 100644 (file)
index 0000000..b1792cf
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef __UCL_MISC_SMART_DELEGATION_WEAK_DELEGATE_H__
+#define __UCL_MISC_SMART_DELEGATION_WEAK_DELEGATE_H__
+
+#include "ucl/util/delegation.h"
+#include "ucl/util/memory.h"
+
+namespace ucl {
+
+       template <class FUNC_SIG>
+       class WeakDelegate;
+
+       template <class R, class ...ARGS>
+       class WeakDelegate<R(ARGS...)> :
+                       public BaseDelegate<R(ARGS...), WeakRef<void>> {
+       public:
+               using BaseDelegate<R(ARGS...), WeakRef<void>>::BaseDelegate;
+
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+               static WeakDelegate make(const WeakRef<CLASS> &data) noexcept;
+
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+               static WeakDelegate make(const WeakRef<const CLASS> &data) noexcept;
+       };
+}
+
+#include "WeakDelegate.hpp"
+
+#endif // __UCL_MISC_SMART_DELEGATION_WEAK_DELEGATE_H__
diff --git a/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.hpp b/ucl/inc/ucl/misc/smartDelegation/WeakDelegate.hpp
new file mode 100644 (file)
index 0000000..be7c1ac
--- /dev/null
@@ -0,0 +1,19 @@
+namespace ucl {
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+       inline WeakDelegate<R(ARGS...)> WeakDelegate<R(ARGS...)>::make(
+                       const WeakRef<CLASS> &data) noexcept
+       {
+               return {data, WeakDelegate::Cb::template stubA<CLASS, METHOD>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+       inline WeakDelegate<R(ARGS...)> WeakDelegate<R(ARGS...)>::make(
+                       const WeakRef<const CLASS> &data) noexcept
+       {
+               return {constRefCast<CLASS>(data),
+                               WeakDelegate::Cb::template stubA<CLASS, METHOD>};
+       }
+}
diff --git a/ucl/inc/ucl/misc/smartDelegation/macro.h b/ucl/inc/ucl/misc/smartDelegation/macro.h
new file mode 100644 (file)
index 0000000..24ab614
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __UCL_MISC_SMART_DELEGATION_MACRO_H__
+#define __UCL_MISC_SMART_DELEGATION_MACRO_H__
+
+#define UCL_WEAK_DELEGATE(FUNC, DATA) \
+               _UCL_DELEGATE(::ucl::WeakDelegate, FUNC, DATA)
+
+#endif // __UCL_MISC_SMART_DELEGATION_MACRO_H__
diff --git a/ucl/inc/ucl/misc/smartDelegation/shortMacro.h b/ucl/inc/ucl/misc/smartDelegation/shortMacro.h
new file mode 100644 (file)
index 0000000..3893008
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef __UCL_MISC_SMART_DELEGATION_SHORT_MACRO_H__
+#define __UCL_MISC_SMART_DELEGATION_SHORT_MACRO_H__
+
+#define WEAK_DELEGATE(FUNC, DATA) UCL_WEAK_DELEGATE(FUNC, DATA)
+
+#endif // __UCL_MISC_SMART_DELEGATION_SHORT_MACRO_H__
diff --git a/ucl/inc/ucl/util/delegation.h b/ucl/inc/ucl/util/delegation.h
new file mode 100644 (file)
index 0000000..198c20f
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __UCL_UTIL_DELEGATION_H__
+#define __UCL_UTIL_DELEGATION_H__
+
+#include "delegation/Callback.h"
+
+#include "delegation/BaseDelegate.h"
+#include "delegation/BaseDelegate2.h"
+
+#include "delegation/Delegate.h"
+#include "delegation/Delegate2.h"
+
+#include "delegation/helpers.h"
+#include "delegation/macro.h"
+
+#if (UCL_INCLUDE_DELEGATION_SHORT_MACRO_H)
+#include "delegation/shortMacro.h"
+#endif
+
+#endif // __UCL_UTIL_DELEGATION_H__
diff --git a/ucl/inc/ucl/util/delegation/BaseDelegate.h b/ucl/inc/ucl/util/delegation/BaseDelegate.h
new file mode 100644 (file)
index 0000000..e4307f0
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __UCL_UTIL_DELEGATION_BASE_DELEGATE_H__
+#define __UCL_UTIL_DELEGATION_BASE_DELEGATE_H__
+
+#include "Callback.h"
+
+namespace ucl {
+
+       template <class FUNC_SIG, class DATA>
+       class BaseDelegate;
+
+       template <class FUNC_SIG, class DATA>
+       class BaseDelegate2;
+
+       template <class R, class ...ARGS, class DATA>
+       class BaseDelegate<R(ARGS...), DATA> {
+       public:
+               using Cb = Callback<R(ARGS...)>;
+               using StubA = typename Cb::StubA;
+
+       public:
+               constexpr BaseDelegate() noexcept;
+               constexpr BaseDelegate(nullptr_t) noexcept;
+
+               template <class FUNC_SIG>
+               BaseDelegate(const BaseDelegate2<FUNC_SIG, DATA> &d) noexcept;
+               template <class FUNC_SIG>
+               BaseDelegate(BaseDelegate2<FUNC_SIG, DATA> &&d) noexcept;
+
+               R operator()(ARGS ...args) const;
+
+               void reset() noexcept;
+
+               const DATA &getData() const noexcept;
+               StubA getStubA() const noexcept;
+               operator bool() const noexcept;
+
+       protected:
+               BaseDelegate(const DATA &data, StubA stubA) noexcept;
+
+       private:
+               DATA m_data;
+               StubA m_stubA;
+       };
+}
+
+#include "BaseDelegate.hpp"
+
+#endif // __UCL_UTIL_DELEGATION_BASE_DELEGATE_H__
diff --git a/ucl/inc/ucl/util/delegation/BaseDelegate.hpp b/ucl/inc/ucl/util/delegation/BaseDelegate.hpp
new file mode 100644 (file)
index 0000000..46cef7f
--- /dev/null
@@ -0,0 +1,74 @@
+namespace ucl {
+
+       template <class R, class ...ARGS, class DATA>
+       constexpr BaseDelegate<R(ARGS...), DATA>::BaseDelegate() noexcept :
+               m_data(nullptr),
+               m_stubA(nullptr)
+       {
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       constexpr BaseDelegate<R(ARGS...), DATA>::
+                       BaseDelegate(nullptr_t) noexcept :
+               BaseDelegate()
+       {
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       inline BaseDelegate<R(ARGS...), DATA>::
+                       BaseDelegate(const DATA &data, StubA stubA) noexcept :
+               m_data(data),
+               m_stubA(stubA)
+       {
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       template <class FUNC_SIG>
+       inline BaseDelegate<R(ARGS...), DATA>::
+                       BaseDelegate(const BaseDelegate2<FUNC_SIG, DATA> &d) noexcept :
+               m_data(d.m_data),
+               m_stubA(d.m_stubA)
+       {
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       template <class FUNC_SIG>
+       inline BaseDelegate<R(ARGS...), DATA>::
+                       BaseDelegate(BaseDelegate2<FUNC_SIG, DATA> &&d) noexcept :
+               m_data(std::move(d.m_data)),
+               m_stubA(d.m_stubA)
+       {
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       inline R BaseDelegate<R(ARGS...), DATA>::operator()(ARGS ...args) const
+       {
+               return m_stubA(
+                               static_cast<void *>(m_data), std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       inline void BaseDelegate<R(ARGS...), DATA>::reset() noexcept
+       {
+               *this = {};
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       inline const DATA &BaseDelegate<R(ARGS...), DATA>::getData() const noexcept
+       {
+               return m_data;
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       inline typename BaseDelegate<R(ARGS...), DATA>::StubA
+                       BaseDelegate<R(ARGS...), DATA>::getStubA() const noexcept
+       {
+               return m_stubA;
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       inline BaseDelegate<R(ARGS...), DATA>::operator bool() const noexcept
+       {
+               return !!m_data;
+       }
+}
diff --git a/ucl/inc/ucl/util/delegation/BaseDelegate2.h b/ucl/inc/ucl/util/delegation/BaseDelegate2.h
new file mode 100644 (file)
index 0000000..ad3242e
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef __UCL_UTIL_DELEGATION_BASE_DELEGATE2_H__
+#define __UCL_UTIL_DELEGATION_BASE_DELEGATE2_H__
+
+#include "BaseDelegate.h"
+
+namespace ucl {
+
+       template <class FUNC_SIG, class DATA>
+       class BaseDelegate2;
+
+       template <class R, class ...ARGS, class DATA>
+       class BaseDelegate2<R(ARGS...), DATA> :
+                       public BaseDelegate<R(ARGS...), DATA> {
+       public:
+               using Cb = typename BaseDelegate2::Cb;
+               using StubA = typename Cb::StubA;
+               using StubB = typename Cb::StubB;
+
+       public:
+               using BaseDelegate<R(ARGS...), DATA>::BaseDelegate;
+
+               StubB getStubB() const noexcept;
+
+       protected:
+               BaseDelegate2(const DATA &data, StubA stubA, StubB stubB) noexcept;
+
+       private:
+               StubB m_stubB;
+       };
+}
+
+#include "BaseDelegate2.hpp"
+
+#endif // __UCL_UTIL_DELEGATION_BASE_DELEGATE2_H__
diff --git a/ucl/inc/ucl/util/delegation/BaseDelegate2.hpp b/ucl/inc/ucl/util/delegation/BaseDelegate2.hpp
new file mode 100644 (file)
index 0000000..28446de
--- /dev/null
@@ -0,0 +1,17 @@
+namespace ucl {
+
+       template <class R, class ...ARGS, class DATA>
+       inline BaseDelegate2<R(ARGS...), DATA>::
+                       BaseDelegate2(const DATA &data, StubA stubA, StubB stubB) noexcept :
+               BaseDelegate<R(ARGS...), DATA>(data, stubA),
+               m_stubB(stubB)
+       {
+       }
+
+       template <class R, class ...ARGS, class DATA>
+       inline typename BaseDelegate2<R(ARGS...), DATA>::StubB
+                       BaseDelegate2<R(ARGS...), DATA>::getStubB() const noexcept
+       {
+               return m_stubB;
+       }
+}
diff --git a/ucl/inc/ucl/util/delegation/Callback.h b/ucl/inc/ucl/util/delegation/Callback.h
new file mode 100644 (file)
index 0000000..6b282d4
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef __UCL_UTIL_DELEGATION_CALLBACK_H__
+#define __UCL_UTIL_DELEGATION_CALLBACK_H__
+
+#include "ucl/util/types/baseTypes.h"
+
+namespace ucl {
+
+       template <class FUNC_SIG>
+       class Callback;
+
+       template <class R, class ...ARGS>
+       class Callback<R(ARGS...)> {
+       public:
+               using StubA = R(*)(void *, ARGS...);
+               using StubB = R(*)(ARGS..., void *);
+
+       public:
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+               static R stubA(void *data, ARGS ...args);
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+               static R stubB(ARGS ...args, void *data);
+
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+               static R stubA(void *data, ARGS ...args);
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+               static R stubB(ARGS ...args, void *data);
+
+               template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
+               static R stubA2A(void *data, ARGS ...args);
+               template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
+               static R stubB2A(ARGS ...args, void *data);
+
+               template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
+               static R stubA2B(void *data, ARGS ...args);
+               template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
+               static R stubB2B(ARGS ...args, void *data);
+
+               template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
+               static R stubA2A(void *data, ARGS ...args);
+               template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
+               static R stubB2A(ARGS ...args, void *data);
+
+               template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
+               static R stubA2B(void *data, ARGS ...args);
+               template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
+               static R stubB2B(ARGS ...args, void *data);
+
+               template <R(*FUNC)(ARGS...)>
+               static R stubA2V(void *data, ARGS ...args);
+               template <R(*FUNC)(ARGS...)>
+               static R stubB2V(ARGS ...args, void *data);
+       };
+}
+
+#include "Callback.hpp"
+
+#endif // __UCL_UTIL_DELEGATION_CALLBACK_H__
diff --git a/ucl/inc/ucl/util/delegation/Callback.hpp b/ucl/inc/ucl/util/delegation/Callback.hpp
new file mode 100644 (file)
index 0000000..622729f
--- /dev/null
@@ -0,0 +1,104 @@
+namespace ucl {
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+       inline R Callback<R(ARGS...)>::stubA(void *data, ARGS ...args)
+       {
+               return (static_cast<CLASS *>(data)->*METHOD)(
+                               std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+       inline R Callback<R(ARGS...)>::stubB(ARGS ...args, void *data)
+       {
+               return (static_cast<CLASS *>(data)->*METHOD)(
+                               std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+       inline R Callback<R(ARGS...)>::stubA(void *data, ARGS ...args)
+       {
+               return (static_cast<const CLASS *>(data)->*METHOD)(
+                               std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+       inline R Callback<R(ARGS...)>::stubB(ARGS ...args, void *data)
+       {
+               return (static_cast<const CLASS *>(data)->*METHOD)(
+                               std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
+       inline R Callback<R(ARGS...)>::stubA2A(void *data, ARGS ...args)
+       {
+               return FUNC(*static_cast<CLASS *>(data), std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
+       inline R Callback<R(ARGS...)>::stubB2A(ARGS ...args, void *data)
+       {
+               return FUNC(*static_cast<CLASS *>(data), std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
+       inline R Callback<R(ARGS...)>::stubA2B(void *data, ARGS ...args)
+       {
+               return FUNC(std::forward<ARGS>(args)..., *static_cast<CLASS *>(data));
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
+       inline R Callback<R(ARGS...)>::stubB2B(ARGS ...args, void *data)
+       {
+               return FUNC(std::forward<ARGS>(args)..., *static_cast<CLASS *>(data));
+       }
+
+       template <class R, class ...ARGS>
+       template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
+       inline R Callback<R(ARGS...)>::stubA2A(void *data, ARGS ...args)
+       {
+               return FUNC(static_cast<HANDLE>(data), std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS>
+       template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
+       inline R Callback<R(ARGS...)>::stubB2A(ARGS ...args, void *data)
+       {
+               return FUNC(static_cast<HANDLE>(data), std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS>
+       template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
+       inline R Callback<R(ARGS...)>::stubA2B(void *data, ARGS ...args)
+       {
+               return FUNC(std::forward<ARGS>(args)..., static_cast<HANDLE>(data));
+       }
+
+       template <class R, class ...ARGS>
+       template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
+       inline R Callback<R(ARGS...)>::stubB2B(ARGS ...args, void *data)
+       {
+               return FUNC(std::forward<ARGS>(args)..., static_cast<HANDLE>(data));
+       }
+
+       template <class R, class ...ARGS>
+       template <R(*FUNC)(ARGS...)>
+       inline R Callback<R(ARGS...)>::stubA2V(void *data, ARGS ...args)
+       {
+               return FUNC(std::forward<ARGS>(args)...);
+       }
+
+       template <class R, class ...ARGS>
+       template <R(*FUNC)(ARGS...)>
+       inline R Callback<R(ARGS...)>::stubB2V(ARGS ...args, void *data)
+       {
+               return FUNC(std::forward<ARGS>(args)...);
+       }
+}
diff --git a/ucl/inc/ucl/util/delegation/Delegate.h b/ucl/inc/ucl/util/delegation/Delegate.h
new file mode 100644 (file)
index 0000000..214482c
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef __UCL_UTIL_DELEGATION_DELEGATE_H__
+#define __UCL_UTIL_DELEGATION_DELEGATE_H__
+
+#include "BaseDelegate.h"
+
+namespace ucl {
+
+       template <class FUNC_SIG>
+       class Delegate;
+
+       template <class R, class ...ARGS>
+       class Delegate<R(ARGS...)> : public BaseDelegate<R(ARGS...), void *> {
+       public:
+               using BaseDelegate<R(ARGS...), void *>::BaseDelegate;
+
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+               static Delegate make(CLASS *data) noexcept;
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+               static Delegate make(const CLASS *data) noexcept;
+
+               template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
+               static Delegate make(CLASS &data) noexcept;
+               template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
+               static Delegate make(CLASS &data) noexcept;
+
+               template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
+               static Delegate make(HANDLE data) noexcept;
+               template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
+               static Delegate make(HANDLE data) noexcept;
+
+               template <R(*FUNC)(ARGS...)>
+               static Delegate make() noexcept;
+       };
+}
+
+#include "Delegate.hpp"
+
+#endif // __UCL_UTIL_DELEGATION_DELEGATE_H__
diff --git a/ucl/inc/ucl/util/delegation/Delegate.hpp b/ucl/inc/ucl/util/delegation/Delegate.hpp
new file mode 100644 (file)
index 0000000..adb595b
--- /dev/null
@@ -0,0 +1,64 @@
+namespace ucl {
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+       inline Delegate<R(ARGS...)>
+                       Delegate<R(ARGS...)>::make(CLASS *const data) noexcept
+       {
+               return {static_cast<void *>(data),
+                               Delegate::Cb::template stubA<CLASS, METHOD>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+       inline Delegate<R(ARGS...)>
+                       Delegate<R(ARGS...)>::make(const CLASS *const data) noexcept
+       {
+               return {static_cast<void *>(const_cast<CLASS *>(data)),
+                               Delegate::Cb::template stubA<CLASS, METHOD>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
+       inline Delegate<R(ARGS...)>
+                       Delegate<R(ARGS...)>::make(CLASS &data) noexcept
+       {
+               return {const_cast<void *>(static_cast<const void *>(&data)),
+                               Delegate::Cb::template stubA2A<CLASS, FUNC>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
+       inline Delegate<R(ARGS...)>
+                       Delegate<R(ARGS...)>::make(CLASS &data) noexcept
+       {
+               return {const_cast<void *>(static_cast<const void *>(&data)),
+                               Delegate::Cb::template stubA2B<CLASS, FUNC>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
+       inline Delegate<R(ARGS...)>
+                       Delegate<R(ARGS...)>::make(const HANDLE data) noexcept
+       {
+               return {const_cast<void *>(static_cast<const void *>(data)),
+                               Delegate::Cb::template stubA2A<HANDLE, FUNC>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
+       inline Delegate<R(ARGS...)>
+                       Delegate<R(ARGS...)>::make(const HANDLE data) noexcept
+       {
+               return {const_cast<void *>(static_cast<const void *>(data)),
+                               Delegate::Cb::template stubA2B<HANDLE, FUNC>};
+       }
+
+       template <class R, class ...ARGS>
+       template <R(*FUNC)(ARGS...)>
+       inline Delegate<R(ARGS...)>
+                       Delegate<R(ARGS...)>::make() noexcept
+       {
+               return {nullptr, Delegate::Cb::template stubA2V<FUNC>};
+       }
+}
diff --git a/ucl/inc/ucl/util/delegation/Delegate2.h b/ucl/inc/ucl/util/delegation/Delegate2.h
new file mode 100644 (file)
index 0000000..b780af7
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef __UCL_UTIL_DELEGATION_DELEGATE2_H__
+#define __UCL_UTIL_DELEGATION_DELEGATE2_H__
+
+#include "BaseDelegate2.h"
+
+namespace ucl {
+
+       template <class FUNC_SIG>
+       class Delegate2;
+
+       template <class R, class ...ARGS>
+       class Delegate2<R(ARGS...)> : public BaseDelegate2<R(ARGS...), void *> {
+       public:
+               using BaseDelegate2<R(ARGS...), void *>::BaseDelegate2;
+
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+               static Delegate2 make(CLASS *data) noexcept;
+               template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+               static Delegate2 make(const CLASS *data) noexcept;
+
+               template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
+               static Delegate2 make(CLASS &data) noexcept;
+               template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
+               static Delegate2 make(CLASS &data) noexcept;
+
+               template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
+               static Delegate2 make(HANDLE data) noexcept;
+               template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
+               static Delegate2 make(HANDLE data) noexcept;
+
+               template <R(*FUNC)(ARGS...)>
+               static Delegate2 make() noexcept;
+       };
+}
+
+#include "Delegate2.hpp"
+
+#endif // __UCL_UTIL_DELEGATION_DELEGATE2_H__
diff --git a/ucl/inc/ucl/util/delegation/Delegate2.hpp b/ucl/inc/ucl/util/delegation/Delegate2.hpp
new file mode 100644 (file)
index 0000000..88246a3
--- /dev/null
@@ -0,0 +1,72 @@
+namespace ucl {
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...)>
+       inline Delegate2<R(ARGS...)>
+                       Delegate2<R(ARGS...)>::make(CLASS *const data) noexcept
+       {
+               return {static_cast<void *>(data),
+                               Delegate2::Cb::template stubA<CLASS, METHOD>,
+                               Delegate2::Cb::template stubB<CLASS, METHOD>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(CLASS::*METHOD)(ARGS...) const>
+       inline Delegate2<R(ARGS...)>
+                       Delegate2<R(ARGS...)>::make(const CLASS *const data) noexcept
+       {
+               return {static_cast<void *>(const_cast<CLASS *>(data)),
+                               Delegate2::Cb::template stubA<CLASS, METHOD>,
+                               Delegate2::Cb::template stubB<CLASS, METHOD>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(*FUNC)(CLASS &, ARGS...)>
+       inline Delegate2<R(ARGS...)>
+                       Delegate2<R(ARGS...)>::make(CLASS &data) noexcept
+       {
+               return {const_cast<void *>(static_cast<const void *>(&data)),
+                               Delegate2::Cb::template stubA2A<CLASS, FUNC>,
+                               Delegate2::Cb::template stubB2A<CLASS, FUNC>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class CLASS, R(*FUNC)(ARGS..., CLASS &)>
+       inline Delegate2<R(ARGS...)>
+                       Delegate2<R(ARGS...)>::make(CLASS &data) noexcept
+       {
+               return {const_cast<void *>(static_cast<const void *>(&data)),
+                               Delegate2::Cb::template stubA2B<CLASS, FUNC>,
+                               Delegate2::Cb::template stubB2B<CLASS, FUNC>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class HANDLE, R(*FUNC)(HANDLE, ARGS...)>
+       inline Delegate2<R(ARGS...)>
+                       Delegate2<R(ARGS...)>::make(const HANDLE data) noexcept
+       {
+               return {const_cast<void *>(static_cast<const void *>(data)),
+                               Delegate2::Cb::template stubA2A<HANDLE, FUNC>,
+                               Delegate2::Cb::template stubB2A<HANDLE, FUNC>};
+       }
+
+       template <class R, class ...ARGS>
+       template <class HANDLE, R(*FUNC)(ARGS..., HANDLE)>
+       inline Delegate2<R(ARGS...)>
+                       Delegate2<R(ARGS...)>::make(const HANDLE data) noexcept
+       {
+               return {const_cast<void *>(static_cast<const void *>(data)),
+                               Delegate2::Cb::template stubA2B<HANDLE, FUNC>,
+                               Delegate2::Cb::template stubB2B<HANDLE, FUNC>};
+       }
+
+       template <class R, class ...ARGS>
+       template <R(*FUNC)(ARGS...)>
+       inline Delegate2<R(ARGS...)>
+                       Delegate2<R(ARGS...)>::make() noexcept
+       {
+               return {nullptr,
+                               Delegate2::Cb::template stubA2V<FUNC>,
+                               Delegate2::Cb::template stubB2V<FUNC>};
+       }
+}
diff --git a/ucl/inc/ucl/util/delegation/helpers.h b/ucl/inc/ucl/util/delegation/helpers.h
new file mode 100644 (file)
index 0000000..fdcc566
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef __UCL_UTIL_DELEGATION_HELPERS_H__
+#define __UCL_UTIL_DELEGATION_HELPERS_H__
+
+namespace ucl {
+
+       // Automatic function signature detection for a specific type //
+
+       template <template <typename ...> class T, class TAG, class FUNC>
+       struct AutoFuncSig;
+
+       template <template <typename ...> class T,
+                        class R, class CLASS, class ...ARGS>
+       struct AutoFuncSig<T, void *, R(CLASS::*)(ARGS...)> {
+               using Data = CLASS;
+               using Type = T<R(ARGS...)>;
+       };
+
+       template <template <typename ...> class T,
+                       class CLASS, class R, class ...ARGS>
+       struct AutoFuncSig<T, void *, R(CLASS::*)(ARGS...) const> {
+               using Data = CLASS;
+               using Type = T<R(ARGS...)>;
+       };
+
+       template <template <typename ...> class T,
+                       class CLASS, class R, class ...ARGS>
+       struct AutoFuncSig<T, void *, R(*)(CLASS &, ARGS...)> {
+               using Data = CLASS;
+               using Type = T<R(ARGS...)>;
+       };
+
+       template <template <typename ...> class T,
+                       class HANDLE, class R, class ...ARGS>
+       struct AutoFuncSig<T, void *, R(*)(HANDLE, ARGS...)> {
+               using Data = HANDLE;
+               using Type = T<R(ARGS...)>;
+       };
+
+       template <template <typename ...> class T,
+                       class R, class ...ARGS>
+       struct AutoFuncSig<T, void, R(*)(ARGS...)> {
+               using Type = T<R(ARGS...)>;
+       };
+
+       // Relation operators //
+
+       template <class R, class ...ARGS, class DATA1, class DATA2>
+       inline bool operator==(const BaseDelegate<R(ARGS...), DATA1> &lhs,
+                       const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
+       {
+               return ((lhs.getStubA() == rhs.getStubA()) && (static_cast<void *>(
+                               lhs.getData()) == static_cast<void *>(rhs.getData())));
+       }
+
+       template <class R, class ...ARGS, class DATA1, class DATA2>
+       inline bool operator!=(const BaseDelegate<R(ARGS...), DATA1> &lhs,
+                       const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
+       {
+               return ((lhs.getStubA() != rhs.getStubA()) || (static_cast<void *>(
+                               lhs.getData()) != static_cast<void *>(rhs.getData())));
+       }
+
+       template <class R, class ...ARGS, class DATA1, class DATA2>
+       inline bool operator<(const BaseDelegate<R(ARGS...), DATA1> &lhs,
+                       const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
+       {
+               return ((lhs.getStubA() < rhs.getStubA()) ||
+                               ((lhs.getStubA() == rhs.getStubA()) && (static_cast<void *>(
+                                       lhs.getData()) < static_cast<void *>(rhs.getData()))));
+       }
+
+       template <class R, class ...ARGS, class DATA1, class DATA2>
+       inline bool operator<=(const BaseDelegate<R(ARGS...), DATA1> &lhs,
+                       const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
+       {
+               return ((lhs.getStubA() < rhs.getStubA()) ||
+                               ((lhs.getStubA() == rhs.getStubA()) && (static_cast<void *>(
+                                       lhs.getData()) <= static_cast<void *>(rhs.getData()))));
+       }
+
+       template <class R, class ...ARGS, class DATA1, class DATA2>
+       inline bool operator>(const BaseDelegate<R(ARGS...), DATA1> &lhs,
+                       const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
+       {
+               return ((lhs.getStubA() > rhs.getStubA()) ||
+                               ((lhs.getStubA() == rhs.getStubA()) && (static_cast<void *>(
+                                       lhs.getData()) > static_cast<void *>(rhs.getData()))));
+       }
+
+       template <class R, class ...ARGS, class DATA1, class DATA2>
+       inline bool operator>=(const BaseDelegate<R(ARGS...), DATA1> &lhs,
+                       const BaseDelegate<R(ARGS...), DATA2> &rhs) noexcept
+       {
+               return ((lhs.getStubA() > rhs.getStubA()) ||
+                               ((lhs.getStubA() == rhs.getStubA()) && (static_cast<void *>(
+                                       lhs.getData()) >= static_cast<void *>(rhs.getData()))));
+       }
+}
+
+#endif // __UCL_UTIL_DELEGATION_HELPERS_H__
diff --git a/ucl/inc/ucl/util/delegation/macro.h b/ucl/inc/ucl/util/delegation/macro.h
new file mode 100644 (file)
index 0000000..d58bd57
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef __UCL_UTIL_DELEGATION_MACRO_H__
+#define __UCL_UTIL_DELEGATION_MACRO_H__
+
+// Helper macro to simplify use of AutoFuncSig template
+
+#define _UCL_AFS(DELEGATE, FUNC) \
+               ::ucl::AutoFuncSig<DELEGATE, void *, decltype(&FUNC)>
+
+// Helper macro to automatically generate different delegate objects //
+
+#define _UCL_DELEGATE(DELEGATE, FUNC, DATA) (_UCL_AFS(DELEGATE, FUNC):: \
+               Type::make<_UCL_AFS(DELEGATE, FUNC)::Data, &FUNC>(DATA))
+
+#define _UCL_DELEGATE_V(DELEGATE, FUNC) \
+               (::ucl::AutoFuncSig<DELEGATE, void, decltype(&FUNC)>::\
+                       Type::make<&FUNC>())
+
+// Helper macro to automatically generate Delegate objects //
+
+#define UCL_DELEGATE(FUNC, DATA) _UCL_DELEGATE(::ucl::Delegate, FUNC, DATA)
+#define UCL_DELEGATE_V(FUNC) _UCL_DELEGATE_V(::ucl::Delegate, FUNC)
+
+// Helper macro to automatically generate Delegate2 objects //
+
+#define UCL_DELEGATE2(FUNC, DATA) _UCL_DELEGATE(::ucl::Delegate2, FUNC, DATA)
+#define UCL_DELEGATE2_V(FUNC) _UCL_DELEGATE_V(::ucl::Delegate2, FUNC)
+
+// Helper macro to automatically generate Callback stubs //
+
+#define UCL_CALLBACK_A(FUNC) (&_UCL_AFS(::ucl::Callback, FUNC):: \
+               Type::stubA<_UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>)
+#define UCL_CALLBACK_B(FUNC) (&_UCL_AFS(::ucl::Callback, FUNC):: \
+               Type::stubB<_UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>)
+
+#define UCL_CALLBACK_A2A(FUNC) (&_UCL_AFS(::ucl::Callback, FUNC)::Type:: \
+               stubA2A<_UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>)
+#define UCL_CALLBACK_B2A(FUNC) (&_UCL_AFS(::ucl::Callback, FUNC)::Type:: \
+               stubB2A<_UCL_AFS(::ucl::Callback, FUNC)::Data, &FUNC>)
+
+#define UCL_CALLBACK_A2V(FUNC) (&::ucl::AutoFuncSig<::ucl::Callback, void, \
+               decltype(&FUNC)>::Type::stubA2V<&FUNC>)
+#define UCL_CALLBACK_B2V(FUNC) (&::ucl::AutoFuncSig<::ucl::Callback, void, \
+               decltype(&FUNC)>::Type::stubB2V<&FUNC>)
+
+#endif // __UCL_UTIL_DELEGATION_MACRO_H__
diff --git a/ucl/inc/ucl/util/delegation/shortMacro.h b/ucl/inc/ucl/util/delegation/shortMacro.h
new file mode 100644 (file)
index 0000000..ed0c806
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __UCL_UTIL_DELEGATION_SHORT_MACRO_H__
+#define __UCL_UTIL_DELEGATION_SHORT_MACRO_H__
+
+// Helper macro to automatically generate Delegate objects //
+
+#define DELEGATE(FUNC, DATA)  UCL_DELEGATE(FUNC, DATA)
+#define DELEGATE_V(FUNC)      UCL_DELEGATE_V(FUNC)
+
+// Helper macro to automatically generate Delegate2 objects //
+
+#define DELEGATE2(FUNC, DATA)  UCL_DELEGATE2(FUNC, DATA)
+#define DELEGATE2_V(FUNC)      UCL_DELEGATE2_V(FUNC)
+
+// Helper macro to automatically generate Callback stubs //
+
+#define CALLBACK_A(FUNC)  UCL_CALLBACK_A(FUNC)
+#define CALLBACK_B(FUNC)  UCL_CALLBACK_B(FUNC)
+
+#define CALLBACK_A2A(FUNC)  UCL_CALLBACK_A2A(FUNC)
+#define CALLBACK_B2A(FUNC)  UCL_CALLBACK_B2A(FUNC)
+
+#define CALLBACK_A2V(FUNC)  UCL_CALLBACK_A2V(FUNC)
+#define CALLBACK_B2V(FUNC)  UCL_CALLBACK_B2V(FUNC)
+
+#endif // __UCL_UTIL_DELEGATION_SHORT_MACRO_H__
diff --git a/ucl/inc/ucl/util/helpers.h b/ucl/inc/ucl/util/helpers.h
new file mode 100644 (file)
index 0000000..c0ddccb
--- /dev/null
@@ -0,0 +1,90 @@
+#ifndef __UCL_UTIL_HELPERS_H__
+#define __UCL_UTIL_HELPERS_H__
+
+#include "types/baseTypes.h"
+
+namespace ucl {
+
+       constexpr Eina_Bool toEina(bool value);
+
+       // "nz()" - "Not Zero" functions
+       // return "zValue" if "!value" is true
+       constexpr const char *nz(const char *value, const char *zValue = "");
+
+       // "ne()" - "Not Empty" functions
+       // return "eValue" if "isEmpty(value)" is true
+       constexpr const char *ne(const char *value, const char *eValue = nullptr);
+
+       constexpr bool isEmpty(const char *value);
+
+       template <class T>
+       constexpr auto isEmpty(const T &value) -> decltype(value.empty())
+       {
+               return value.empty();
+       }
+
+       template <class T>
+       constexpr auto isEmpty(const T &value) -> decltype(value.isEmpty())
+       {
+               return value.isEmpty();
+       }
+
+       template <class T>
+       constexpr bool isNotEmpty(T &&value);
+
+       template <class T>
+       constexpr bool isNotValid(T &&value);
+
+       char *strDupSafe(const char *value);
+       int strCmpSafe(const char *lhs, const char *rhs);
+
+       template <class T1, class T2>
+       inline auto dynamicCast(T2 &&src) -> decltype(
+                       dynamic_cast<T1>(std::forward<T2>(src)))
+       {
+               return dynamic_cast<T1>(std::forward<T2>(src));
+       }
+
+       template <class T1, class T2>
+       inline auto constCast(T2 &&src) -> decltype(
+                       const_cast<T1>(std::forward<T2>(src)))
+       {
+               return const_cast<T1>(std::forward<T2>(src));
+       }
+
+       template <class T>
+       constexpr const T &min(const T &a, const T &b);
+
+       template <class T>
+       constexpr const T &max(const T &a, const T &b);
+
+       template <class T>
+       constexpr bool isPot(T value);
+
+       template <uint MULTIPLE, class T>
+       constexpr T ceilDiv(T value);
+
+       template <uint MULTIPLE, class T>
+       constexpr typename std::enable_if<isPot(MULTIPLE), T>::type
+                       roundUp(T value)
+       {
+               return ((value + (MULTIPLE - 1)) & ~static_cast<T>(MULTIPLE - 1));
+       }
+
+       template <uint MULTIPLE, class T>
+       constexpr typename std::enable_if<!isPot(MULTIPLE), T>::type
+                       roundUp(T value)
+       {
+               return (ceilDiv<MULTIPLE>(value) * MULTIPLE);
+       }
+}
+
+namespace ucl { namespace util {
+
+       template <class T>
+       std::unique_ptr<T> makeUnique(T *p);
+}}
+
+#include "helpers.hpp"
+
+#endif // __UCL_UTIL_HELPERS_H__
diff --git a/ucl/inc/ucl/util/helpers.hpp b/ucl/inc/ucl/util/helpers.hpp
new file mode 100644 (file)
index 0000000..bafaff2
--- /dev/null
@@ -0,0 +1,77 @@
+namespace ucl {
+
+       constexpr Eina_Bool toEina(const bool value)
+       {
+               return (value ? EINA_TRUE : EINA_FALSE);
+       }
+
+       constexpr const char *nz(const char *const value, const char *const zValue)
+       {
+               return (value ? value : zValue);
+       }
+
+       constexpr const char *ne(const char *const value, const char *const eValue)
+       {
+               return (isNotEmpty(value) ? value : eValue);
+       }
+
+       constexpr bool isEmpty(const char *const value)
+       {
+               return (!value || (value[0] == '\0'));
+       }
+
+       template <class T>
+       constexpr bool isNotEmpty(T &&value)
+       {
+               return !isEmpty(std::forward<T>(value));
+       }
+
+       template <class T>
+       constexpr bool isNotValid(T &&value)
+       {
+               return !isValid(std::forward<T>(value));
+       }
+
+       inline char *strDupSafe(const char *const value)
+       {
+               return (value ? strdup(value) : nullptr);
+       }
+
+       inline int strCmpSafe(const char *lhs, const char *rhs)
+       {
+               return strcmp(nz(lhs), nz(rhs));
+       }
+
+       template <class T>
+       constexpr const T &min(const T &a, const T &b)
+       {
+               return ((a < b) ? a : b);
+       }
+
+       template <class T>
+       constexpr const T &max(const T &a, const T &b)
+       {
+               return ((a > b) ? a : b);
+       }
+
+       template <class T>
+       constexpr bool isPot(const T value)
+       {
+               return (((value - 1) & value) == 0);
+       }
+
+       template <uint MULTIPLE, class T>
+       constexpr T ceilDiv(T value)
+       {
+               return ((value + (MULTIPLE - 1)) / MULTIPLE);
+       }
+}
+
+namespace ucl { namespace util {
+
+       template <class T>
+       inline std::unique_ptr<T> makeUnique(T *const p)
+       {
+               return std::unique_ptr<T>(p);
+       }
+}}
diff --git a/ucl/inc/ucl/util/logging.h b/ucl/inc/ucl/util/logging.h
new file mode 100644 (file)
index 0000000..6fb60f5
--- /dev/null
@@ -0,0 +1,189 @@
+#ifndef __UCL_UTIL_LOGGING_H__
+#define __UCL_UTIL_LOGGING_H__
+
+#include <assert.h>
+
+#include <dlog.h>
+
+#include "types/Result.h"
+
+::ucl::ResultData getUCLResultData(::ucl::Result result);
+
+#ifndef UCL_LOG_LEVEL
+#define UCL_LOG_LEVEL UCL_MAX_LOG_LEVEL
+#elif UCL_LOG_LEVEL > UCL_MAX_LOG_LEVEL
+#undef UCL_LOG_LEVEL
+#define UCL_LOG_LEVEL UCL_MAX_LOG_LEVEL
+#endif
+
+#ifndef UCL_LOG_TAG
+#define UCL_LOG_TAG UCL_DEFAULT_LOG_TAG
+#endif
+
+#ifndef __MODULE__
+#define __MODULE__ (strrchr(__FILE__, '/') ? \
+               strrchr(__FILE__, '/') + 1 : __FILE__)
+#endif
+
+// Base macros for writing logs without result code
+#define UCL_ULOG(prio, fmt, ...) dlog_print( \
+       (log_priority)prio, UCL_LOG_TAG, "%s: %s(%d) > " fmt, \
+       __MODULE__, __func__, __LINE__, ##__VA_ARGS__)
+
+// Base macros for writing logs WITH result code
+#define UCL_URESDATALOG(prio, resdata, fmt, ...) dlog_print( \
+       (log_priority)prio, UCL_LOG_TAG, "%s: %s(%d) > " fmt " {%s}", \
+       __MODULE__, __func__, __LINE__, ##__VA_ARGS__, resdata.name)
+
+#define UCL_URESLOG(prio, result, fmt, ...) do { \
+       const ::ucl::ResultData &resdata = ::getUCLResultData(result); \
+       UCL_URESDATALOG(prio, resdata, fmt, ##__VA_ARGS__);} while (false)
+
+#if UCL_LOG_LEVEL >= UCL_LOG_LEVEL_VERBOSE
+#define UCL_VLOG(msg, ...) UCL_ULOG(DLOG_VERBOSE, msg, ##__VA_ARGS__)
+#define UCL_VRESLOG(result, msg, ...) \
+               UCL_URESLOG(DLOG_VERBOSE, result, msg, ##__VA_ARGS__)
+#else
+#define UCL_VLOG(msg, ...) do {} while (false)
+#define UCL_VRESLOG(result, msg, ...) do {} while (false)
+#endif
+
+#if UCL_LOG_LEVEL >= UCL_LOG_LEVEL_DEBUG
+#define UCL_DLOG(msg, ...) UCL_ULOG(DLOG_DEBUG, msg, ##__VA_ARGS__)
+#define UCL_DRESLOG(result, msg, ...) \
+               UCL_URESLOG(DLOG_DEBUG, result, msg, ##__VA_ARGS__)
+#else
+#define UCL_DLOG(msg, ...) do {} while (false)
+#define UCL_DRESLOG(result, msg, ...) do {} while (false)
+#endif
+
+#if UCL_LOG_LEVEL >= UCL_LOG_LEVEL_INFO
+#define UCL_ILOG(msg, ...) UCL_ULOG(DLOG_INFO, msg, ##__VA_ARGS__)
+#define UCL_IRESLOG(result, msg, ...) \
+               UCL_URESLOG(DLOG_INFO, result, msg, ##__VA_ARGS__)
+#else
+#define UCL_ILOG(msg, ...) do {} while (false)
+#define UCL_IRESLOG(result, msg, ...) do {} while (false)
+#endif
+
+#if UCL_LOG_LEVEL >= UCL_LOG_LEVEL_WARNING
+#define UCL_WLOG(msg, ...) UCL_ULOG(DLOG_WARN, msg, ##__VA_ARGS__)
+#define UCL_WRESLOG(result, msg, ...) \
+               UCL_URESLOG(DLOG_WARN, result, msg, ##__VA_ARGS__)
+#else
+#define UCL_WLOG(msg, ...) do {} while (false)
+#define UCL_WRESLOG(result, msg, ...) do {} while (false)
+#endif
+
+#if UCL_LOG_LEVEL >= UCL_LOG_LEVEL_ERROR
+#define UCL_ELOG(msg, ...) UCL_ULOG(DLOG_ERROR, msg, ##__VA_ARGS__)
+#define UCL_ERESLOG(result, msg, ...) \
+               UCL_URESLOG(DLOG_ERROR, result, msg, ##__VA_ARGS__)
+#else
+#define UCL_ELOG(msg, ...) do {} while (false)
+#define UCL_ERESLOG(result, msg, ...) do {} while (false)
+#endif
+
+#if UCL_LOG_LEVEL >= UCL_LOG_LEVEL_FATAL
+#define UCL_FLOG(msg, ...) UCL_ULOG(DLOG_FATAL, msg, ##__VA_ARGS__)
+#define UCL_FRESLOG(result, msg, ...) UCL_URESLOG( \
+       DLOG_FATAL, result, msg, ##__VA_ARGS__)
+#else
+#define UCL_FLOG(msg, ...) do {} while (false)
+#define UCL_FRESLOG(result, msg, ...) do {} while (false)
+#endif
+
+#if UCL_LOG_LEVEL >= UCL_LOG_LEVEL_ERROR
+
+// Simple macros for writing logs WITH result
+// code and automatic log priority determination
+#define UCL_RESLOG(result, msg, ...) { \
+       const ::ucl::ResultData &resdata = ::getUCLResultData(result); \
+       UCL_URESDATALOG(resdata.logPrio, \
+                       resdata, msg, ##__VA_ARGS__);} while (false)
+
+#else
+#define UCL_RESLOG(result, msg, ...) do {} while (false)
+#endif
+
+#define UCL_ASSERT(expr, msg, ...) \
+       do { \
+               if (!(expr)) { \
+                       UCL_FLOG(msg, ##__VA_ARGS__); \
+                       assert(false); \
+               } \
+       } while (false)
+
+#define UCL_FAIL_RETURN(result, msg, ...) \
+       do { \
+               const ::ucl::Result __RESULT__ = (result); \
+               if (isBad(__RESULT__)) { \
+                       UCL_RESLOG(__RESULT__, msg, ##__VA_ARGS__); \
+                       return __RESULT__; \
+               } \
+       } while (false)
+
+#define UCL_FAIL_RETURN_VALUE(result, value, msg, ...) \
+       do { \
+               const ::ucl::Result __RESULT__ = (result); \
+               if (isBad(__RESULT__)) { \
+                       UCL_RESLOG(__RESULT__, msg, ##__VA_ARGS__); \
+                       return (value); \
+               } \
+       } while (false)
+
+#define UCL_FAIL_RETURN_VOID(result, msg, ...) \
+       do { \
+               const ::ucl::Result __RESULT__ = (result); \
+               if (isBad(__RESULT__)) { \
+                       UCL_RESLOG(__RESULT__, msg, ##__VA_ARGS__); \
+                       return; \
+               } \
+       } while (false)
+
+#define UCL_LOG_RETURN(result, msg, ...) \
+       do { \
+               const ::ucl::Result __RESULT__ = (result); \
+               UCL_RESLOG(__RESULT__, msg, ##__VA_ARGS__); \
+               return __RESULT__; \
+       } while (false)
+
+#define UCL_LOG_RETURN_VALUE(result, value, msg, ...) \
+       do { \
+               const ::ucl::Result __RESULT__ = (result); \
+               UCL_RESLOG(__RESULT__, msg, ##__VA_ARGS__); \
+               return (value); \
+       } while (false)
+
+#define UCL_LOG_RETURN_VOID(result, msg, ...) \
+       do { \
+               const ::ucl::Result __RESULT__ = (result); \
+               UCL_RESLOG(__RESULT__, msg, ##__VA_ARGS__); \
+               return; \
+       } while (false)
+
+#define UCL_FAIL_BREAK(result, msg, ...) \
+       do { \
+               const ::ucl::Result __RESULT__ = (result); \
+               if (isBad(__RESULT__)) { \
+                       UCL_RESLOG(__RESULT__, msg, ##__VA_ARGS__); \
+                       break; \
+               } \
+       } while (false)
+
+#define UCL_LOG_BREAK(result, msg, ...) \
+       do { \
+               const ::ucl::Result __RESULT__ = (result); \
+               UCL_RESLOG(__RESULT__, msg, ##__VA_ARGS__); \
+               break; \
+       } while (false)
+
+#define UCL_FAIL_LOG(result, msg, ...) \
+       do { \
+               const ::ucl::Result __RESULT__ = (result); \
+               if (isBad(__RESULT__)) { \
+                       UCL_RESLOG(__RESULT__, msg, ##__VA_ARGS__); \
+               } \
+       } while (false)
+
+#endif // __UCL_UTIL_LOGGING_H__
diff --git a/ucl/inc/ucl/util/memory.h b/ucl/inc/ucl/util/memory.h
new file mode 100644 (file)
index 0000000..edc74ce
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __UCL_UTIL_MEMORY_H__
+#define __UCL_UTIL_MEMORY_H__
+
+#include "memory/RefCountObjBase.h"
+#include "memory/RefCountObj.h"
+
+#include "memory/BaseRef.h"
+#include "memory/SharedRef.h"
+#include "memory/WeakRef.h"
+
+#include "memory/helpers.h"
+#include "memory/macro.h"
+
+#endif // __UCL_UTIL_MEMORY_H__
diff --git a/ucl/inc/ucl/util/memory/BaseRef.h b/ucl/inc/ucl/util/memory/BaseRef.h
new file mode 100644 (file)
index 0000000..bfae1fb
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef __UCL_UTIL_MEMORY_BASE_REF_H__
+#define __UCL_UTIL_MEMORY_BASE_REF_H__
+
+#include "RefCountObjBase.h"
+
+namespace ucl {
+
+       template <class T>
+       class BaseRef {
+       public:
+               using Type = T;
+
+               template <class U>
+               friend class BaseRef;
+               template <class U>
+               friend class SharedRef;
+               template <class U>
+               friend class WeakRef;
+
+       public:
+               T *operator->() const noexcept;
+               typename std::add_lvalue_reference<T>::type operator*() const noexcept;
+
+               template <class U>
+               explicit operator U() const noexcept;
+
+       protected:
+               constexpr BaseRef() noexcept;
+               BaseRef(RefCountObjBase *rc, T *ptr) noexcept;
+               BaseRef(BaseRef<T> &&r) noexcept;
+               template <class U>
+               BaseRef(BaseRef<U> &&r) noexcept;
+
+       protected:
+               RefCountObjBase *m_rc;
+               T *m_ptr;
+       };
+}
+
+#include "BaseRef.hpp"
+
+#endif // __UCL_UTIL_MEMORY_BASE_REF_H__
diff --git a/ucl/inc/ucl/util/memory/BaseRef.hpp b/ucl/inc/ucl/util/memory/BaseRef.hpp
new file mode 100644 (file)
index 0000000..047cc88
--- /dev/null
@@ -0,0 +1,56 @@
+namespace ucl {
+
+       template <class T>
+       constexpr BaseRef<T>::BaseRef() noexcept :
+               m_rc(nullptr),
+               m_ptr(nullptr)
+       {
+       }
+
+       template <class T>
+       inline BaseRef<T>::BaseRef(
+                       RefCountObjBase *const rc, T *const ptr) noexcept :
+               m_rc(rc),
+               m_ptr(ptr)
+       {
+       }
+
+       template <class T>
+       inline BaseRef<T>::BaseRef(BaseRef<T> &&r) noexcept :
+               m_rc(r.m_rc),
+               m_ptr(r.m_ptr)
+       {
+               r.m_rc = nullptr;
+               r.m_ptr = nullptr;
+       }
+
+       template <class T>
+       template <class U>
+       inline BaseRef<T>::BaseRef(BaseRef<U> &&r) noexcept :
+               m_rc(r.m_rc),
+               m_ptr(r.m_ptr)
+       {
+               r.m_rc = nullptr;
+               r.m_ptr = nullptr;
+       }
+
+       template <class T>
+       inline T *BaseRef<T>::operator->() const noexcept
+       {
+               return m_ptr;
+       }
+
+       template <class T>
+       inline typename std::add_lvalue_reference<T>::type
+                       BaseRef<T>::operator*() const noexcept
+       {
+               return *m_ptr;
+       }
+
+       template <class T>
+       template <class U>
+       inline BaseRef<T>::operator U() const noexcept
+       {
+               return static_cast<U>(m_ptr);
+       }
+}
diff --git a/ucl/inc/ucl/util/memory/RefCountObj.h b/ucl/inc/ucl/util/memory/RefCountObj.h
new file mode 100644 (file)
index 0000000..f067b0a
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef __UCL_UTIL_MEMORY_REF_COUNT_OBJ_H__
+#define __UCL_UTIL_MEMORY_REF_COUNT_OBJ_H__
+
+#include "RefCountObjBase.h"
+
+namespace ucl {
+
+       template <class T>
+       class RefCountObj : public RefCountObjBase {
+       public:
+               template <class ...ARGS>
+               RefCountObj(ARGS &&...args);
+
+               T *getObj() noexcept;
+
+       protected:
+               // RefCountObjBase //
+               virtual void dispose() noexcept final override;
+               virtual void onUniqueChanged(bool isUnique) noexcept final override;
+
+       private:
+               // Consume-all SFINAE functions
+               template <class T2, class ...ARGS>
+               void createObj(const P<0> &, ARGS &&...args);
+               template <class T2>
+               void dispatchOnUniqueChanged(
+                               const P<0> &, const bool isUnique) noexcept;
+
+               // Specialized SFINAE functions
+
+               template <class T2, class ...ARGS>
+               auto createObj(const P<1> &, ARGS &&...args) -> decltype(
+                               (void)(new T2(this, std::forward<ARGS>(args)...)))
+               {
+                       new (getObj()) T(this, std::forward<ARGS>(args)...);
+               }
+
+               template <class T2, class ...ARGS>
+               auto createObj(const P<2> &, ARGS &&...args) -> decltype(
+                               (void)(new T2(*this, std::forward<ARGS>(args)...)))
+               {
+                       new (getObj()) T(*this, std::forward<ARGS>(args)...);
+               }
+
+               template <class T2,
+                               class = char(*)[T2::ENABLE_ON_UNIQUE_CHANGED_DISPATCH * 0 + 1]>
+               void dispatchOnUniqueChanged(
+                               const P<1> &, const bool isUnique) noexcept
+               {
+                       getObj()->onUniqueChanged(isUnique);
+               }
+
+       private:
+               // Proper-aligned storage for T
+               typename std::aligned_storage<sizeof(T), alignof(T)>::type m_obj;
+       };
+}
+
+#include "RefCountObj.hpp"
+
+#endif // __UCL_UTIL_MEMORY_REF_COUNT_OBJ_H__
diff --git a/ucl/inc/ucl/util/memory/RefCountObj.hpp b/ucl/inc/ucl/util/memory/RefCountObj.hpp
new file mode 100644 (file)
index 0000000..d0cfa2a
--- /dev/null
@@ -0,0 +1,44 @@
+namespace ucl {
+
+       template <class T>
+       template <class ...ARGS>
+       inline RefCountObj<T>::RefCountObj(ARGS &&...args)
+       {
+               createObj<T>(P<2>(), std::forward<ARGS>(args)...);
+       }
+
+       template <class T>
+       inline T *RefCountObj<T>::getObj() noexcept
+       {
+               return static_cast<T *>(static_cast<void *>(&m_obj));
+       }
+
+       template <class T>
+       inline void RefCountObj<T>::dispose() noexcept
+       {
+               if (!isDisposed()) {
+                       RefCountObjBase::dispose();
+                       getObj()->~T();
+               }
+       }
+
+       template <class T>
+       inline void RefCountObj<T>::onUniqueChanged(const bool isUnique) noexcept
+       {
+               dispatchOnUniqueChanged<T>(P<1>(), isUnique);
+       }
+
+       template <class T>
+       template <class T2, class ...ARGS>
+       inline void RefCountObj<T>::createObj(const P<0> &, ARGS &&...args)
+       {
+               new (getObj()) T(std::forward<ARGS>(args)...);
+       }
+
+       template <class T>
+       template <class T2>
+       inline void RefCountObj<T>::dispatchOnUniqueChanged(
+                       const P<0> &, const bool isUnique) noexcept
+       {
+       }
+}
diff --git a/ucl/inc/ucl/util/memory/RefCountObjBase.h b/ucl/inc/ucl/util/memory/RefCountObjBase.h
new file mode 100644 (file)
index 0000000..b5e4277
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef __UCL_UTIL_MEMORY_REF_COUNT_OBJ_BASE_H__
+#define __UCL_UTIL_MEMORY_REF_COUNT_OBJ_BASE_H__
+
+#include "ucl/util/types/classTypes.h"
+
+namespace ucl {
+
+       class RefCountObjBase : public Polymorphic {
+       public:
+               void ref() noexcept;
+               void unref() noexcept;
+
+               void refWeak() noexcept;
+               void unrefWeak() noexcept;
+
+               bool isDisposed() const noexcept;
+
+       protected:
+               RefCountObjBase();
+               virtual ~RefCountObjBase() = default;
+
+               virtual void dispose() noexcept;
+               virtual void onUniqueChanged(bool isUnique) noexcept = 0;
+
+       private:
+               int m_useRefs;
+               int m_weakRefs;
+               bool m_isDisposed;
+       };
+}
+
+#include "RefCountObjBase.hpp"
+
+#endif // __UCL_UTIL_MEMORY_REF_COUNT_OBJ_BASE_H__
diff --git a/ucl/inc/ucl/util/memory/RefCountObjBase.hpp b/ucl/inc/ucl/util/memory/RefCountObjBase.hpp
new file mode 100644 (file)
index 0000000..4edfa52
--- /dev/null
@@ -0,0 +1,53 @@
+namespace ucl {
+
+       inline RefCountObjBase::RefCountObjBase() :
+               m_useRefs(0),
+               m_weakRefs(1),
+               m_isDisposed(false)
+       {
+       }
+
+       inline void RefCountObjBase::ref() noexcept
+       {
+               ++m_useRefs;
+               if (m_useRefs == 2) {
+                       onUniqueChanged(false);
+               }
+       }
+
+       inline void RefCountObjBase::unref() noexcept
+       {
+               --m_useRefs;
+               if (m_useRefs <= 1) {
+                       if (m_useRefs == 1) {
+                               onUniqueChanged(true);
+                       } else {
+                               dispose();
+                               unrefWeak();
+                       }
+               }
+       }
+
+       inline void RefCountObjBase::refWeak() noexcept
+       {
+               ++m_weakRefs;
+       }
+
+       inline void RefCountObjBase::unrefWeak() noexcept
+       {
+               --m_weakRefs;
+               if (m_weakRefs == 0) {
+                       delete this;
+               }
+       }
+
+       inline bool RefCountObjBase::isDisposed() const noexcept
+       {
+               return m_isDisposed;
+       }
+
+       inline void RefCountObjBase::dispose() noexcept
+       {
+               m_isDisposed = true;
+       }
+}
diff --git a/ucl/inc/ucl/util/memory/SharedRef.h b/ucl/inc/ucl/util/memory/SharedRef.h
new file mode 100644 (file)
index 0000000..15b0d49
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef __UCL_UTIL_MEMORY_SHARED_REF_H__
+#define __UCL_UTIL_MEMORY_SHARED_REF_H__
+
+#include "BaseRef.h"
+
+namespace ucl {
+
+       template <class T>
+       class SharedRef : public BaseRef<T> {
+       public:
+               template <class U>
+               friend void swap(SharedRef<U> &x, SharedRef<U> &y) noexcept;
+
+               template <class T2, class U>
+               friend SharedRef<T2> staticRefCast(const SharedRef<U> &r) noexcept;
+               template <class T2, class U>
+               friend SharedRef<T2> dynamicRefCast(const SharedRef<U> &r) noexcept;
+
+       public:
+               constexpr SharedRef() noexcept;
+               constexpr SharedRef(nullptr_t) noexcept;
+
+               SharedRef(RefCountObjBase *rc, T *ptr) noexcept;
+
+               SharedRef(const SharedRef<T> &r) noexcept;
+               template <class U>
+               SharedRef(const BaseRef<U> &r) noexcept;
+
+               SharedRef(SharedRef<T> &&r) noexcept;
+               template <class U>
+               SharedRef(SharedRef<U> &&r) noexcept;
+
+               ~SharedRef();
+
+               SharedRef<T> &operator=(SharedRef<T> r) noexcept;
+
+               void reset() noexcept;
+
+               T *get() const noexcept;
+               operator bool() const noexcept;
+
+               template <class U, class = typename std::enable_if<
+                       std::is_convertible<T *, U *>::value && (
+                               std::is_same<typename std::remove_cv<U>::type, void>::value ||
+                               std::is_same<typename std::remove_cv<U>::type,
+                                       typename std::remove_cv<T>::type>::value)>::type>
+               operator const SharedRef<U> &() const noexcept
+               {
+                       return reinterpret_cast<const SharedRef<U> &>(*this);
+               }
+       };
+
+       // Non-member functions //
+
+       template <class T, class ...ARGS>
+       SharedRef<T> makeShared(ARGS &&...args);
+
+       template <class T, class U>
+       const SharedRef<T> &constRefCast(const SharedRef<U> &r) noexcept;
+       template <class T, class U>
+       SharedRef<T> &&constRefCast(SharedRef<U> &&r) noexcept;
+}
+
+#include "SharedRef.hpp"
+
+#endif // __UCL_UTIL_MEMORY_SHARED_REF_H__
diff --git a/ucl/inc/ucl/util/memory/SharedRef.hpp b/ucl/inc/ucl/util/memory/SharedRef.hpp
new file mode 100644 (file)
index 0000000..29d8ad2
--- /dev/null
@@ -0,0 +1,133 @@
+#include "RefCountObj.h"
+
+namespace ucl {
+
+       template <class T>
+       constexpr SharedRef<T>::SharedRef() noexcept
+       {
+       }
+
+       template <class T>
+       constexpr SharedRef<T>::SharedRef(nullptr_t) noexcept
+       {
+       }
+
+       template <class T>
+       inline SharedRef<T>::SharedRef(
+                       RefCountObjBase *const rc, T *const ptr) noexcept :
+               BaseRef<T>(rc, ptr)
+       {
+               this->m_rc->ref();
+       }
+
+       template <class T>
+       inline SharedRef<T>::SharedRef(const SharedRef<T> &r) noexcept :
+               BaseRef<T>(r.m_rc, r.m_ptr)
+       {
+               if (this->m_rc) {
+                       this->m_rc->ref();
+               }
+       }
+
+       template <class T>
+       template <class U>
+       inline SharedRef<T>::SharedRef(const BaseRef<U> &r) noexcept :
+               BaseRef<T>(r.m_rc, r.m_ptr)
+       {
+               if (this->m_rc) {
+                       this->m_rc->ref();
+               }
+       }
+
+       template <class T>
+       inline SharedRef<T>::SharedRef(SharedRef<T> &&r) noexcept :
+               BaseRef<T>(std::move(r))
+       {
+       }
+
+       template <class T>
+       template <class U>
+       inline SharedRef<T>::SharedRef(SharedRef<U> &&r) noexcept :
+               BaseRef<T>(std::move(r))
+       {
+       }
+
+       template <class T>
+       inline SharedRef<T>::~SharedRef()
+       {
+               if (this->m_rc) {
+                       this->m_rc->unref();
+               }
+       }
+
+       template <class T>
+       inline SharedRef<T> &SharedRef<T>::operator=(SharedRef<T> r) noexcept
+       {
+               swap(*this, r);
+               return *this;
+       }
+
+       template <class T>
+       inline void SharedRef<T>::reset() noexcept
+       {
+               *this = {};
+       }
+
+       template <class T>
+       inline T *SharedRef<T>::get() const noexcept
+       {
+               return this->m_ptr;
+       }
+
+       template <class T>
+       inline SharedRef<T>::operator bool() const noexcept
+       {
+               return !!this->m_ptr;
+       }
+
+       // Non-member functions //
+
+       template <class T, class ...ARGS>
+       SharedRef<T> makeShared(ARGS &&...args)
+       {
+               const auto rc = new RefCountObj<T>(std::forward<ARGS>(args)...);
+               return {rc, rc->getObj()};
+       }
+
+       template <class T>
+       inline void swap(SharedRef<T> &x, SharedRef<T> &y) noexcept
+       {
+               std::swap(x.m_rc, y.m_rc);
+               std::swap(x.m_ptr, y.m_ptr);
+       }
+
+       template <class T, class U>
+       inline SharedRef<T> staticRefCast(const SharedRef<U> &r) noexcept
+       {
+               return {r.m_rc, static_cast<T *>(r.get())};
+       }
+
+       template <class T, class U>
+       inline SharedRef<T> dynamicRefCast(const SharedRef<U> &r) noexcept
+       {
+               const auto ptr = dynamic_cast<T *>(r.get());
+               if (!ptr) {
+                       return {};
+               }
+               return {r.m_rc, ptr};
+       }
+
+       template <class T, class U>
+       inline const SharedRef<T> &constRefCast(const SharedRef<U> &r) noexcept
+       {
+               (void)const_cast<T *>((U *)nullptr);
+               return reinterpret_cast<const SharedRef<T> &>(r);
+       }
+
+       template <class T, class U>
+       inline SharedRef<T> &&constRefCast(SharedRef<U> &&r) noexcept
+       {
+               (void)const_cast<T *>((U *)nullptr);
+               return reinterpret_cast<SharedRef<T> &&>(r);
+       }
+}
diff --git a/ucl/inc/ucl/util/memory/WeakRef.h b/ucl/inc/ucl/util/memory/WeakRef.h
new file mode 100644 (file)
index 0000000..a755f2a
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef __UCL_UTIL_MEMORY_WEAK_REF_H__
+#define __UCL_UTIL_MEMORY_WEAK_REF_H__
+
+#include "SharedRef.h"
+
+namespace ucl {
+
+       template <class T>
+       class WeakRef : public BaseRef<T> {
+       public:
+               template <class U>
+               friend void swap(WeakRef<U> &x, WeakRef<U> &y) noexcept;
+
+               template <class T2, class U>
+               friend WeakRef<T2> staticRefCast(const WeakRef<U> &r) noexcept;
+               template <class T2, class U>
+               friend WeakRef<T2> dynamicRefCast(const WeakRef<U> &r) noexcept;
+
+       public:
+               constexpr WeakRef() noexcept;
+               constexpr WeakRef(nullptr_t) noexcept;
+
+               WeakRef(RefCountObjBase *rc, T *ptr) noexcept;
+
+               WeakRef(const WeakRef<T> &r) noexcept;
+               template <class U>
+               WeakRef(const BaseRef<U> &r) noexcept;
+
+               WeakRef(WeakRef<T> &&r) noexcept;
+               template <class U>
+               WeakRef(WeakRef<U> &&r) noexcept;
+
+               ~WeakRef();
+
+               WeakRef<T> &operator=(WeakRef<T> r) noexcept;
+
+               void reset() noexcept;
+
+               T *get() const noexcept;
+               operator bool() const noexcept;
+
+               template <class U, class = typename std::enable_if<
+                       std::is_convertible<T *, U *>::value && (
+                               std::is_same<typename std::remove_cv<U>::type, void>::value ||
+                               std::is_same<typename std::remove_cv<U>::type,
+                                       typename std::remove_cv<T>::type>::value)>::type>
+               operator const WeakRef<U> &() const noexcept
+               {
+                       return reinterpret_cast<const WeakRef<U> &>(*this);
+               }
+       };
+
+       // Non-member functions //
+
+       template <class T>
+       WeakRef<T> makeWeak(const SharedRef<T> &r) noexcept;
+
+       template <class T, class U>
+       const WeakRef<T> &constRefCast(const WeakRef<U> &r) noexcept;
+       template <class T, class U>
+       WeakRef<T> &&constRefCast(WeakRef<U> &&r) noexcept;
+}
+
+#include "WeakRef.hpp"
+
+#endif // __UCL_UTIL_MEMORY_WEAK_REF_H__
diff --git a/ucl/inc/ucl/util/memory/WeakRef.hpp b/ucl/inc/ucl/util/memory/WeakRef.hpp
new file mode 100644 (file)
index 0000000..3fcee28
--- /dev/null
@@ -0,0 +1,130 @@
+namespace ucl {
+
+       template <class T>
+       constexpr WeakRef<T>::WeakRef() noexcept
+       {
+       }
+
+       template <class T>
+       constexpr WeakRef<T>::WeakRef(nullptr_t) noexcept
+       {
+       }
+
+       template <class T>
+       inline WeakRef<T>::WeakRef(
+                       RefCountObjBase *const rc, T *const ptr) noexcept :
+               BaseRef<T>(rc, ptr)
+       {
+               this->m_rc->refWeak();
+       }
+
+       template <class T>
+       inline WeakRef<T>::WeakRef(const WeakRef<T> &r) noexcept :
+               BaseRef<T>(r.m_rc, r.m_ptr)
+       {
+               if (this->m_rc) {
+                       this->m_rc->refWeak();
+               }
+       }
+
+       template <class T>
+       template <class U>
+       inline WeakRef<T>::WeakRef(const BaseRef<U> &r) noexcept :
+               BaseRef<T>(r.m_rc, r.m_ptr)
+       {
+               if (this->m_rc) {
+                       this->m_rc->refWeak();
+               }
+       }
+
+       template <class T>
+       inline WeakRef<T>::WeakRef(WeakRef<T> &&r) noexcept :
+               BaseRef<T>(std::move(r))
+       {
+       }
+
+       template <class T>
+       template <class U>
+       inline WeakRef<T>::WeakRef(WeakRef<U> &&r) noexcept :
+               BaseRef<T>(std::move(r))
+       {
+       }
+
+       template <class T>
+       inline WeakRef<T>::~WeakRef()
+       {
+               if (this->m_rc) {
+                       this->m_rc->unrefWeak();
+               }
+       }
+
+       template <class T>
+       inline WeakRef<T> &WeakRef<T>::operator=(WeakRef<T> r) noexcept
+       {
+               swap(*this, r);
+               return *this;
+       }
+
+       template <class T>
+       inline void WeakRef<T>::reset() noexcept
+       {
+               *this = {};
+       }
+
+       template <class T>
+       inline T *WeakRef<T>::get() const noexcept
+       {
+               return (operator bool() ? this->m_ptr : nullptr);
+       }
+
+       template <class T>
+       inline WeakRef<T>::operator bool() const noexcept
+       {
+               return (this->m_ptr && !this->m_rc->isDisposed());
+       }
+
+       // Non-member functions //
+
+       template <class T>
+       inline WeakRef<T> makeWeak(const SharedRef<T> &r) noexcept
+       {
+               return r;
+       }
+
+       template <class T>
+       inline void swap(WeakRef<T> &x, WeakRef<T> &y) noexcept
+       {
+               std::swap(x.m_rc, y.m_rc);
+               std::swap(x.m_ptr, y.m_ptr);
+       }
+
+       template <class T, class U>
+       inline WeakRef<T> staticRefCast(const WeakRef<U> &r) noexcept
+       {
+               return {r.m_rc, static_cast<T *>(r.get())};
+       }
+
+       template <class T, class U>
+       inline WeakRef<T> dynamicRefCast(const WeakRef<U> &r) noexcept
+       {
+               const auto ptr = dynamic_cast<T *>(r.get());
+               if (!ptr) {
+                       return {};
+               }
+               return {r.m_rc, ptr};
+       }
+
+       template <class T, class U>
+       inline const WeakRef<T> &constRefCast(const WeakRef<U> &r) noexcept
+       {
+               (void)const_cast<T *>((U *)nullptr);
+               return reinterpret_cast<const WeakRef<T> &>(r);
+       }
+
+       template <class T, class U>
+       inline WeakRef<T> &&constRefCast(WeakRef<U> &&r) noexcept
+       {
+               (void)const_cast<T *>((U *)nullptr);
+               return reinterpret_cast<WeakRef<T> &&>(r);
+       }
+}
diff --git a/ucl/inc/ucl/util/memory/helpers.h b/ucl/inc/ucl/util/memory/helpers.h
new file mode 100644 (file)
index 0000000..96921b1
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef __UCL_UTIL_MEMORY_HELPERS_H__
+#define __UCL_UTIL_MEMORY_HELPERS_H__
+
+namespace ucl {
+
+       // Generic casting functions //
+
+       template <class T, class U>
+       inline auto dynamicCast(const U &src) noexcept -> decltype(
+                       dynamicRefCast<typename T::Type>(src))
+       {
+               return dynamicRefCast<typename T::Type>(src);
+       }
+
+       template <class T, class U>
+       inline auto constCast(U &&src) noexcept -> decltype(
+                       constRefCast<typename T::Type>(std::forward<U>(src)))
+       {
+               return constRefCast<typename T::Type>(std::forward<U>(src));
+       }
+
+       // Relation operators //
+
+       template <class T, class U, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value &&
+               std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+       inline bool operator==(const T &lhs, const U &rhs) noexcept
+       {
+               return (lhs.get() == rhs.get());
+       }
+
+       template <class T, class U, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value &&
+               std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+       inline bool operator!=(const T &lhs, const U &rhs) noexcept
+       {
+               return (lhs.get() != rhs.get());
+       }
+
+       template <class T, class U, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value &&
+               std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+       inline bool operator<(const T &lhs, const U &rhs) noexcept
+       {
+               return (lhs.get() < rhs.get());
+       }
+
+       template <class T, class U, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value &&
+               std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+       inline bool operator<=(const T &lhs, const U &rhs) noexcept
+       {
+               return (lhs.get() <= rhs.get());
+       }
+
+       template <class T, class U, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value &&
+               std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+       inline bool operator>(const T &lhs, const U &rhs) noexcept
+       {
+               return (lhs.get() > rhs.get());
+       }
+
+       template <class T, class U, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value &&
+               std::is_base_of<BaseRef<typename U::Type>, U>::value>::type>
+       inline bool operator>=(const T &lhs, const U &rhs) noexcept
+       {
+               return (lhs.get() >= rhs.get());
+       }
+
+       template <class T, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value>::type>
+       inline bool operator==(const T &lhs, nullptr_t rhs) noexcept
+       {
+               return !lhs;
+       }
+
+       template <class T, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value>::type>
+       bool operator==(nullptr_t lhs, const T &rhs) noexcept
+       {
+               return !rhs;
+       }
+
+       template <class T, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value>::type>
+       bool operator!=(const T &lhs, nullptr_t rhs) noexcept
+       {
+               return lhs;
+       }
+
+       template <class T, class = typename std::enable_if<
+               std::is_base_of<BaseRef<typename T::Type>, T>::value>::type>
+       bool operator!=(nullptr_t lhs, const T &rhs) noexcept
+       {
+               return rhs;
+       }
+}
+
+#endif // __UCL_UTIL_MEMORY_HELPERS_H__
diff --git a/ucl/inc/ucl/util/memory/macro.h b/ucl/inc/ucl/util/memory/macro.h
new file mode 100644 (file)
index 0000000..a273096
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __UCL_UTIL_MEMORY_MACRO_H__
+#define __UCL_UTIL_MEMORY_MACRO_H__
+
+#define UCL_DECLARE_REF_ALIASES(CLASS_NAME) \
+               class CLASS_NAME; \
+               using CLASS_NAME##SRef = ::ucl::SharedRef<CLASS_NAME>; \
+               using CLASS_NAME##WRef = ::ucl::WeakRef<CLASS_NAME>; \
+               using CLASS_NAME##SCRef = ::ucl::SharedRef<const CLASS_NAME>; \
+               using CLASS_NAME##WCRef = ::ucl::WeakRef<const CLASS_NAME>
+
+#endif // __UCL_UTIL_MEMORY_MACRO_H__
diff --git a/ucl/inc/ucl/util/shortLogs.h b/ucl/inc/ucl/util/shortLogs.h
new file mode 100644 (file)
index 0000000..0e1edd4
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef __UCL_UTIL_SHORT_LOGS_H__
+#define __UCL_UTIL_SHORT_LOGS_H__
+
+#undef ULOG
+#undef URESDATALOG
+#undef URESLOG
+
+#undef VLOG
+#undef DLOG
+#undef ILOG
+#undef WLOG
+#undef ELOG
+#undef FLOG
+
+#undef VRESLOG
+#undef DRESLOG
+#undef IRESLOG
+#undef WRESLOG
+#undef ERESLOG
+#undef FRESLOG
+
+#undef RESLOG
+
+#undef RETVM_IF
+#undef RETM_IF
+
+#undef FAIL_RETURN
+#undef FAIL_RETURN_VALUE
+#undef FAIL_RETURN_VOID
+#undef FAIL_BREAK
+#undef FAIL_LOG
+
+#undef LOG_RETURN
+#undef LOG_RETURN_VALUE
+#undef LOG_RETURN_VOID
+#undef LOG_BREAK
+
+#define ULOG         UCL_ULOG
+#define URESDATALOG  UCL_URESDATALOG
+#define URESLOG      UCL_URESLOG
+
+#define VLOG  UCL_VLOG
+#define DLOG  UCL_DLOG
+#define ILOG  UCL_ILOG
+#define WLOG  UCL_WLOG
+#define ELOG  UCL_ELOG
+#define FLOG  UCL_FLOG
+
+#define VRESLOG  UCL_VRESLOG
+#define DRESLOG  UCL_DRESLOG
+#define IRESLOG  UCL_IRESLOG
+#define WRESLOG  UCL_WRESLOG
+#define ERESLOG  UCL_ERESLOG
+#define FRESLOG  UCL_FRESLOG
+
+#define RESLOG  UCL_RESLOG
+
+#define FAIL_RETURN        UCL_FAIL_RETURN
+#define FAIL_RETURN_VALUE  UCL_FAIL_RETURN_VALUE
+#define FAIL_RETURN_VOID   UCL_FAIL_RETURN_VOID
+#define FAIL_BREAK         UCL_FAIL_BREAK
+#define FAIL_LOG           UCL_FAIL_LOG
+
+#define LOG_RETURN        UCL_LOG_RETURN
+#define LOG_RETURN_VALUE  UCL_LOG_RETURN_VALUE
+#define LOG_RETURN_VOID   UCL_LOG_RETURN_VOID
+#define LOG_BREAK         UCL_LOG_BREAK
+
+#endif // __UCL_UTIL_SHORT_LOGS_H__
diff --git a/ucl/inc/ucl/util/threading.h b/ucl/inc/ucl/util/threading.h
new file mode 100644 (file)
index 0000000..f8724f2
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __UCL_UTIL_THREADING_H__
+#define __UCL_UTIL_THREADING_H__
+
+#include "threading/Thread.h"
+#include "threading/Mutex.h"
+#include "threading/MutexLock.h"
+#include "threading/CondVar.h"
+
+#endif // __UCL_UTIL_THREADING_H__
diff --git a/ucl/inc/ucl/util/threading/CondVar.h b/ucl/inc/ucl/util/threading/CondVar.h
new file mode 100644 (file)
index 0000000..dc7c94d
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef __UCL_UTIL_THREADING_COND_VAR_H__
+#define __UCL_UTIL_THREADING_COND_VAR_H__
+
+#include "MutexLock.h"
+
+namespace ucl {
+
+       class CondVar : public NonCopyable {
+       public:
+               CondVar();
+               ~CondVar();
+               void wait(MutexLock &lock);
+               void notify();
+               void notifyAll();
+               pthread_cond_t *getHandle();
+       private:
+               pthread_cond_t m_cond;
+       };
+}
+
+#include "CondVar.hpp"
+
+#endif // __UCL_UTIL_THREADING_COND_VAR_H__
diff --git a/ucl/inc/ucl/util/threading/CondVar.hpp b/ucl/inc/ucl/util/threading/CondVar.hpp
new file mode 100644 (file)
index 0000000..eb7be06
--- /dev/null
@@ -0,0 +1,33 @@
+namespace ucl {
+
+       inline CondVar::CondVar() :
+               m_cond()
+       {
+               pthread_cond_init(&m_cond, NULL);
+       }
+
+       inline CondVar::~CondVar()
+       {
+               pthread_cond_destroy(&m_cond);
+       }
+
+       inline void CondVar::wait(MutexLock &lock)
+       {
+               pthread_cond_wait(&m_cond, lock.getMutex().getHandle());
+       }
+
+       inline void CondVar::notify()
+       {
+               pthread_cond_signal(&m_cond);
+       }
+
+       inline void CondVar::notifyAll()
+       {
+               pthread_cond_broadcast(&m_cond);
+       }
+
+       inline pthread_cond_t *CondVar::getHandle()
+       {
+               return &m_cond;
+       }
+}
diff --git a/ucl/inc/ucl/util/threading/Mutex.h b/ucl/inc/ucl/util/threading/Mutex.h
new file mode 100644 (file)
index 0000000..8e53e0a
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef __UCL_UTIL_THREADING_MUTEX_H__
+#define __UCL_UTIL_THREADING_MUTEX_H__
+
+// Use pthread because Tizen 3.0 officially not support C++ 11
+// And there were problems with threading in C++ 11 and Tizen 3.0
+#include <pthread.h>
+
+#include "ucl/util/types/classTypes.h"
+
+namespace ucl {
+
+       class Mutex : public NonCopyable {
+       public:
+               Mutex();
+               ~Mutex();
+               void lock();
+               void unlock();
+               pthread_mutex_t *getHandle();
+       private:
+               pthread_mutex_t m_mutex;
+       };
+}
+
+#include "Mutex.hpp"
+
+#endif // __UCL_UTIL_THREADING_MUTEX_H__
diff --git a/ucl/inc/ucl/util/threading/Mutex.hpp b/ucl/inc/ucl/util/threading/Mutex.hpp
new file mode 100644 (file)
index 0000000..71e5baa
--- /dev/null
@@ -0,0 +1,28 @@
+namespace ucl {
+
+       inline Mutex::Mutex() :
+               m_mutex()
+       {
+               pthread_mutex_init(&m_mutex, NULL);
+       }
+
+       inline Mutex::~Mutex()
+       {
+               pthread_mutex_destroy(&m_mutex);
+       }
+
+       inline void Mutex::lock()
+       {
+               pthread_mutex_lock(&m_mutex);
+       }
+
+       inline void Mutex::unlock()
+       {
+               pthread_mutex_unlock(&m_mutex);
+       }
+
+       inline pthread_mutex_t *Mutex::getHandle()
+       {
+               return &m_mutex;
+       }
+}
diff --git a/ucl/inc/ucl/util/threading/MutexLock.h b/ucl/inc/ucl/util/threading/MutexLock.h
new file mode 100644 (file)
index 0000000..a982b0c
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __UCL_UTIL_THREADING_MUTEX_LOCK_H__
+#define __UCL_UTIL_THREADING_MUTEX_LOCK_H__
+
+#include "Mutex.h"
+
+namespace ucl {
+
+       class MutexLock : public NonCopyable {
+       public:
+               MutexLock(Mutex &mutex);
+               ~MutexLock();
+               Mutex &getMutex();
+       private:
+               Mutex &m_mutex;
+       };
+}
+
+#include "MutexLock.hpp"
+
+#endif // __UCL_UTIL_THREADING_MUTEX_LOCK_H__
diff --git a/ucl/inc/ucl/util/threading/MutexLock.hpp b/ucl/inc/ucl/util/threading/MutexLock.hpp
new file mode 100644 (file)
index 0000000..251978e
--- /dev/null
@@ -0,0 +1,18 @@
+namespace ucl {
+
+       inline MutexLock::MutexLock(Mutex &mutex) :
+               m_mutex(mutex)
+       {
+               mutex.lock();
+       }
+
+       inline MutexLock::~MutexLock()
+       {
+               m_mutex.unlock();
+       }
+
+       inline Mutex &MutexLock::getMutex()
+       {
+               return m_mutex;
+       }
+}
diff --git a/ucl/inc/ucl/util/threading/Thread.h b/ucl/inc/ucl/util/threading/Thread.h
new file mode 100644 (file)
index 0000000..52bef4b
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef __UCL_UTIL_THREADING_THREAD_H__
+#define __UCL_UTIL_THREADING_THREAD_H__
+
+// Use pthread because Tizen 3.0 officially not support C++ 11
+// And there were problems with threading in C++ 11 and Tizen 3.0
+#include <pthread.h>
+
+#include "ucl/util/types/classTypes.h"
+
+namespace ucl {
+
+       class Thread : public NonCopyable {
+       public:
+               explicit Thread(bool createSuspended = false);
+               virtual ~Thread();
+               bool wasStarted() const;
+               bool wasJoinded() const;
+               bool start();
+               void join();
+               pthread_t *getHandle();
+       protected:
+               virtual void execute() = 0;
+       private:
+               pthread_t m_thread;
+               bool m_wasStarted;
+               bool m_wasJoined;
+       };
+}
+
+#include "Thread.hpp"
+
+#endif // __UCL_UTIL_THREADING_THREAD_H__
diff --git a/ucl/inc/ucl/util/threading/Thread.hpp b/ucl/inc/ucl/util/threading/Thread.hpp
new file mode 100644 (file)
index 0000000..2027f44
--- /dev/null
@@ -0,0 +1,71 @@
+#include "ucl/util/logging.h"
+
+namespace ucl {
+
+       inline Thread::Thread(bool createSuspended) :
+               m_thread(),
+               m_wasStarted(false),
+               m_wasJoined(false)
+       {
+               if (!createSuspended) {
+                       start();
+               }
+       }
+
+       inline Thread::~Thread()
+       {
+               if (!m_wasJoined) {
+                       join();
+               }
+       }
+
+       inline bool Thread::wasStarted() const
+       {
+               return m_wasStarted;
+       }
+
+       inline bool Thread::wasJoinded() const
+       {
+               return m_wasJoined;
+       }
+
+       inline bool Thread::start()
+       {
+               if (m_wasStarted) {
+                       UCL_WLOG("Already started!");
+                       return false;
+               }
+               const int res = pthread_create(&m_thread, NULL,
+                       [](void *data) -> void *
+                       {
+                               static_cast<Thread *>(data)->execute();
+                               return nullptr;
+                       },
+                       this);
+               if (res != 0) {
+                       UCL_ELOG("pthread_create() failed: %d", res);
+                       return false;
+               }
+               m_wasStarted = true;
+               return true;
+       }
+
+       inline void Thread::join()
+       {
+               if (!m_wasStarted) {
+                       UCL_WLOG("Not stared started!");
+                       return;
+               }
+               if (m_wasJoined) {
+                       UCL_WLOG("Already joined!");
+                       return;
+               }
+               m_wasJoined = true;
+               pthread_join(m_thread, NULL);
+       }
+
+       inline pthread_t *Thread::getHandle()
+       {
+               return ((m_wasStarted && !m_wasJoined) ? &m_thread : NULL);
+       }
+}
diff --git a/ucl/inc/ucl/util/types.h b/ucl/inc/ucl/util/types.h
new file mode 100644 (file)
index 0000000..e20ca41
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __UCL_UTIL_TYPES_H__
+#define __UCL_UTIL_TYPES_H__
+
+#include "types/baseTypes.h"
+#include "types/classTypes.h"
+#include "types/Result.h"
+
+#endif // __UCL_UTIL_TYPES_H__
diff --git a/ucl/inc/ucl/util/types/Result.h b/ucl/inc/ucl/util/types/Result.h
new file mode 100644 (file)
index 0000000..8f83301
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef __UCL_UTIL_TYPES_RESULT_H__
+#define __UCL_UTIL_TYPES_RESULT_H__
+
+#include "baseTypes.h"
+
+namespace ucl {
+
+       // ResultData declaration //
+
+       struct ResultData {
+               const char *name;
+               int logPrio;
+       };
+
+       // Result declaration //
+
+       struct Result {
+               int value;
+
+               Result() = default;
+
+               template <class VALUE, class = char(*)[VALUE::_UCL_RESULT * 0 + 1]>
+               constexpr Result(const VALUE &v) : value(v) {}
+       };
+
+       // Result non-member functions //
+
+       const ResultData &getResultData(Result result);
+
+       constexpr bool isGood(Result result);
+       constexpr bool isBad(Result result);
+
+       constexpr bool operator==(Result lhs, Result rhs);
+       constexpr bool operator!=(Result lhs, Result rhs);
+
+       // Basic Result values //
+
+       enum {
+               _UCL_RESULT,
+
+               RES_OK    = 0,
+               RES_FALSE = 1,
+               _RES_END,
+
+               RES_FAIL              = -1,
+               RES_INVALID_ARGUMENTS = -2,
+               RES_ILLEGAL_STATE     = -3,
+               RES_OUT_OF_MEMORY     = -4,
+               RES_IO_ERROR          = -5,
+               RES_NOT_SUPPORTED     = -6,
+               RES_INVALID_DATA      = -7,
+               // TODO MUST match previous item!
+               _RES_BEGIN            = RES_INVALID_DATA
+       };
+}
+
+#include "Result.hpp"
+
+#endif // __UCL_UTIL_TYPES_RESULT_H__
diff --git a/ucl/inc/ucl/util/types/Result.hpp b/ucl/inc/ucl/util/types/Result.hpp
new file mode 100644 (file)
index 0000000..9c3fd38
--- /dev/null
@@ -0,0 +1,22 @@
+namespace ucl {
+
+       constexpr bool isGood(const Result result)
+       {
+               return (result.value >= RES_OK);
+       }
+
+       constexpr bool isBad(const Result result)
+       {
+               return !isGood(result);
+       }
+
+       constexpr bool operator==(const Result lhs, const Result rhs)
+       {
+               return (lhs.value == rhs.value);
+       }
+
+       constexpr bool operator!=(const Result lhs, const Result rhs)
+       {
+               return (lhs.value != rhs.value);
+       }
+}
diff --git a/ucl/inc/ucl/util/types/baseTypes.h b/ucl/inc/ucl/util/types/baseTypes.h
new file mode 100644 (file)
index 0000000..50bcfba
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef __UCL_UTIL_TYPES_BASE_TYPES_H__
+#define __UCL_UTIL_TYPES_BASE_TYPES_H__
+
+#include <cstddef>
+#include <cstdlib>
+#include <cstdint>
+
+#include <string>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
+#include <Eina.h>
+
+#include "ucl/config.h"
+
+namespace ucl {
+       using UInt = unsigned int;
+}
+
+#endif // __UCL_UTIL_TYPES_BASE_TYPES_H__
diff --git a/ucl/inc/ucl/util/types/classTypes.h b/ucl/inc/ucl/util/types/classTypes.h
new file mode 100644 (file)
index 0000000..d264084
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef __UCL_UTIL_TYPES_CLASS_TYPES_H__
+#define __UCL_UTIL_TYPES_CLASS_TYPES_H__
+
+#include "baseTypes.h"
+
+namespace ucl {
+
+       class NonCopyable {
+       public:
+               NonCopyable(const NonCopyable &) = delete;
+               NonCopyable &operator=(const NonCopyable &) = delete;
+       protected:
+               NonCopyable() = default;
+               ~NonCopyable() = default;
+       };
+
+       class Polymorphic : public NonCopyable {
+       protected:
+               Polymorphic() = default;
+               virtual ~Polymorphic() = default;
+       };
+
+       class IDisposable : public Polymorphic {
+       public:
+               virtual void dispose() = 0;
+       protected:
+               virtual ~IDisposable() = default;
+       };
+
+       template <class IPRODUCT>
+       class IFactory : public Polymorphic {
+       public:
+               using IProduct = IPRODUCT;
+       public:
+               virtual IPRODUCT *newInstance() const = 0;
+       protected:
+               ~IFactory() = default;
+       };
+
+       template <class PRODUCT, class IPRODUCT>
+       class Factory : public IFactory<IPRODUCT> {
+       public:
+               using Product = PRODUCT;
+       public:
+               virtual IPRODUCT *newInstance() const final override
+               {
+                       return new PRODUCT();
+               }
+       };
+
+       // Priority selector for SFINAE functions
+       template <int N>
+       struct P : P<N - 1> {};
+       template <>
+       struct P<0> {};
+}
+
+#endif // __UCL_UTIL_TYPES_CLASS_TYPES_H__
diff --git a/ucl/src/appfw/InstanceManagerBase.cpp b/ucl/src/appfw/InstanceManagerBase.cpp
new file mode 100644 (file)
index 0000000..8929394
--- /dev/null
@@ -0,0 +1,31 @@
+#include "ucl/appfw/InstanceManagerBase.h"
+
+#include "../common.h"
+
+namespace ucl {
+
+       InstanceManagerBase::InstanceManagerBase(AppParams appParams) :
+               m_appParams(std::move(appParams))
+       {
+       }
+
+       InstanceManagerBase::~InstanceManagerBase()
+       {
+       }
+
+       const AppParams &InstanceManagerBase::getAppParams() const
+       {
+               return m_appParams;
+       }
+
+       void InstanceManagerBase::setSysEventProvider(SysEventProviderUPtr provider)
+       {
+               m_sysEventProvider = std::move(provider);
+       }
+
+       SysEventProvider &InstanceManagerBase::getSysEventProvider() const
+       {
+               UCL_ASSERT(m_sysEventProvider, "m_sysEventProvider is NULL!");
+               return *m_sysEventProvider;
+       }
+}
diff --git a/ucl/src/appfw/SysEventProvider.cpp b/ucl/src/appfw/SysEventProvider.cpp
new file mode 100644 (file)
index 0000000..459bdb1
--- /dev/null
@@ -0,0 +1,97 @@
+#include "ucl/appfw/SysEventProvider.h"
+
+#include "../common.h"
+
+namespace ucl {
+
+       // SysEventProvider::EventProxy //
+
+       class SysEventProvider::EventProxy : public NonCopyable {
+       public:
+               EventProxy(SysEventProvider &provider,
+                               const SysEvent sysEvent,
+                               const app_event_type_e appEvent):
+                       m_provider(provider),
+                       m_sysEvent(sysEvent)
+               {
+                       const int res = m_provider.addEventHandler(&m_eventHandler,
+                                       appEvent, CALLBACK_B(EventProxy::onAppEvent), this);
+                       if (res != APP_ERROR_NONE) {
+                               if (res != APP_ERROR_INVALID_PARAMETER) {
+                                       ELOG("addEventHandler() failed! %d", res);
+                               }
+                               m_eventHandler = nullptr;
+                       }
+               }
+
+               ~EventProxy()
+               {
+                       if (m_eventHandler) {
+                               const int res = m_provider.delEventHandler(m_eventHandler);
+                               if (res != APP_ERROR_NONE) {
+                                       WLOG("delEventHandler() failed! %d", res);
+                               }
+                       }
+               }
+
+       private:
+               void onAppEvent(app_event_info_h event)
+               {
+                       m_provider.dispatch(m_sysEvent);
+               }
+
+       private:
+               SysEventProvider &m_provider;
+               app_event_handler_h m_eventHandler;
+               SysEvent m_sysEvent;
+       };
+
+       // SysEventProvider //
+
+       SysEventProvider::SysEventProvider(EventHandlerAddFunc addFunc,
+                       EventHandlerDelFunc delFunc):
+               m_addFunc(addFunc),
+               m_delFunc(delFunc)
+       {
+               m_eventProxies.emplace_back(*this, SysEvent::LANGUAGE_CHANGED,
+                               APP_EVENT_LANGUAGE_CHANGED);
+
+               m_eventProxies.emplace_back(*this, SysEvent::REGION_FMT_CHANGED,
+                               APP_EVENT_REGION_FORMAT_CHANGED);
+
+               m_eventProxies.emplace_back(*this, SysEvent::LOW_MEMORY,
+                               APP_EVENT_LOW_MEMORY);
+
+               m_eventProxies.emplace_back(*this, SysEvent::LOW_BATTERY,
+                               APP_EVENT_LOW_BATTERY);
+
+               m_eventProxies.emplace_back(*this, SysEvent::ORIENTATION_CHANGED,
+                               APP_EVENT_DEVICE_ORIENTATION_CHANGED);
+
+               m_eventProxies.emplace_back(*this, SysEvent::SUSPEND_STATE_CHANGED,
+                               APP_EVENT_SUSPENDED_STATE_CHANGED);
+
+               m_eventProxies.emplace_back(*this, SysEvent::UPDATE_REQUESTED,
+                               APP_EVENT_UPDATE_REQUESTED);
+       }
+
+       SysEventProvider::~SysEventProvider()
+       {
+       }
+
+       int SysEventProvider::addEventHandler(app_event_handler_h *handler,
+                       app_event_type_e appEvent, app_event_cb cb, void *data)
+       {
+               return m_addFunc(handler, appEvent, cb, data);
+       }
+
+       int SysEventProvider::delEventHandler(app_event_handler_h handler)
+       {
+               return m_delFunc(handler);
+       }
+
+       void SysEventProvider::dispatch(SysEvent sysEvent)
+       {
+               m_event.invoke(sysEvent);
+       }
+}
diff --git a/ucl/src/appfw/UIApp.cpp b/ucl/src/appfw/UIApp.cpp
new file mode 100644 (file)
index 0000000..c33a34e
--- /dev/null
@@ -0,0 +1,178 @@
+#include "ucl/appfw/UIApp.h"
+
+#include <app.h>
+
+#include "ucl/appfw/IInstanceAppControlExt.h"
+#include "../common.h"
+
+namespace ucl {
+
+       UIApp::UIApp(InstanceManagerBase &instanceMgr) :
+               m_instanceMgr(instanceMgr)
+       {
+       }
+
+       UIApp::~UIApp()
+       {
+       }
+
+       int UIApp::run(int argc, char *argv[])
+       {
+               ui_app_lifecycle_callback_s alcc = {};
+               alcc.create = CALLBACK_B(UIApp::onCreate);
+               alcc.terminate = CALLBACK_B(UIApp::onTerminate);
+               alcc.pause = CALLBACK_B(UIApp::onPause);
+               alcc.resume = CALLBACK_B(UIApp::onResume);
+               alcc.app_control = CALLBACK_B(UIApp::onAppControl);
+
+               const int ret = ui_app_main(argc, argv, &alcc, this);
+               if (ret != APP_ERROR_NONE) {
+                       LOG_RETURN_VALUE(RES_FAIL, ret, "ui_app_main() failed! %d", ret);
+               }
+
+               return 0;
+       }
+
+       AppType UIApp::getAppType() const
+       {
+               return AppType::UI;
+       }
+
+       WindowSRef UIApp::getWindow()
+       {
+               return m_window;
+       }
+
+       void UIApp::exitApp()
+       {
+               ui_app_exit();
+       }
+
+       bool UIApp::onCreate()
+       {
+               FAIL_RETURN_VALUE(configParams(), false, "configParams() failed!");
+
+               FAIL_RETURN_VALUE(createWindow(), false, "createWindow() failed!");
+
+               initSysEventManager();
+
+               FAIL_RETURN_VALUE(createInstance(), false, "createInstance() failed!");
+
+               return true;
+       }
+
+       void UIApp::onTerminate()
+       {
+               m_instance.reset();
+               m_instanceMgr.setSysEventProvider(nullptr);
+               m_window.reset();
+       }
+
+       void UIApp::onPause()
+       {
+               if (m_instance) {
+                       m_instance->onPause();
+               }
+       }
+
+       void UIApp::onResume()
+       {
+               if (m_instance) {
+                       m_instance->onResume();
+               }
+       }
+
+       void UIApp::onAppControl(app_control_h appControl)
+       {
+               auto instance = dynamic_cast<
+                               IInstanceAppControlExt *>(m_instance.get());
+               if (instance) {
+                       instance->onAppControl(appControl);
+               }
+       }
+
+       Result UIApp::configParams()
+       {
+               auto &&appParams = m_instanceMgr.getAppParams();
+
+               Variant paramValue;
+
+               if (appParams.get(AppParam::BASE_SCALE, paramValue)) {
+                       const double baseScale = paramValue.asDouble();
+                       if (baseScale <= 0.0) {
+                               LOG_RETURN(RES_INVALID_DATA,
+                                               "Invalid parameter BASE_SCALE: %f", baseScale);
+                       }
+                       elm_app_base_scale_set(baseScale);
+               }
+
+               if (appParams.get(AppParam::ACCELERATION_PREFERENECE, paramValue)) {
+                       const char *const accelPreference = paramValue.asString();
+                       if (isEmpty(accelPreference)) {
+                               LOG_RETURN(RES_INVALID_DATA,
+                                               "Invalid parameter ACCELERATION_PREFERENECE: %s",
+                                               accelPreference);
+                       }
+                       elm_config_accel_preference_set(accelPreference);
+               }
+
+               return RES_OK;
+       }
+
+       Result UIApp::createWindow()
+       {
+               auto &&appParams = m_instanceMgr.getAppParams();
+
+               Variant paramValue;
+
+               auto winType = Window::Type::BASIC;
+               if (appParams.get(AppParam::WINDOW_TYPE, paramValue)) {
+                       winType = static_cast<Window::Type>(paramValue.asInt());
+                       if (isNotValid(winType)) {
+                               LOG_RETURN(RES_INVALID_DATA,
+                                               "Invalid parameter WINDOW_TYPE: %d", winType);
+                       }
+               }
+
+               paramValue = appParams.get(AppParam::WINDOW_NAME);
+               if (isEmpty(paramValue)) {
+                       LOG_RETURN(RES_INVALID_DATA, "WINDOW_NAME must not be empty!");
+               }
+
+               m_window = Window::Builder().
+                               setType(winType).
+                               setName({paramValue.asString()}).
+                               setIsOwner(true).
+                               build();
+               if (!m_window) {
+                       LOG_RETURN(RES_FAIL, "Window::Builder().build() Failed!");
+               }
+
+               return RES_OK;
+       }
+
+       void UIApp::initSysEventManager()
+       {
+               m_instanceMgr.setSysEventProvider(
+                               util::makeUnique(new SysEventProvider(
+                                       &ui_app_add_event_handler,
+                                       &ui_app_remove_event_handler)));
+       }
+
+       Result UIApp::createInstance()
+       {
+               auto instance = util::makeUnique(m_instanceMgr.newInstance());
+               if (!instance) {
+                       LOG_RETURN(RES_FAIL, "m_instanceMgr.newInstance() failed!");
+               }
+
+               const auto res = instance->onCreate(this);
+               if (isBad(res)) {
+                       LOG_RETURN(res, "instance->onCreate() failed!");
+               }
+
+               m_instance = std::move(instance);
+
+               return RES_OK;
+       }
+}
diff --git a/ucl/src/common.h b/ucl/src/common.h
new file mode 100644 (file)
index 0000000..24857a2
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __UCL_COMMON_H__
+#define __UCL_COMMON_H__
+
+#include <cmath>
+#include <cstring>
+
+#include <algorithm>
+
+#include <Ecore.h>
+
+#include "ucl/util/types.h"
+#include "ucl/util/helpers.h"
+#include "ucl/util/logging.h"
+#include "ucl/util/shortLogs.h"
+
+#include "ucl/util/delegation/shortMacro.h"
+#include "ucl/misc/smartDelegation/shortMacro.h"
+
+#endif // __UCL_COMMON_H__
diff --git a/ucl/src/gui/EdjeWidget.cpp b/ucl/src/gui/EdjeWidget.cpp
new file mode 100644 (file)
index 0000000..0ca9c0c
--- /dev/null
@@ -0,0 +1,37 @@
+#include "ucl/gui/EdjeWidget.h"
+
+namespace ucl {
+
+       void EdjeWidget::setText(const TString &value)
+       {
+               if (value.isTranslatable()) {
+                       if (value.hasDomain()) {
+                               elm_object_domain_translatable_text_set(
+                                               getEo(), value.getDomain(), value);
+                       } else {
+                               elm_object_translatable_text_set(getEo(), value);
+                       }
+               } else {
+                       elm_object_domain_text_translatable_set(getEo(),
+                                       nullptr, EINA_FALSE);
+                       elm_object_text_set(getEo(), value);
+               }
+       }
+
+       void EdjeWidget::setPartText(const EdjePart part, const TString &value)
+       {
+               if (value.isTranslatable()) {
+                       if (value.hasDomain()) {
+                               elm_object_domain_translatable_part_text_set(
+                                               getEo(), part.name, value.getDomain(), value);
+                       } else {
+                               elm_object_translatable_part_text_set(
+                                               getEo(), part.name, value);
+                       }
+               } else {
+                       elm_object_part_text_translatable_set(getEo(),
+                                       part.name, EINA_FALSE);
+                       elm_object_part_text_set(getEo(), part.name, value);
+               }
+       }
+}
diff --git a/ucl/src/gui/ElmWidget.cpp b/ucl/src/gui/ElmWidget.cpp
new file mode 100644 (file)
index 0000000..68ee5af
--- /dev/null
@@ -0,0 +1,14 @@
+#include "ucl/gui/ElmWidget.h"
+
+namespace ucl {
+
+       void ElmWidget::setFocusedImpl(const bool value)
+       {
+               elm_object_focus_set(getEo(), toEina(value));
+       }
+
+       bool ElmWidget::isFocusedImpl() const
+       {
+               return elm_object_focus_get(getEo());
+       }
+}
diff --git a/ucl/src/gui/Layout.cpp b/ucl/src/gui/Layout.cpp
new file mode 100644 (file)
index 0000000..bd43c37
--- /dev/null
@@ -0,0 +1,35 @@
+#include "ucl/gui/Layout.h"
+
+#include "ucl/gui/stdTheme/layout.h"
+
+#include "../common.h"
+
+namespace ucl {
+
+       // Layout::Builder //
+
+       LayoutSRef Layout::Builder::build(Widget &parent) const
+       {
+               Evas_Object *const eo = elm_layout_add(parent);
+               if (!eo) {
+                       ELOG("elm_layout_add() failed!");
+                       return {};
+               }
+
+               auto result = makeShared<Layout>(eo, m_isOwner);
+
+               if (m_needBindToEo) {
+                       result->bindToEo();
+               }
+
+               if (isNotEmpty(m_edjeFilePath) && isValid(m_edjeGroup)) {
+                       result->setEdjeFile(m_edjeFilePath, m_edjeGroup);
+               } else {
+                       result->setTheme(isValid(m_theme) ? m_theme : LAYOUT_DEFAULT);
+               }
+
+               show(*result);
+
+               return result;
+       }
+}
diff --git a/ucl/src/gui/Naviframe.cpp b/ucl/src/gui/Naviframe.cpp
new file mode 100644 (file)
index 0000000..d7d2776
--- /dev/null
@@ -0,0 +1,31 @@
+#include "ucl/gui/Naviframe.h"
+
+#include "../common.h"
+
+namespace ucl {
+
+       // Naviframe::Builder //
+
+       NaviframeSRef Naviframe::Builder::build(Widget &parent) const
+       {
+               Evas_Object *const eo = elm_naviframe_add(parent);
+               if (!eo) {
+                       ELOG("elm_naviframe_add() failed!");
+                       return {};
+               }
+
+               auto result = makeShared<Naviframe>(eo, m_isOwner);
+
+               if (m_needBindToEo) {
+                       result->bindToEo();
+               }
+
+               if (isValid(m_style)) {
+                       result->setStyle(m_style);
+               }
+
+               show(*result);
+
+               return result;
+       }
+}
diff --git a/ucl/src/gui/Widget.cpp b/ucl/src/gui/Widget.cpp
new file mode 100644 (file)
index 0000000..d8f519f
--- /dev/null
@@ -0,0 +1,281 @@
+#include "ucl/gui/Widget.h"
+
+#include "../common.h"
+
+namespace ucl { namespace { namespace impl {
+
+       constexpr auto WIDGET_EVENT_SMART = EVAS_CALLBACK_LAST;
+}}}
+
+namespace ucl {
+
+       // Widget::EventProxy //
+
+       class Widget::EventProxy : public NonCopyable {
+       public:
+               EventProxy(Widget &widget, const WidgetEvent event,
+                               const WidgetEventHandler handler) :
+                       m_widget(widget),
+                       m_handler(handler),
+                       m_type(static_cast<Evas_Callback_Type>(event))
+               {
+                       evas_object_event_callback_add(m_widget.getEo(),
+                                       m_type, event_cb, this);
+               }
+
+               EventProxy(Widget &widget, const SmartEvent event,
+                               const WidgetEventHandler handler) :
+                       m_widget(widget),
+                       m_smartEvent(event),
+                       m_handler(handler),
+                       m_type(impl::WIDGET_EVENT_SMART)
+               {
+                       evas_object_smart_callback_add(m_widget.getEo(),
+                                       m_smartEvent.c_str(), smart_cb, this);
+               }
+
+               ~EventProxy()
+               {
+                       if (m_type == impl::WIDGET_EVENT_SMART) {
+                               evas_object_smart_callback_del_full(m_widget.getEo(),
+                                               m_smartEvent.c_str(), smart_cb, this);
+                       } else {
+                               evas_object_event_callback_del_full(m_widget.getEo(),
+                                               m_type, event_cb, this);
+                       }
+               }
+
+               void setSelfIt(const Widget::EventProxiesIt it)
+               {
+                       m_selfIt = it;
+               }
+
+               bool operator==(const std::pair<WidgetEvent, WidgetEventHandler> &rhs)
+               {
+                       return ((m_type == static_cast<Evas_Callback_Type>(rhs.first)) &&
+                                       (m_handler == rhs.second));
+               }
+
+               bool operator==(const std::pair<SmartEvent, WidgetEventHandler> &rhs)
+               {
+                       return ((m_type == impl::WIDGET_EVENT_SMART) &&
+                                       (m_handler == rhs.second) &&
+                                       (m_smartEvent.compare(rhs.first) == 0));
+               }
+
+       private:
+               static void event_cb(void *data, Evas *e,
+                               Evas_Object *obj, void *event_info)
+               {
+                       static_cast<EventProxy *>(data)->dispatchEvent(event_info);
+               }
+
+               static void smart_cb(void *data, Evas_Object *obj, void *event_info)
+               {
+                       static_cast<EventProxy *>(data)->dispatchEvent(event_info);
+               }
+
+               void dispatchEvent(void *const event_info)
+               {
+                       if (m_handler) {
+                               m_handler(m_widget, event_info);
+                       } else {
+                               m_widget.delEventProxy(m_selfIt);
+                       }
+               }
+
+       private:
+               Widget &m_widget;
+               const std::string m_smartEvent;
+               const WidgetEventHandler m_handler;
+               const Evas_Callback_Type m_type;
+               Widget::EventProxiesIt m_selfIt;
+       };
+
+       // Widget //
+
+       Widget::Widget(RefCountObjBase *const rc, Evas_Object *const eo,
+                       const bool isOwner) :
+               SharedObject(rc),
+               m_eo(eo),
+               m_isOwner(isOwner),
+               m_isBoundToEo(false),
+               m_isEoRefKept(false),
+               m_isSelfRefKept(false),
+               m_isSelfRefUnique(false)
+       {
+               UCL_ASSERT(m_eo, "m_eo is NULL!");
+
+               if (m_rc) {
+                       evas_object_event_callback_priority_add(m_eo, EVAS_CALLBACK_FREE,
+                                       EO_CALLBACK_PRIORITY_AFTER,
+                                       CALLBACK_A(Widget::onEoFree), this);
+               }
+
+               updateRefs();
+       }
+
+       Widget::~Widget()
+       {
+               m_eventProxies.clear();
+
+               if (m_isBoundToEo) {
+                       unbindFromEo();
+               }
+
+               if (m_rc) {
+                       evas_object_event_callback_del_full(m_eo, EVAS_CALLBACK_FREE,
+                                       CALLBACK_A(Widget::onEoFree), this);
+               }
+
+               if (m_isOwner) {
+                       evas_object_del(m_eo);
+               }
+
+               if (m_isEoRefKept) {
+                       evas_object_unref(m_eo);
+               }
+       }
+
+       void Widget::bindToEo()
+       {
+               if (!evas_object_data_get(m_eo, impl::WIDGET_DATA_NAME)) {
+                       evas_object_data_set(m_eo, impl::WIDGET_DATA_NAME, this);
+                       m_isBoundToEo = true;
+               } else {
+                       WLOG("Other Widget is already bound to this Eo!");
+               }
+       }
+
+       void Widget::unbindFromEo()
+       {
+               if (evas_object_data_get(m_eo, impl::WIDGET_DATA_NAME) == this) {
+                       evas_object_data_del(m_eo, impl::WIDGET_DATA_NAME);
+                       m_isBoundToEo = false;
+               } else {
+                       WLOG("Widget does not bound to its Eo!");
+               }
+       }
+
+       void Widget::updateRefs()
+       {
+               const auto rc = m_rc;
+
+               updateEoRef();
+
+               if (rc && !rc->isDisposed()) {
+                       updateSelfRef();
+               }
+       }
+
+       void Widget::updateEoRef()
+       {
+               if (needKeepEoRef()) {
+                       if (!m_isEoRefKept) {
+                               m_isEoRefKept = true;
+                               evas_object_ref(m_eo);
+                       }
+               } else if (m_isEoRefKept) {
+                       m_isEoRefKept = false;
+                       evas_object_unref(m_eo);
+               }
+       }
+
+       bool Widget::needKeepEoRef() const
+       {
+               return (!m_isSelfRefUnique || !needKeepSelfRef());
+       }
+
+       void Widget::updateSelfRef()
+       {
+               if (needKeepSelfRef()) {
+                       if (!m_isSelfRefKept) {
+                               m_isSelfRefKept = true;
+                               m_rc->ref();
+                       }
+               } else if (m_isSelfRefKept) {
+                       m_isSelfRefKept = false;
+                       m_rc->unref();
+               }
+       }
+
+       bool Widget::needKeepSelfRef() const
+       {
+               return (!m_isOwner && m_eo);
+       }
+
+       void Widget::setSelfRefUnique(const bool value)
+       {
+               if (value != m_isSelfRefUnique) {
+                       m_isSelfRefUnique = value;
+                       updateEoRef();
+               }
+       }
+
+       void Widget::onEoFree(Evas *e, Evas_Object *obj, void *event_info)
+       {
+               if (!m_isSelfRefKept) {
+                       FLOG("UNEXPECTED! m_isSelfRefKept: %d;", m_isSelfRefKept);
+                       m_eo = nullptr;
+                       return;
+               }
+               if (m_isOwner || m_isEoRefKept || !m_isSelfRefUnique) {
+                       ELOG("UNEXPECTED! m_isOwner: %d; m_isEoRefKept: %d; "
+                                       "m_isSelfRefUnique: %d;",
+                                       m_isOwner, m_isEoRefKept, m_isSelfRefUnique);
+                       m_eo = nullptr;
+               }
+               m_isSelfRefKept = false;
+               m_rc->unref();
+       }
+
+       void Widget::onUniqueChanged(bool isUnique)
+       {
+               setSelfRefUnique(isUnique);
+       }
+
+       void Widget::delEventProxy(const EventProxiesIt it)
+       {
+               if (it != m_eventProxies.end()) {
+                       m_eventProxies.erase(it);
+               }
+       }
+
+       void Widget::addEventHandler(const WidgetEvent event,
+                       const WidgetEventHandler handler)
+       {
+               m_eventProxies.emplace_front(*this, event, handler);
+               m_eventProxies.front().setSelfIt(m_eventProxies.begin());
+       }
+
+       void Widget::addEventHandler(const SmartEvent event,
+                       const WidgetEventHandler handler)
+       {
+               m_eventProxies.emplace_front(*this, event, handler);
+               m_eventProxies.front().setSelfIt(m_eventProxies.begin());
+       }
+
+       void Widget::delEventHandler(const WidgetEvent event,
+                       const WidgetEventHandler handler)
+       {
+               delEventProxy(std::find(m_eventProxies.begin(), m_eventProxies.end(),
+                               std::make_pair(event, handler)));
+       }
+
+       void Widget::delEventHandler(const SmartEvent event,
+                       const WidgetEventHandler handler)
+       {
+               delEventProxy(std::find(m_eventProxies.begin(), m_eventProxies.end(),
+                               std::make_pair(event, handler)));
+       }
+
+       void Widget::setFocusedImpl(const bool value)
+       {
+               evas_object_focus_set(getEo(), toEina(value));
+       }
+
+       bool Widget::isFocusedImpl() const
+       {
+               return evas_object_focus_get(getEo());
+       }
+}
diff --git a/ucl/src/gui/WidgetItem.cpp b/ucl/src/gui/WidgetItem.cpp
new file mode 100644 (file)
index 0000000..3bc242a
--- /dev/null
@@ -0,0 +1,37 @@
+#include "ucl/gui/WidgetItem.h"
+
+namespace ucl {
+
+       void WidgetItem::setText(const TString &value) const
+       {
+               if (value.isTranslatable()) {
+                       if (value.hasDomain()) {
+                               elm_object_item_domain_translatable_text_set(
+                                               getIt(), value.getDomain(), value);
+                       } else {
+                               elm_object_item_translatable_text_set(getIt(), value);
+                       }
+               } else {
+                       elm_object_item_text_translatable_set(getIt(), EINA_FALSE);
+                       elm_object_item_text_set(getIt(), value);
+               }
+       }
+
+       void WidgetItem::setPartText(
+                       const EdjePart part, const TString &value) const
+       {
+               if (value.isTranslatable()) {
+                       if (value.hasDomain()) {
+                               elm_object_item_domain_translatable_part_text_set(
+                                               getIt(), part.name, value.getDomain(), value);
+                       } else {
+                               elm_object_item_translatable_part_text_set(
+                                               getIt(), part.name, value);
+                       }
+               } else {
+                       elm_object_item_part_text_translatable_set(getIt(),
+                                       part.name, EINA_FALSE);
+                       elm_object_item_part_text_set(getIt(), part.name, value);
+               }
+       }
+}
diff --git a/ucl/src/gui/Window.cpp b/ucl/src/gui/Window.cpp
new file mode 100644 (file)
index 0000000..23a99d2
--- /dev/null
@@ -0,0 +1,62 @@
+#include "ucl/gui/Window.h"
+
+#include "../common.h"
+
+namespace ucl {
+
+       // Window::Builder //
+
+       WindowSRef Window::Builder::build() const
+       {
+               if (!m_winEo && isEmpty(m_name) && isEmpty(m_title)) {
+                       ELOG("Wrong built parameters!");
+                       return {};
+               }
+
+               Evas_Object *winEo = m_winEo;
+               bool isOwner = m_isOwner;
+
+               if (!winEo) {
+                       winEo = elm_win_add(nullptr,
+                                       (m_name.empty() ? m_title : m_name).c_str(),
+                                       static_cast<Elm_Win_Type>(m_type));
+                       if (!winEo) {
+                               ELOG("elm_win_add() failed!");
+                               return {};
+                       }
+                       if (!m_isOwnerWasSet) {
+                               isOwner = true;
+                       }
+               }
+
+               StyledWidget bg(elm_bg_add(winEo));
+               expand(bg);
+               show(bg);
+
+               StyledWidget conform(elm_conformant_add(winEo));
+               expand(conform);
+               show(conform);
+
+               elm_win_resize_object_add(winEo, bg);
+               elm_win_resize_object_add(winEo, conform);
+
+               elm_win_indicator_opacity_set(winEo, ELM_WIN_INDICATOR_OPAQUE);
+               elm_win_conformant_set(winEo, EINA_TRUE);
+
+               auto result = makeShared<Window>(winEo, isOwner, conform);
+
+               if (m_needBindToEo) {
+                       result->bindToEo();
+               }
+
+               result->setTitle(m_title.empty() ? m_name : m_title);
+
+               if (result->isRotationsSupported()) {
+                       result->setRotations(m_rotations);
+               }
+
+               result->setIndicatorVisible(m_isIndicatorVisible);
+
+               return result;
+       }
+}
diff --git a/ucl/src/misc/Variant.cpp b/ucl/src/misc/Variant.cpp
new file mode 100644 (file)
index 0000000..d6cebfa
--- /dev/null
@@ -0,0 +1,212 @@
+#include "ucl/misc/Variant.h"
+
+#include "../common.h"
+
+namespace ucl {
+
+       // Variant //
+
+       Variant::Variant(const char *const aString, const int length) :
+               m_type(aString ? TYPE_STRING : TYPE_NIL)
+       {
+               if (aString) {
+                       const int realLength = ((length < 0) ? strlen(aString) : length);
+                       const UInt size = (realLength + 1);
+                       if (size <= sizeof(m_aSmallStr.buffer)) {
+                               strncpy(m_aSmallStr.buffer, aString, size);
+                               m_type |= impl::FLAG_SMALL_STR;
+                       } else {
+                               m_aString.data = strndup(aString, realLength);
+                               m_aString.length = realLength;
+                       }
+               }
+       }
+
+       Variant::Variant(nullptr_t, const int arrayLength) :
+               m_type(static_cast<int>((arrayLength > 0) ? TYPE_ARRAY : TYPE_NIL))
+       {
+               if (arrayLength > 0) {
+                       m_anArray.data = new Variant[arrayLength];
+                       m_anArray.length = arrayLength;
+               }
+       }
+
+       Variant::Variant(const Variant *const anArray, const int length) :
+               Variant(nullptr, length)
+       {
+               if (length > 0) {
+                       std::copy(anArray, (anArray + length), m_anArray.data);
+               }
+       }
+
+       Variant::Variant(const Variant &v) :
+               m_type(v.m_type)
+       {
+               switch (m_type) {
+               case TYPE_NIL:
+                       break;
+               case TYPE_STRING:
+                       m_aString.data = strndup(v.m_aString.data, v.m_aString.length);
+                       m_aString.length = v.m_aString.length;
+                       break;
+               case TYPE_ARRAY:
+                       m_anArray.data = new Variant[v.m_anArray.length];
+                       std::copy(v.m_anArray.data, (v.m_anArray.data + v.m_anArray.length),
+                                       m_anArray.data);
+                       m_anArray.length = v.m_anArray.length;
+                       break;
+               default:
+                       m_raw = v.m_raw;
+                       break;
+               }
+       }
+
+       bool Variant::asBool() const noexcept
+       {
+               switch (m_type) {
+               case TYPE_BOOLEAN:
+                       return m_aBool.value;
+               case TYPE_INTEGER:
+                       return (m_anInt.value != 0);
+               case TYPE_FLOAT:
+                       return (m_aFloat.value != 0.0f);
+               case TYPE_DOUBLE:
+                       return (m_aDouble.value != 0.0);
+               case TYPE_STRING:
+               case impl::TYPE_SMALL_STR:
+                       {
+                               const auto str = getStr();
+                               return (strcasecmp(str, "true") == 0)
+                                       || (strcasecmp(str, "yes") == 0)
+                                       || (strcasecmp(str, "ok") == 0)
+                                       || (strcasecmp(str, "on") == 0)
+                                       || (strcasecmp(str, "1") == 0);
+                       }
+               case TYPE_ARRAY:
+                       return (m_anArray.length != 0);
+               }
+               return false;
+       }
+
+       int Variant::asInt() const noexcept
+       {
+               switch (m_type) {
+               case TYPE_BOOLEAN:
+                       return static_cast<int>(m_aBool.value);
+               case TYPE_INTEGER:
+                       return m_anInt.value;
+               case TYPE_FLOAT:
+                       return static_cast<int>(m_aFloat.value);
+               case TYPE_DOUBLE:
+                       return static_cast<int>(m_aDouble.value);
+               case TYPE_STRING:
+               case impl::TYPE_SMALL_STR:
+                       return std::atoi(getStr());
+               case TYPE_ARRAY:
+                       return m_anArray.length;
+               }
+               return 0;
+       }
+
+       float Variant::asFloat() const noexcept
+       {
+               switch (m_type) {
+               case TYPE_BOOLEAN:
+                       return static_cast<float>(m_aBool.value);
+               case TYPE_INTEGER:
+                       return static_cast<float>(m_anInt.value);
+               case TYPE_FLOAT:
+                       return m_aFloat.value;
+               case TYPE_DOUBLE:
+                       return static_cast<float>(m_aDouble.value);
+               case TYPE_STRING:
+               case impl::TYPE_SMALL_STR:
+                       return static_cast<float>(std::atof(getStr()));
+               case TYPE_ARRAY:
+                       return static_cast<float>(m_anArray.length);
+               }
+               return 0.0f;
+       }
+
+       double Variant::asDouble() const noexcept
+       {
+               switch (m_type) {
+               case TYPE_BOOLEAN:
+                       return static_cast<double>(m_aBool.value);
+               case TYPE_INTEGER:
+                       return static_cast<double>(m_anInt.value);
+               case TYPE_FLOAT:
+                       return static_cast<double>(m_aFloat.value);
+               case TYPE_DOUBLE:
+                       return m_aDouble.value;
+               case TYPE_STRING:
+               case impl::TYPE_SMALL_STR:
+                       return std::atof(getStr());
+               case TYPE_ARRAY:
+                       return static_cast<double>(m_anArray.length);
+               }
+               return 0.0;
+       }
+
+       Variant::CStr Variant::asString() const noexcept
+       {
+               char strBuff[impl::TMP_STR_BUFF_SIZE] = {};
+               switch (m_type) {
+               case TYPE_NIL:
+                       return {"", false};
+               case TYPE_BOOLEAN:
+                       return {(m_aBool.value ? "true" : "false"), false};
+               case TYPE_INTEGER:
+                       snprintf(strBuff, sizeof(strBuff), "%d", m_anInt.value);
+                       break;
+               case TYPE_FLOAT:
+                       snprintf(strBuff, sizeof(strBuff), "%f",
+                                       static_cast<double>(m_aFloat.value));
+                       break;
+               case TYPE_DOUBLE:
+                       snprintf(strBuff, sizeof(strBuff), "%f", m_aDouble.value);
+                       break;
+               case impl::TYPE_SMALL_STR:
+                       return m_aSmallStr.buffer;
+               case TYPE_STRING:
+                       return {m_aString.data, false};
+               case TYPE_ARRAY:
+                       snprintf(strBuff, sizeof(strBuff), "%d", m_anArray.length);
+                       break;
+               }
+               return strBuff;
+       }
+
+       // Non-member functions //
+
+       bool operator==(const Variant &lhs, const Variant &rhs) noexcept
+       {
+               if (lhs.m_type != rhs.m_type) {
+                       return false;
+               }
+               switch (lhs.m_type) {
+               case Variant::TYPE_BOOLEAN:
+                       return (lhs.m_aBool.value == rhs.m_aBool.value);
+               case Variant::TYPE_INTEGER:
+                       return (lhs.m_anInt.value == rhs.m_anInt.value);
+               case Variant::TYPE_FLOAT:
+                       return (lhs.m_aFloat.value == rhs.m_aFloat.value);
+               case Variant::TYPE_DOUBLE:
+                       return (lhs.m_aDouble.value == rhs.m_aDouble.value);
+               case Variant::TYPE_STRING:
+               case impl::TYPE_SMALL_STR:
+                       return (strcmp(lhs.getStr(), rhs.getStr()) == 0);
+               case Variant::TYPE_ARRAY:
+                       if (lhs.m_anArray.length != rhs.m_anArray.length) {
+                               return false;
+                       }
+                       for (int i = 0; i < lhs.m_anArray.length; ++i) {
+                               if (lhs.m_anArray.data[i] != rhs.m_anArray.data[i]) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               }
+               return true;
+       }
+}
diff --git a/ucl/src/util/logging.cpp b/ucl/src/util/logging.cpp
new file mode 100644 (file)
index 0000000..cd341a5
--- /dev/null
@@ -0,0 +1,10 @@
+#include "ucl/util/logging.h"
+
+#if (UCL_DEFINE_GET_UCL_RESULT_DATA)
+#include "ucl/util/types/Result.h"
+
+ucl::ResultData getUCLResultData(const ucl::Result result)
+{
+       return ucl::getResultData(result);
+}
+#endif
diff --git a/ucl/src/util/types/Result.cpp b/ucl/src/util/types/Result.cpp
new file mode 100644 (file)
index 0000000..dee8d6c
--- /dev/null
@@ -0,0 +1,29 @@
+#include "ucl/util/types/Result.h"
+
+#include "ucl/util/logging.h"
+
+namespace ucl { namespace { namespace impl {
+
+       constexpr ResultData RESUT_DATA[] = {
+               {"RES_INVALID_DATA",      DLOG_ERROR},
+               {"RES_NOT_SUPPORTED",     DLOG_ERROR},
+               {"RES_IO_ERROR",          DLOG_ERROR},
+               {"RES_OUT_OF_MEMORY",     DLOG_ERROR},
+               {"RES_ILLEGAL_STATE",     DLOG_ERROR},
+               {"RES_INVALID_ARGUMENTS", DLOG_ERROR},
+               {"RES_FAIL",              DLOG_ERROR},
+               {"RES_OK",                DLOG_INFO},
+               {"RES_FALSE",             DLOG_INFO},
+               {"Unknown result value",  DLOG_ERROR},
+       };
+}}}
+
+namespace ucl {
+
+       const ResultData &getResultData(const Result result)
+       {
+               return impl::RESUT_DATA[
+                       ((result.value < _RES_BEGIN) || (result.value >= _RES_END)) ?
+                               _RES_END : (result.value - _RES_BEGIN)];
+       }
+}