├── .gitattributes ├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── Win32.sln ├── build.gradle ├── gradle.properties ├── include ├── core.h ├── data.h ├── io.h ├── native.h ├── test.h └── ui.h ├── samples ├── components │ ├── build.gradle │ ├── components.vcxproj │ ├── components.vcxproj.filters │ └── src │ │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-v21 │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── main.cpp ├── drawing │ ├── build.gradle │ ├── drawing.vcxproj │ ├── drawing.vcxproj.filters │ └── src │ │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-v21 │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── main.cpp ├── helloworld │ ├── build.gradle │ ├── helloworld.vcxproj │ ├── helloworld.vcxproj.filters │ └── src │ │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-v21 │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── main.cpp ├── layout │ ├── build.gradle │ ├── layout.vcxproj │ ├── layout.vcxproj.filters │ └── src │ │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-v21 │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── main.cpp ├── notepad │ ├── build.gradle │ ├── notepad.vcxproj │ ├── notepad.vcxproj.filters │ └── src │ │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-v21 │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ │ └── main.cpp └── webview │ ├── build.gradle │ ├── src │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ └── ic_launcher.png │ │ │ ├── values-v21 │ │ │ └── styles.xml │ │ │ └── values │ │ │ └── styles.xml │ └── main.cpp │ ├── webview.vcxproj │ └── webview.vcxproj.filters ├── settings.gradle ├── src ├── core │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ ├── atomic.cpp │ │ ├── datetime.cpp │ │ ├── mutex.cpp │ │ ├── semaphore.cpp │ │ ├── system.cpp │ │ └── thread.cpp │ ├── build.gradle │ ├── common │ │ ├── array.cpp │ │ ├── asciicodec.cpp │ │ ├── clock.cpp │ │ ├── conditionvariable.cpp │ │ ├── convert.cpp │ │ ├── hash.cpp │ │ ├── latin1codec.cpp │ │ ├── math.cpp │ │ ├── memory.cpp │ │ ├── singleton.cpp │ │ ├── spinlock.cpp │ │ ├── string.cpp │ │ ├── stringcodec.cpp │ │ ├── threadpool.cpp │ │ ├── utf8codec.cpp │ │ └── variant.cpp │ ├── core.vcxproj │ ├── core.vcxproj.filters │ ├── include │ │ ├── array.h │ │ ├── asciicodec.h │ │ ├── atomic.h │ │ ├── clock.h │ │ ├── collection.h │ │ ├── conditionvariable.h │ │ ├── convert.h │ │ ├── datetime.h │ │ ├── exception.h │ │ ├── flags.h │ │ ├── function.h │ │ ├── hash.h │ │ ├── ilockable.h │ │ ├── iterator.h │ │ ├── latin1codec.h │ │ ├── linkedlist.h │ │ ├── list.h │ │ ├── lockscope.h │ │ ├── map.h │ │ ├── math.h │ │ ├── memory.h │ │ ├── mutex.h │ │ ├── platform.h │ │ ├── queue.h │ │ ├── semaphore.h │ │ ├── set.h │ │ ├── shared.h │ │ ├── signal.h │ │ ├── singleton.h │ │ ├── spinlock.h │ │ ├── stack.h │ │ ├── string.h │ │ ├── stringcodec.h │ │ ├── system.h │ │ ├── task.h │ │ ├── thread.h │ │ ├── threadpool.h │ │ ├── types.h │ │ ├── utf8codec.h │ │ └── variant.h │ └── win32 │ │ ├── atomic.cpp │ │ ├── datetime.cpp │ │ ├── mutex.cpp │ │ ├── semaphore.cpp │ │ ├── system.cpp │ │ └── thread.cpp ├── data │ ├── android │ │ ├── AndroidManifest.xml │ │ └── CMakeLists.txt │ ├── build.gradle │ ├── data.vcxproj │ ├── data.vcxproj.filters │ └── dummy.cpp ├── io │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ └── file.cpp │ ├── build.gradle │ ├── common │ │ ├── memorystream.cpp │ │ ├── networkaddress.cpp │ │ ├── socket.cpp │ │ ├── tcpsocket.cpp │ │ └── udpsocket.cpp │ ├── include │ │ ├── file.h │ │ ├── istream.h │ │ ├── memorystream.h │ │ ├── networkaddress.h │ │ ├── socket.h │ │ ├── tcpsocket.h │ │ └── udpsocket.h │ ├── io.vcxproj │ ├── io.vcxproj.filters │ └── win32 │ │ └── file.cpp └── ui │ ├── android │ ├── AndroidManifest.xml │ ├── CMakeLists.txt │ ├── alerts.cpp │ ├── androidapp.cpp │ ├── app.cpp │ ├── bitmap.cpp │ ├── brush.cpp │ ├── canvas.cpp │ ├── componentadapter.cpp │ ├── componentadapterproperties.h │ ├── componentevent.h │ ├── eventqueue.cpp │ ├── font.cpp │ ├── java │ │ └── libnative │ │ │ └── ui │ │ │ ├── Button.java │ │ │ ├── Checkbox.java │ │ │ ├── INativeComponent.java │ │ │ ├── InputComponent.java │ │ │ ├── MainActivity.java │ │ │ ├── NativeRunnable.java │ │ │ ├── NumberPicker.java │ │ │ ├── ProgressBar.java │ │ │ ├── RadioButton.java │ │ │ ├── ScrollView.java │ │ │ ├── TextArea.java │ │ │ ├── TextComponent.java │ │ │ ├── ViewExtensions.java │ │ │ ├── WebView.java │ │ │ └── Window.java │ ├── lineargradientbrush.cpp │ ├── menuadapter.cpp │ ├── pen.cpp │ └── webview.cpp │ ├── build.gradle │ ├── common │ ├── action.cpp │ ├── button.cpp │ ├── checkbox.cpp │ ├── color.cpp │ ├── component.cpp │ ├── groupbox.cpp │ ├── inputcomponent.cpp │ ├── label.cpp │ ├── layoutcomponent.cpp │ ├── linearlayout.cpp │ ├── menu.cpp │ ├── numberpicker.cpp │ ├── point.cpp │ ├── progressbar.cpp │ ├── radiobutton.cpp │ ├── rectangle.cpp │ ├── scrollview.cpp │ ├── size.cpp │ ├── textarea.cpp │ ├── textcomponent.cpp │ └── window.cpp │ ├── include │ ├── action.h │ ├── alerts.h │ ├── app.h │ ├── bitmap.h │ ├── brush.h │ ├── button.h │ ├── canvas.h │ ├── checkbox.h │ ├── color.h │ ├── component.h │ ├── componentadapter.h │ ├── eventqueue.h │ ├── font.h │ ├── groupbox.h │ ├── icomponentadapter.h │ ├── imenuadapter.h │ ├── inputcomponent.h │ ├── inputevent.h │ ├── label.h │ ├── layoutcomponent.h │ ├── lineargradientbrush.h │ ├── linearlayout.h │ ├── menu.h │ ├── menuadapter.h │ ├── numberpicker.h │ ├── pen.h │ ├── point.h │ ├── progressbar.h │ ├── radiobutton.h │ ├── rectangle.h │ ├── scrollview.h │ ├── size.h │ ├── textarea.h │ ├── textcomponent.h │ ├── webview.h │ └── window.h │ ├── ui.vcxproj │ ├── ui.vcxproj.filters │ └── win32 │ ├── alerts.cpp │ ├── app.cpp │ ├── bitmap.cpp │ ├── brush.cpp │ ├── canvas.cpp │ ├── componentadapter.cpp │ ├── componentadapterproperties.h │ ├── componentevent.h │ ├── eventqueue.cpp │ ├── font.cpp │ ├── lineargradientbrush.cpp │ ├── menuadapter.cpp │ ├── pen.cpp │ └── webview.cpp └── tests ├── test ├── build.gradle ├── include │ ├── log.h │ ├── testregistry.h │ └── unittest.h ├── src │ ├── android │ │ ├── AndroidManifest.xml │ │ ├── CMakeLists.txt │ │ ├── java │ │ │ └── libnative │ │ │ │ └── test │ │ │ │ └── TestActivity.java │ │ └── log.cpp │ ├── common │ │ ├── testregistry.cpp │ │ └── unittest.cpp │ └── win32 │ │ └── log.cpp ├── test.vcxproj └── test.vcxproj.filters └── unittests ├── build.gradle ├── src ├── android │ ├── AndroidManifest.xml │ ├── CMakeLists.txt │ └── res │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ └── mipmap-xxhdpi │ │ └── ic_launcher.png ├── core │ ├── array.cpp │ ├── asciicodec.cpp │ ├── atomic.cpp │ ├── conditionvariable.cpp │ ├── convert.cpp │ ├── datetime.cpp │ ├── function.cpp │ ├── hash.cpp │ ├── linkedlist.cpp │ ├── list.cpp │ ├── map.cpp │ ├── math.cpp │ ├── queue.cpp │ ├── semaphore.cpp │ ├── set.cpp │ ├── stack.cpp │ ├── string.cpp │ ├── task.cpp │ ├── thread.cpp │ ├── threadpool.cpp │ ├── types.cpp │ ├── utf8codec.cpp │ └── variant.cpp ├── io │ └── memorystream.cpp ├── main.cpp └── ui │ ├── color.cpp │ ├── component.cpp │ ├── layoutcomponent.cpp │ ├── mockcomponentadapter.h │ ├── point.cpp │ ├── rectangle.cpp │ ├── size.cpp │ └── window.cpp ├── unittests.vcxproj └── unittests.vcxproj.filters /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/jnipp"] 2 | path = lib/jnipp 3 | url = https://github.com/mitchdowd/jnipp 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mitch 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | dependencies { 7 | classpath 'com.android.tools.build:gradle:3.2.1' 8 | 9 | // NOTE: Do not place your application dependencies here; they belong 10 | // in the individual module build.gradle files 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /include/core.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_CORE_H_ 2 | #define _NATIVE_CORE_H_ 1 3 | 4 | #include "../src/core/include/array.h" 5 | #include "../src/core/include/asciicodec.h" 6 | #include "../src/core/include/atomic.h" 7 | #include "../src/core/include/clock.h" 8 | #include "../src/core/include/collection.h" 9 | #include "../src/core/include/conditionvariable.h" 10 | #include "../src/core/include/convert.h" 11 | #include "../src/core/include/datetime.h" 12 | #include "../src/core/include/exception.h" 13 | #include "../src/core/include/flags.h" 14 | #include "../src/core/include/function.h" 15 | #include "../src/core/include/hash.h" 16 | #include "../src/core/include/ilockable.h" 17 | #include "../src/core/include/iterator.h" 18 | #include "../src/core/include/latin1codec.h" 19 | #include "../src/core/include/linkedlist.h" 20 | #include "../src/core/include/list.h" 21 | #include "../src/core/include/lockscope.h" 22 | #include "../src/core/include/map.h" 23 | #include "../src/core/include/math.h" 24 | #include "../src/core/include/memory.h" 25 | #include "../src/core/include/mutex.h" 26 | #include "../src/core/include/platform.h" 27 | #include "../src/core/include/queue.h" 28 | #include "../src/core/include/semaphore.h" 29 | #include "../src/core/include/set.h" 30 | #include "../src/core/include/shared.h" 31 | #include "../src/core/include/signal.h" 32 | #include "../src/core/include/singleton.h" 33 | #include "../src/core/include/spinlock.h" 34 | #include "../src/core/include/stack.h" 35 | #include "../src/core/include/string.h" 36 | #include "../src/core/include/stringcodec.h" 37 | #include "../src/core/include/system.h" 38 | #include "../src/core/include/task.h" 39 | #include "../src/core/include/thread.h" 40 | #include "../src/core/include/threadpool.h" 41 | #include "../src/core/include/types.h" 42 | #include "../src/core/include/utf8codec.h" 43 | #include "../src/core/include/variant.h" 44 | 45 | #endif // _NATIVE_CORE_H_ 46 | 47 | -------------------------------------------------------------------------------- /include/data.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_DATA_H_ 2 | #define _NATIVE_DATA_H_ 1 3 | 4 | 5 | 6 | #endif // _NATIVE_DATA_H_ 7 | 8 | -------------------------------------------------------------------------------- /include/io.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_IO_H_ 2 | #define _NATIVE_IO_H_ 1 3 | 4 | #include "../src/io/include/file.h" 5 | #include "../src/io/include/istream.h" 6 | #include "../src/io/include/memorystream.h" 7 | #include "../src/io/include/networkaddress.h" 8 | #include "../src/io/include/socket.h" 9 | #include "../src/io/include/tcpsocket.h" 10 | #include "../src/io/include/udpsocket.h" 11 | 12 | #endif // _NATIVE_IO_H_ 13 | 14 | -------------------------------------------------------------------------------- /include/native.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_NATIVE_H_ 2 | #define _NATIVE_NATIVE_H_ 1 3 | 4 | #include "core.h" 5 | #include "data.h" 6 | #include "io.h" 7 | #include "ui.h" 8 | 9 | #endif // _NATIVE_NATIVE_H_ 10 | 11 | -------------------------------------------------------------------------------- /include/test.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_TEST_TEST_H_ 2 | #define _NATIVE_TEST_TEST_H_ 1 3 | 4 | #include "../tests/test/include/log.h" 5 | #include "../tests/test/include/testregistry.h" 6 | #include "../tests/test/include/unittest.h" 7 | 8 | #endif // _NATIVE_TEST_TEST_H_ 9 | 10 | -------------------------------------------------------------------------------- /include/ui.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_H_ 2 | #define _NATIVE_UI_H_ 1 3 | 4 | #include "../src/ui/include/action.h" 5 | #include "../src/ui/include/alerts.h" 6 | #include "../src/ui/include/app.h" 7 | #include "../src/ui/include/brush.h" 8 | #include "../src/ui/include/button.h" 9 | #include "../src/ui/include/canvas.h" 10 | #include "../src/ui/include/checkbox.h" 11 | #include "../src/ui/include/color.h" 12 | #include "../src/ui/include/component.h" 13 | #include "../src/ui/include/componentadapter.h" 14 | #include "../src/ui/include/eventqueue.h" 15 | #include "../src/ui/include/font.h" 16 | #include "../src/ui/include/groupbox.h" 17 | #include "../src/ui/include/icomponentadapter.h" 18 | #include "../src/ui/include/inputcomponent.h" 19 | #include "../src/ui/include/inputevent.h" 20 | #include "../src/ui/include/label.h" 21 | #include "../src/ui/include/layoutcomponent.h" 22 | #include "../src/ui/include/lineargradientbrush.h" 23 | #include "../src/ui/include/linearlayout.h" 24 | #include "../src/ui/include/menu.h" 25 | #include "../src/ui/include/numberpicker.h" 26 | #include "../src/ui/include/pen.h" 27 | #include "../src/ui/include/point.h" 28 | #include "../src/ui/include/progressbar.h" 29 | #include "../src/ui/include/radiobutton.h" 30 | #include "../src/ui/include/rectangle.h" 31 | #include "../src/ui/include/scrollview.h" 32 | #include "../src/ui/include/size.h" 33 | #include "../src/ui/include/textarea.h" 34 | #include "../src/ui/include/textcomponent.h" 35 | #include "../src/ui/include/webview.h" 36 | #include "../src/ui/include/window.h" 37 | 38 | #endif // _NATIVE_UI_H_ 39 | 40 | -------------------------------------------------------------------------------- /samples/components/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | applicationId = 'libnative.samples.components' 9 | minSdkVersion 15 10 | targetSdkVersion 26 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled = false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt') 17 | } 18 | } 19 | 20 | sourceSets { 21 | main { 22 | java.srcDir 'src/android' 23 | jni.srcDir 'src' 24 | manifest.srcFile 'src/android/AndroidManifest.xml' 25 | res.srcDir 'src/android/res' 26 | } 27 | } 28 | 29 | externalNativeBuild { 30 | cmake { 31 | path 'src/android/CMakeLists.txt' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation project(':ui') 38 | } 39 | -------------------------------------------------------------------------------- /samples/components/components.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/components/src/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/components/src/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 9 | 10 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 11 | 12 | ADD_LIBRARY(ui STATIC IMPORTED) 13 | ADD_LIBRARY(core STATIC IMPORTED) 14 | ADD_LIBRARY(jnipp STATIC IMPORTED) 15 | ADD_LIBRARY(components SHARED ${sources}) 16 | 17 | SET_TARGET_PROPERTIES(ui PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libui.so") 18 | SET_TARGET_PROPERTIES(core PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libcore.so") 19 | SET_TARGET_PROPERTIES(jnipp PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libjnipp.so") 20 | 21 | TARGET_LINK_LIBRARIES(components ui core jnipp) 22 | -------------------------------------------------------------------------------- /samples/components/src/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/components/src/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/components/src/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/components/src/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/components/src/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/components/src/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/components/src/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/components/src/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/components/src/android/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/components/src/android/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/components/src/android/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /samples/components/src/android/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples/drawing/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | applicationId = 'libnative.samples.drawing' 9 | minSdkVersion 15 10 | targetSdkVersion 26 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled = false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt') 17 | } 18 | } 19 | 20 | sourceSets { 21 | main { 22 | java.srcDir 'src/android' 23 | jni.srcDir 'src' 24 | manifest.srcFile 'src/android/AndroidManifest.xml' 25 | res.srcDir 'src/android/res' 26 | } 27 | } 28 | 29 | externalNativeBuild { 30 | cmake { 31 | path 'src/android/CMakeLists.txt' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation project(':ui') 38 | } 39 | -------------------------------------------------------------------------------- /samples/drawing/drawing.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/drawing/src/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/drawing/src/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 9 | 10 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 11 | 12 | ADD_LIBRARY(ui STATIC IMPORTED) 13 | ADD_LIBRARY(core STATIC IMPORTED) 14 | ADD_LIBRARY(jnipp STATIC IMPORTED) 15 | ADD_LIBRARY(drawing SHARED ${sources}) 16 | 17 | SET_TARGET_PROPERTIES(ui PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libui.so") 18 | SET_TARGET_PROPERTIES(core PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libcore.so") 19 | SET_TARGET_PROPERTIES(jnipp PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libjnipp.so") 20 | 21 | TARGET_LINK_LIBRARIES(drawing ui core jnipp) 22 | -------------------------------------------------------------------------------- /samples/drawing/src/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/drawing/src/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/drawing/src/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/drawing/src/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/drawing/src/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/drawing/src/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/drawing/src/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/drawing/src/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/drawing/src/android/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/drawing/src/android/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/drawing/src/android/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /samples/drawing/src/android/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples/helloworld/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | applicationId = 'libnative.samples.helloworld' 9 | minSdkVersion 15 10 | targetSdkVersion 26 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled = false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt') 17 | } 18 | } 19 | 20 | sourceSets { 21 | main { 22 | java.srcDir 'src/android' 23 | jni.srcDir 'src' 24 | manifest.srcFile 'src/android/AndroidManifest.xml' 25 | res.srcDir 'src/android/res' 26 | } 27 | } 28 | 29 | externalNativeBuild { 30 | cmake { 31 | path 'src/android/CMakeLists.txt' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation project(':ui') 38 | } 39 | -------------------------------------------------------------------------------- /samples/helloworld/helloworld.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/helloworld/src/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/helloworld/src/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 9 | 10 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 11 | 12 | ADD_LIBRARY(ui STATIC IMPORTED) 13 | ADD_LIBRARY(core STATIC IMPORTED) 14 | ADD_LIBRARY(jnipp STATIC IMPORTED) 15 | ADD_LIBRARY(helloworld SHARED ${sources}) 16 | 17 | SET_TARGET_PROPERTIES(ui PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libui.so") 18 | SET_TARGET_PROPERTIES(core PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libcore.so") 19 | SET_TARGET_PROPERTIES(jnipp PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libjnipp.so") 20 | 21 | TARGET_LINK_LIBRARIES(helloworld ui core jnipp) 22 | -------------------------------------------------------------------------------- /samples/helloworld/src/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/helloworld/src/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/helloworld/src/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/helloworld/src/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/helloworld/src/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/helloworld/src/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/helloworld/src/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/helloworld/src/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/helloworld/src/android/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/helloworld/src/android/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/helloworld/src/android/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /samples/helloworld/src/android/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples/helloworld/src/main.cpp: -------------------------------------------------------------------------------- 1 | // Framework Dependencies 2 | #include 3 | 4 | // Namespace Usage 5 | using namespace native; 6 | using namespace native::ui; 7 | 8 | class HelloWorldApp : public App 9 | { 10 | public: 11 | HelloWorldApp() 12 | { 13 | // Set up the main window. 14 | setTitle("Hello World Sample"); 15 | setSize(300, 300); 16 | 17 | // Set up the hello button. 18 | _helloBtn.setText("Say Hello"); 19 | _helloBtn.setAlignment(Align::Center); 20 | _helloBtn.clicked.connect([]() { 21 | Alerts::messageBox("Hello World", "Alert"); 22 | }); 23 | 24 | addChild(_helloBtn); 25 | } 26 | 27 | private: 28 | Button _helloBtn; 29 | }; 30 | 31 | // Entry Point 32 | NATIVE_UI_APP(HelloWorldApp) 33 | -------------------------------------------------------------------------------- /samples/layout/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | applicationId = 'libnative.samples.layout' 9 | minSdkVersion 15 10 | targetSdkVersion 26 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled = false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt') 17 | } 18 | } 19 | 20 | sourceSets { 21 | main { 22 | java.srcDir 'src/android' 23 | jni.srcDir 'src' 24 | manifest.srcFile 'src/android/AndroidManifest.xml' 25 | res.srcDir 'src/android/res' 26 | } 27 | } 28 | 29 | externalNativeBuild { 30 | cmake { 31 | path 'src/android/CMakeLists.txt' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation project(':ui') 38 | } 39 | -------------------------------------------------------------------------------- /samples/layout/layout.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/layout/src/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/layout/src/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 9 | 10 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 11 | 12 | ADD_LIBRARY(ui STATIC IMPORTED) 13 | ADD_LIBRARY(core STATIC IMPORTED) 14 | ADD_LIBRARY(jnipp STATIC IMPORTED) 15 | ADD_LIBRARY(layout SHARED ${sources}) 16 | 17 | SET_TARGET_PROPERTIES(ui PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libui.so") 18 | SET_TARGET_PROPERTIES(core PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libcore.so") 19 | SET_TARGET_PROPERTIES(jnipp PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libjnipp.so") 20 | 21 | TARGET_LINK_LIBRARIES(layout ui core jnipp) 22 | -------------------------------------------------------------------------------- /samples/layout/src/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/layout/src/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/layout/src/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/layout/src/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/layout/src/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/layout/src/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/layout/src/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/layout/src/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/layout/src/android/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/layout/src/android/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/layout/src/android/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /samples/layout/src/android/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples/layout/src/main.cpp: -------------------------------------------------------------------------------- 1 | // Framework Dependencies 2 | #include 3 | 4 | // Namespace Usage 5 | using namespace native; 6 | using namespace native::ui; 7 | 8 | class Marker : public Component 9 | { 10 | public: 11 | Marker() 12 | { 13 | setBorder(Color(0x99, 0, 0, 0)); 14 | setMargin(1); 15 | } 16 | 17 | virtual Size getPreferredSize() const override 18 | { 19 | return { 80, 30 }; 20 | } 21 | }; 22 | 23 | class LayoutApp : public App 24 | { 25 | public: 26 | LayoutApp() 27 | { 28 | // Set up the main window. 29 | setTitle("Layout Sample"); 30 | 31 | addChild(_vertical); 32 | 33 | _vertical.addChild(_top); 34 | _vertical.addChild(_bottom); 35 | 36 | _top.addChild(_child1); 37 | _top.addChild(_child2); 38 | _top.addChild(_child3); 39 | 40 | _bottom.addChild(_child4); 41 | 42 | _child1.setAlignment(Align::HFill | Align::Top); 43 | _child2.setAlignment(Align::HFill | Align::VCenter); 44 | _child3.setAlignment(Align::HFill | Align::Bottom); 45 | _child4.setAlignment(Align::Center); 46 | 47 | _vertical.setOrientation(Vertical); 48 | } 49 | 50 | private: 51 | LinearLayout _vertical, _top, _bottom; 52 | Marker _child1, _child2, _child3, _child4; 53 | }; 54 | 55 | // Entry Point 56 | NATIVE_UI_APP(LayoutApp) 57 | -------------------------------------------------------------------------------- /samples/notepad/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | applicationId = 'libnative.samples.notepad' 9 | minSdkVersion 15 10 | targetSdkVersion 26 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled = false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt') 17 | } 18 | } 19 | 20 | sourceSets { 21 | main { 22 | java.srcDir 'src/android' 23 | jni.srcDir 'src' 24 | manifest.srcFile 'src/android/AndroidManifest.xml' 25 | res.srcDir 'src/android/res' 26 | } 27 | } 28 | 29 | externalNativeBuild { 30 | cmake { 31 | path 'src/android/CMakeLists.txt' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation project(':ui') 38 | } 39 | -------------------------------------------------------------------------------- /samples/notepad/notepad.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/notepad/src/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/notepad/src/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 9 | 10 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 11 | 12 | ADD_LIBRARY(ui STATIC IMPORTED) 13 | ADD_LIBRARY(core STATIC IMPORTED) 14 | ADD_LIBRARY(jnipp STATIC IMPORTED) 15 | ADD_LIBRARY(notepad SHARED ${sources}) 16 | 17 | SET_TARGET_PROPERTIES(ui PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libui.so") 18 | SET_TARGET_PROPERTIES(core PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libcore.so") 19 | SET_TARGET_PROPERTIES(jnipp PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libjnipp.so") 20 | 21 | TARGET_LINK_LIBRARIES(notepad ui core jnipp) 22 | -------------------------------------------------------------------------------- /samples/notepad/src/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/notepad/src/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/notepad/src/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/notepad/src/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/notepad/src/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/notepad/src/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/notepad/src/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/notepad/src/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/notepad/src/android/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/notepad/src/android/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/notepad/src/android/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /samples/notepad/src/android/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples/webview/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | applicationId = 'libnative.samples.webview' 9 | minSdkVersion 15 10 | targetSdkVersion 26 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled = false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt') 17 | } 18 | } 19 | 20 | sourceSets { 21 | main { 22 | java.srcDir 'src/android' 23 | jni.srcDir 'src' 24 | manifest.srcFile 'src/android/AndroidManifest.xml' 25 | res.srcDir 'src/android/res' 26 | } 27 | } 28 | 29 | externalNativeBuild { 30 | cmake { 31 | path 'src/android/CMakeLists.txt' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation project(':ui') 38 | } 39 | -------------------------------------------------------------------------------- /samples/webview/src/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /samples/webview/src/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 9 | 10 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 11 | 12 | ADD_LIBRARY(ui STATIC IMPORTED) 13 | ADD_LIBRARY(core STATIC IMPORTED) 14 | ADD_LIBRARY(jnipp STATIC IMPORTED) 15 | 16 | ADD_LIBRARY(webview SHARED ${sources}) 17 | 18 | SET_TARGET_PROPERTIES(ui PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libui.so") 19 | SET_TARGET_PROPERTIES(core PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libcore.so") 20 | SET_TARGET_PROPERTIES(jnipp PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libjnipp.so") 21 | 22 | TARGET_LINK_LIBRARIES(webview ui core jnipp) 23 | -------------------------------------------------------------------------------- /samples/webview/src/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/webview/src/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/webview/src/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/webview/src/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/webview/src/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/webview/src/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/webview/src/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/webview/src/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/webview/src/android/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/samples/webview/src/android/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/webview/src/android/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | -------------------------------------------------------------------------------- /samples/webview/src/android/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /samples/webview/src/main.cpp: -------------------------------------------------------------------------------- 1 | // Framework Dependencies 2 | #include 3 | 4 | // Namespace Usage 5 | using namespace native; 6 | using namespace native::ui; 7 | 8 | class WebViewApp : public App 9 | { 10 | public: 11 | WebViewApp() 12 | { 13 | setTitle("WebView Sample"); 14 | 15 | _webView.navigate("http://github.com"); 16 | 17 | addChild(_webView); 18 | } 19 | 20 | private: 21 | WebView _webView; 22 | }; 23 | 24 | // Entry Point 25 | NATIVE_UI_APP(WebViewApp) 26 | -------------------------------------------------------------------------------- /samples/webview/webview.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':core' 2 | include ':data' 3 | include ':io' 4 | include ':jnipp' 5 | include ':ui' 6 | include ':testing' 7 | include ':unittests' 8 | 9 | include ':components' 10 | include ':drawing' 11 | include ':helloworld' 12 | include ':layout' 13 | include ':notepad' 14 | include ':webview' 15 | 16 | project(':core').projectDir = new File('src', 'core') 17 | project(':data').projectDir = new File('src', 'data') 18 | project(':io').projectDir = new File('src', 'io') 19 | project(':jnipp').projectDir = new File('lib', 'jnipp') 20 | project(':ui').projectDir = new File('src', 'ui') 21 | 22 | project(':testing').projectDir = new File('tests', 'test') 23 | project(':unittests').projectDir = new File('tests', 'unittests') 24 | 25 | project(':components').projectDir = new File('samples', 'components') 26 | project(':drawing').projectDir = new File('samples', 'drawing') 27 | project(':helloworld').projectDir = new File('samples', 'helloworld') 28 | project(':layout').projectDir = new File('samples', 'layout') 29 | project(':notepad').projectDir = new File('samples', 'notepad') 30 | project(':webview').projectDir = new File('samples', 'webview') 31 | -------------------------------------------------------------------------------- /src/core/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/core/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${root_dir}/lib/${ANDROID_ABI}") 9 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 10 | 11 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 12 | 13 | ADD_LIBRARY(core SHARED ${sources}) 14 | -------------------------------------------------------------------------------- /src/core/android/mutex.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | #include 4 | 5 | // Local Dependencies 6 | #include "../include/exception.h" 7 | #include "../include/mutex.h" 8 | 9 | namespace native 10 | { 11 | Mutex::Mutex() 12 | { 13 | if (::pthread_mutex_init((pthread_mutex_t*) &_handle, nullptr) != 0) 14 | throw Exception("Mutex::Mutex"); 15 | } 16 | 17 | Mutex::~Mutex() 18 | { 19 | if (_handle) 20 | ::pthread_mutex_destroy((pthread_mutex_t*) &_handle); 21 | } 22 | 23 | void Mutex::lock() 24 | { 25 | switch (::pthread_mutex_lock((pthread_mutex_t*) &_handle)) 26 | { 27 | case 0: 28 | return; // All is well. 29 | 30 | case EDEADLK: 31 | throw InvalidStateException("Mutex already owned"); 32 | 33 | default: 34 | throw Exception("Mutex::lock"); 35 | } 36 | } 37 | 38 | bool Mutex::tryLock() 39 | { 40 | switch (::pthread_mutex_trylock((pthread_mutex_t*) &_handle)) 41 | { 42 | case 0: 43 | return true; // All is well. 44 | 45 | case EBUSY: 46 | return false; 47 | 48 | case EDEADLK: 49 | throw InvalidStateException("Mutex already owned"); 50 | 51 | default: 52 | throw Exception("Mutex::tryLock"); 53 | } 54 | } 55 | 56 | void Mutex::release() 57 | { 58 | switch (::pthread_mutex_unlock((pthread_mutex_t*) &_handle)) 59 | { 60 | case 0: 61 | return; // All is well. 62 | 63 | case EPERM: 64 | throw InvalidStateException("Mutex not owned"); 65 | 66 | default: 67 | throw Exception("Mutex::release"); 68 | } 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /src/core/android/semaphore.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | #include 4 | #include 5 | 6 | // Module Dependencies 7 | #include "../include/semaphore.h" 8 | 9 | namespace native 10 | { 11 | Semaphore::Semaphore(uint32_t initialValue) : _handle(new sem_t()) 12 | { 13 | if (::sem_init((sem_t*) _handle, 0, initialValue) != 0) 14 | throw Exception("Semaphore::Semaphore"); 15 | } 16 | 17 | Semaphore::Semaphore(Semaphore&& other) noexcept : _handle(other._handle) 18 | { 19 | other._handle = nullptr; 20 | } 21 | 22 | Semaphore::~Semaphore() 23 | { 24 | ::sem_destroy((sem_t*) _handle); 25 | delete (sem_t*) _handle; 26 | } 27 | 28 | void Semaphore::acquire() 29 | { 30 | if (::sem_wait((sem_t*) _handle) != 0) 31 | throw Exception("Semaphore::acquire"); 32 | } 33 | 34 | bool Semaphore::tryAcquire() 35 | { 36 | if (::sem_trywait((sem_t*) _handle) != 0) 37 | { 38 | if (errno == EAGAIN) 39 | return false; 40 | 41 | throw Exception("Semaphore::tryAcquire"); 42 | } 43 | 44 | return true; 45 | } 46 | 47 | void Semaphore::release() 48 | { 49 | if (::sem_post((sem_t*) _handle) != 0) 50 | throw Exception("Semaphore::release"); 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /src/core/android/system.cpp: -------------------------------------------------------------------------------- 1 | // Standard Dependencies 2 | #include 3 | 4 | // Module Dependencies 5 | #include "../include/spinlock.h" 6 | #include "../include/stack.h" 7 | #include "../include/system.h" 8 | 9 | namespace native 10 | { 11 | void System::onExit(const Function& func) 12 | { 13 | static SpinLock lock; 14 | static Stack< Function >* funcs = nullptr; 15 | 16 | lock.lock(); 17 | 18 | if (funcs == nullptr) 19 | { 20 | funcs = new Stack< Function >(); 21 | 22 | // Register as a C++ atexit() handler. 23 | std::atexit([]() { 24 | while (funcs->getSize()) 25 | funcs->pop()(); 26 | 27 | delete funcs; 28 | }); 29 | } 30 | 31 | funcs->push(func); 32 | lock.release(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/core/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | minSdkVersion 15 9 | targetSdkVersion 26 10 | } 11 | 12 | buildTypes { 13 | release { 14 | minifyEnabled = false 15 | proguardFiles getDefaultProguardFile('proguard-android.txt') 16 | } 17 | } 18 | 19 | sourceSets { 20 | main { 21 | java.srcDir 'android' 22 | jni.srcDir 'android/java' 23 | manifest.srcFile 'android/AndroidManifest.xml' 24 | } 25 | } 26 | 27 | externalNativeBuild { 28 | cmake { 29 | path 'android/CMakeLists.txt' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation project(':jnipp') 36 | } 37 | -------------------------------------------------------------------------------- /src/core/common/asciicodec.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/asciicodec.h" 3 | 4 | namespace native 5 | { 6 | void AsciiCodec::encode(byte_t* buffer, size_t& size, const wchar_t* text, size_t& length) 7 | { 8 | if (size < length) 9 | length = size; 10 | else 11 | size = length; 12 | 13 | // Encode character by character. 14 | for (size_t i = 0; i < size; ++i) 15 | { 16 | if (text[i] & 0xFF80) 17 | buffer[i] = '?'; 18 | else 19 | buffer[i] = byte_t(text[i]); 20 | } 21 | } 22 | 23 | void AsciiCodec::decode(wchar_t* buffer, size_t& size, const byte_t* data, size_t& bytes) 24 | { 25 | if (size < bytes) 26 | bytes = size; 27 | else 28 | size = bytes; 29 | 30 | // Decode character by character. 31 | for (size_t i = 0; i < size; ++i) 32 | { 33 | if (data[i] & 0x80) 34 | buffer[i] = L'?'; 35 | else 36 | buffer[i] = wchar_t(data[i]); 37 | } 38 | } 39 | 40 | size_t AsciiCodec::length(const wchar_t* text, size_t length) 41 | { 42 | return length; 43 | } 44 | 45 | size_t AsciiCodec::encodeByteOrderMark(byte_t* buffer, size_t size) 46 | { 47 | return 0; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/core/common/clock.cpp: -------------------------------------------------------------------------------- 1 | // Standard Dependencies 2 | #include 3 | 4 | // Module Dependencies 5 | #include "../include/clock.h" 6 | 7 | namespace native 8 | { 9 | typedef std::chrono::steady_clock chrono_t; 10 | 11 | Clock::tick_t Clock::tick() 12 | { 13 | return chrono_t::now().time_since_epoch().count(); 14 | } 15 | 16 | Clock::tick_t Clock::toMilliSeconds(tick_t duration) 17 | { 18 | return 1000 * duration / chrono_t::period::den; 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/core/common/conditionvariable.cpp: -------------------------------------------------------------------------------- 1 | // Local Dependencies 2 | #include "../include/conditionvariable.h" 3 | 4 | namespace native 5 | { 6 | ConditionVariable::ConditionVariable(ILockable& lock) : _waiters(0), _lock(lock), _waitCount(0) 7 | { 8 | } 9 | 10 | ConditionVariable::~ConditionVariable() 11 | { 12 | } 13 | 14 | void ConditionVariable::wait() 15 | { 16 | Atomic::increment(_waitCount); 17 | _lock.release(); 18 | 19 | _waiters.acquire(); 20 | 21 | _lock.lock(); 22 | Atomic::decrement(_waitCount); 23 | } 24 | 25 | void ConditionVariable::signalOne() 26 | { 27 | if (_waitCount > 0) 28 | _waiters.release(); 29 | } 30 | 31 | void ConditionVariable::signalAll() 32 | { 33 | int toRelease = _waitCount; 34 | 35 | for (int i = 0; i < toRelease; i++) 36 | _waiters.release(); 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/core/common/convert.cpp: -------------------------------------------------------------------------------- 1 | // Standard Dependencies 2 | #include 3 | #include 4 | 5 | // Module Dependencies 6 | #include "../include/convert.h" 7 | #include "../include/string.h" 8 | 9 | namespace native 10 | { 11 | int Convert::toInt(const String& str) 12 | { 13 | return toInt(str.toArray()); 14 | } 15 | 16 | int Convert::toInt(const wchar_t* str) 17 | { 18 | return int(std::wcstol(str, nullptr, 10)); 19 | } 20 | 21 | int Convert::toInt(const char* str) 22 | { 23 | return int(std::strtol(str, nullptr, 10)); 24 | } 25 | 26 | float Convert::toFloat(const String& str) 27 | { 28 | return toFloat(str.toArray()); 29 | } 30 | 31 | float Convert::toFloat(const wchar_t* str) 32 | { 33 | return float(std::wcstod(str, nullptr)); 34 | } 35 | 36 | float Convert::toFloat(const char* str) 37 | { 38 | return float(std::strtod(str, nullptr)); 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/core/common/hash.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/exception.h" 3 | #include "../include/hash.h" 4 | 5 | // Local Constants 6 | #define FNV_1A32_OFFSET (2166136261UL) 7 | #define FNV_1A32_MAGIC_PRIME (16777619UL) 8 | #define FNV_1A64_OFFSET (14695981039346656037UL) 9 | #define FNV_1A64_MAGIC_PRIME (1099511628211UL) 10 | #define INT32_MAGIC_NUMBER (0x45D9F3B) 11 | #define INT64_MAGIC_NUMBER (0xBF58476D1CE4E5B9) 12 | 13 | namespace native 14 | { 15 | uint64_t hash64(const void* data, size_t size) 16 | { 17 | uint64_t value = FNV_1A64_OFFSET; 18 | byte_t* pos = (byte_t*) data; 19 | byte_t* end = pos + size; 20 | 21 | if (data == nullptr && size != 0) 22 | throw InvalidArgumentException(); 23 | 24 | while (pos < end) { 25 | value ^= uint64_t(*pos++); 26 | value *= FNV_1A64_MAGIC_PRIME; 27 | } 28 | 29 | return value; 30 | } 31 | 32 | uint32_t hash32(const void* data, size_t size) 33 | { 34 | uint32_t value = FNV_1A32_OFFSET; 35 | byte_t* pos = (byte_t*) data; 36 | byte_t* end = pos + size; 37 | 38 | if (data == nullptr && size != 0) 39 | throw InvalidArgumentException(); 40 | 41 | while (pos < end) { 42 | value ^= uint32_t(*pos++); 43 | value *= FNV_1A32_MAGIC_PRIME; 44 | } 45 | 46 | return value; 47 | } 48 | 49 | uint32_t hash32(uint64_t i) 50 | { 51 | i = ((i >> 16) ^ i) * INT32_MAGIC_NUMBER; 52 | i = ((i >> 16) ^ i) * INT32_MAGIC_NUMBER; 53 | 54 | return uint32_t((i >> 16) ^ i); 55 | } 56 | 57 | uint64_t hash64(uint64_t i) 58 | { 59 | i = (i ^ (i >> 30)) * INT64_MAGIC_NUMBER; 60 | i = (i ^ (i >> 27)) * INT64_MAGIC_NUMBER; 61 | 62 | return i ^ (i >> 31); 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/core/common/latin1codec.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/latin1codec.h" 3 | 4 | namespace native 5 | { 6 | void Latin1Codec::encode(byte_t* buffer, size_t& size, const wchar_t* text, size_t& length) 7 | { 8 | if (size < length) 9 | length = size; 10 | else 11 | size = length; 12 | 13 | // Encode character by character. 14 | for (size_t i = 0; i < size; ++i) 15 | { 16 | if (text[i] & 0xFF00) 17 | buffer[i] = '?'; 18 | else 19 | buffer[i] = byte_t(text[i]); 20 | } 21 | } 22 | 23 | void Latin1Codec::decode(wchar_t* buffer, size_t& size, const byte_t* data, size_t& bytes) 24 | { 25 | if (size < bytes) 26 | bytes = size; 27 | else 28 | size = bytes; 29 | 30 | // Decode character by character. 31 | for (size_t i = 0; i < size; ++i) 32 | buffer[i] = wchar_t(data[i]); 33 | } 34 | 35 | size_t Latin1Codec::length(const wchar_t* text, size_t length) 36 | { 37 | return length; 38 | } 39 | 40 | size_t Latin1Codec::encodeByteOrderMark(byte_t* buffer, size_t size) 41 | { 42 | return 0; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/core/common/math.cpp: -------------------------------------------------------------------------------- 1 | // Standard Dependencies 2 | #include 3 | #include 4 | 5 | // Module Dependencies 6 | #include "../include/math.h" 7 | 8 | namespace native 9 | { 10 | static std::default_random_engine engine; 11 | 12 | double Math::sqrt(double value) 13 | { 14 | return (double)std::sqrt((long double)value); 15 | } 16 | 17 | long double Math::random(long double min, long double outerMax) 18 | { 19 | return std::uniform_real_distribution(min, outerMax)(engine); 20 | } 21 | 22 | double Math::random(double min, double outerMax) 23 | { 24 | return std::uniform_real_distribution(min, outerMax)(engine); 25 | } 26 | 27 | float Math::random(float min, float outerMax) 28 | { 29 | return std::uniform_real_distribution(min, outerMax)(engine); 30 | } 31 | 32 | int Math::random(int min, int outerMax) 33 | { 34 | return int(std::uniform_real_distribution(double(min), double(outerMax))(engine)); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/core/common/memory.cpp: -------------------------------------------------------------------------------- 1 | // Standard Dependencies 2 | #include 3 | #include 4 | 5 | // Module Dependencies 6 | #include "../include/memory.h" 7 | 8 | namespace native 9 | { 10 | void* Memory::allocate(size_t bytes) 11 | { 12 | return std::malloc(bytes); 13 | } 14 | 15 | void* Memory::allocateAndZero(size_t bytes) 16 | { 17 | return std::calloc(1, bytes); 18 | } 19 | 20 | void Memory::free(void* memory) noexcept 21 | { 22 | std::free(memory); 23 | } 24 | 25 | void* Memory::copy(void* dest, const void* src, size_t bytes) 26 | { 27 | return std::memcpy(dest, src, bytes); 28 | } 29 | 30 | void* Memory::move(void* dest, const void* src, size_t bytes) 31 | { 32 | return std::memmove(dest, src, bytes); 33 | } 34 | 35 | void Memory::zero(void* memory, size_t bytes) 36 | { 37 | std::memset(memory, 0, bytes); 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/core/common/singleton.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/exception.h" 3 | #include "../include/singleton.h" 4 | 5 | namespace native 6 | { 7 | namespace internal 8 | { 9 | void singletonNotInitialised() 10 | { 11 | throw InvalidStateException(); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/core/common/spinlock.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/atomic.h" 3 | #include "../include/spinlock.h" 4 | #include "../include/thread.h" 5 | 6 | namespace native 7 | { 8 | SpinLock::SpinLock() noexcept : _waitCount(0) 9 | { 10 | } 11 | 12 | SpinLock::~SpinLock() 13 | { 14 | Atomic::exchange(_waitCount, 0); 15 | } 16 | 17 | void SpinLock::lock() 18 | { 19 | while (Atomic::compareExchange(_waitCount, 1, 0) != 0) 20 | Thread::yield(); 21 | } 22 | 23 | void SpinLock::release() 24 | { 25 | Atomic::exchange(_waitCount, 0); 26 | } 27 | 28 | bool SpinLock::isLocked() const noexcept 29 | { 30 | return _waitCount != 0; 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/core/common/stringcodec.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/asciicodec.h" 3 | #include "../include/latin1codec.h" 4 | #include "../include/singleton.h" 5 | #include "../include/stringcodec.h" 6 | #include "../include/utf8codec.h" 7 | 8 | namespace native 9 | { 10 | StringCodec::StringCodec(const String& name) : _name(name) 11 | { 12 | } 13 | 14 | size_t StringCodec::encodeByteOrderMark(byte_t*, size_t) 15 | { 16 | return 0; 17 | } 18 | 19 | String StringCodec::getName() const 20 | { 21 | return _name; 22 | } 23 | 24 | void StringCodec::registerByName(StringCodec* codec) 25 | { 26 | CodecRegistry& registry = Singleton::get(); 27 | 28 | if (codec == nullptr) 29 | throw InvalidArgumentException(); 30 | 31 | if (!registry.containsKey(codec->getName())) 32 | { 33 | registry.add(codec->getName(), codec); 34 | } 35 | } 36 | 37 | StringCodec* StringCodec::byName(const String& name) 38 | { 39 | CodecRegistry& registry = Singleton::get(); 40 | return registry[name]; 41 | } 42 | 43 | StringCodec::CodecRegistry::CodecRegistry() 44 | { 45 | AsciiCodec* ascii = new AsciiCodec(); 46 | Latin1Codec* latin1 = new Latin1Codec(); 47 | StringCodec* utf8 = new Utf8Codec(); 48 | 49 | add(ascii->getName(), ascii); 50 | add(latin1->getName(), latin1); 51 | add(utf8->getName(), utf8); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/core/common/threadpool.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/lockscope.h" 3 | #include "../include/threadpool.h" 4 | 5 | namespace native 6 | { 7 | Queue> ThreadPool::_tasks; 8 | List ThreadPool::_threads; 9 | Mutex ThreadPool::_lock; 10 | ConditionVariable ThreadPool::_taskAvailable(_lock); 11 | bool ThreadPool::_terminate = false; 12 | 13 | void ThreadPool::enqueue(const Function& task) 14 | { 15 | LockScope lock(_lock); 16 | 17 | if (_threads.getLength() == 0 || (_tasks.getSize() > 0 && _threads.getLength() < 8)) // TODO: Something less arbitrary. 18 | { 19 | _threads.add(new Thread([&]() { 20 | while (!_terminate) 21 | { 22 | Function t; 23 | 24 | { 25 | LockScope l(_lock); 26 | 27 | // Wait for the next task in the queue. 28 | while (_tasks.getSize() == 0) 29 | _taskAvailable.wait(); 30 | 31 | t = _tasks.pop(); 32 | } 33 | 34 | t.invoke(); 35 | } 36 | })); 37 | } 38 | 39 | _tasks.push(task); 40 | _taskAvailable.signalOne(); 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/core/include/clock.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_CLOCK_H_ 2 | #define _NATIVE_CLOCK_H_ 1 3 | 4 | // Module Dependencies 5 | #include "types.h" 6 | 7 | namespace native 8 | { 9 | /** 10 | A simple timing mechanism for measuring how much time has passed between 11 | two code statements. Time between Clock ticks is not dependent on the 12 | DateTime values, so changes in computer settings will not affect it. 13 | */ 14 | class Clock final 15 | { 16 | public: 17 | /** Storage type for a single time moment, or "tick". */ 18 | typedef uint64_t tick_t; 19 | 20 | /** 21 | Gets the current tick value. Tick values can be compared to determine 22 | how much time has passed. 23 | */ 24 | static tick_t tick(); 25 | 26 | /** 27 | Converts the number of ticks to a duration in milliseconds. 28 | \param duration The number of ticks. 29 | \return The number of milliseconds. 30 | */ 31 | static tick_t toMilliSeconds(tick_t duration); 32 | }; 33 | } 34 | 35 | #endif // _NATIVE_CLOCK_H_ 36 | 37 | -------------------------------------------------------------------------------- /src/core/include/collection.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_COLLECTION_H_ 2 | #define _NATIVE_COLLECTION_H_ 1 3 | 4 | // Module Dependencies 5 | #include "iterator.h" 6 | 7 | namespace native 8 | { 9 | /** 10 | The base class of all multi-valued data structures. This is an interface 11 | that defines those functions that must be implemented. 12 | */ 13 | template 14 | class Collection 15 | { 16 | public: 17 | /** Virtual destructor. */ 18 | virtual ~Collection() = default; 19 | 20 | /** 21 | Adds the given value to the Collection. 22 | \param value The value to add. 23 | */ 24 | virtual void add(const typename TIterator::Value& value) = 0; 25 | 26 | /** Removes all items from the Collection. */ 27 | virtual void clear() = 0; 28 | 29 | /** 30 | Returns the number of items in the Collection. 31 | \return The Collection's length. 32 | */ 33 | virtual size_t getLength() const noexcept = 0; 34 | 35 | /** 36 | Obtains an Iterator positioned at the first value in this Collection. 37 | \return An iterator for this Collection. 38 | */ 39 | virtual TIterator begin() const = 0; 40 | 41 | /** 42 | Returns an Iterator positioned past the last value in the Collection. 43 | \return An Iterator. 44 | */ 45 | virtual TIterator end() const = 0; 46 | }; 47 | 48 | namespace internal 49 | { 50 | /** Used to maintain a linked-list chain of values. */ 51 | template 52 | struct LinkedValue 53 | { 54 | LinkedValue(const TValue& value, LinkedValue* next) : value(value), next(next) {} 55 | TValue value; 56 | LinkedValue* next; 57 | }; 58 | } 59 | } 60 | 61 | #endif // _NATIVE_COLLECTION_H_ 62 | 63 | -------------------------------------------------------------------------------- /src/core/include/conditionvariable.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_CONDITION_VARIABLE_H_ 2 | #define _NATIVE_CONDITION_VARIABLE_H_ 1 3 | 4 | // Module Dependencies 5 | #include "ilockable.h" 6 | #include "semaphore.h" 7 | 8 | namespace native 9 | { 10 | /** 11 | A ConditionVariable allows a Thread to wait for a particular condition 12 | to be met on a protected resource, without having to explicitly unlock 13 | the Mutex protecting that resource to poll the condition's status. 14 | */ 15 | class ConditionVariable 16 | { 17 | public: 18 | /** 19 | Constructor. 20 | \param lock ILockable protecting the shared resource. 21 | */ 22 | ConditionVariable(ILockable& lock); 23 | 24 | /** Destructor. */ 25 | ~ConditionVariable(); 26 | 27 | /** 28 | Waits for this ConditionVariable to be signalled to indicate a 29 | condition has been met to access the protected resource. 30 | */ 31 | void wait(); 32 | 33 | /** 34 | Signals the ConditionVariable allowing just one waiting Thread through. 35 | 36 | */ 37 | void signalOne(); 38 | 39 | /** 40 | Signals the ConditionVariable, allowing all waiting Threads to execute. 41 | */ 42 | void signalAll(); 43 | 44 | private: 45 | // Instance Variables 46 | Semaphore _waiters; 47 | ILockable& _lock; 48 | volatile int _waitCount; 49 | }; 50 | } 51 | 52 | #endif // _NATIVE_CONDITION_VARIABLE_H_ 53 | 54 | -------------------------------------------------------------------------------- /src/core/include/convert.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_CONVERT_H_ 2 | #define _NATIVE_CONVERT_H_ 1 3 | 4 | // Module Dependencies 5 | #include "types.h" 6 | 7 | namespace native 8 | { 9 | // Forward Declarations 10 | class String; 11 | 12 | /** 13 | Convert is a static class that provides basic type conversions. 14 | */ 15 | class Convert 16 | { 17 | public: 18 | // Prevent Instantiation 19 | Convert() = delete; 20 | 21 | /** 22 | Converts a string to an int, or raises a FormatException. 23 | \param str The string to convert. 24 | \return The integer result. 25 | */ 26 | static int toInt(const String& str); 27 | static int toInt(const wchar_t* str); 28 | static int toInt(const char* str); 29 | 30 | /** 31 | Converts a string to a float, or raises a FormatException. 32 | \param str The string to conert. 33 | \return The float result. 34 | */ 35 | static float toFloat(const String& str); 36 | static float toFloat(const wchar_t* str); 37 | static float toFloat(const char* str); 38 | }; 39 | } 40 | 41 | #endif // _NATIVE_CONVERT_H_ 42 | 43 | -------------------------------------------------------------------------------- /src/core/include/ilockable.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_ILOCKABLE_H_ 2 | #define _NATIVE_ILOCKABLE_H_ 1 3 | 4 | namespace native 5 | { 6 | /** 7 | A basic interface for resource locking. 8 | */ 9 | class ILockable 10 | { 11 | public: 12 | /** Virtual destructor. */ 13 | virtual ~ILockable() = default; 14 | 15 | /** Waits for and aquires the lock on this ILockable. */ 16 | virtual void lock() = 0; 17 | 18 | /** Releases the current lock on this ILockable. */ 19 | virtual void release() = 0; 20 | }; 21 | } 22 | 23 | #endif // _NATIVE_ILOCKABLE_H_ 24 | 25 | -------------------------------------------------------------------------------- /src/core/include/iterator.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_ITERATOR_H_ 2 | #define _NATIVE_ITERATOR_H_ 1 3 | 4 | // Module Dependencies 5 | #include "atomic.h" 6 | 7 | namespace native 8 | { 9 | /** 10 | Used to iterate through the values in a Collection. 11 | */ 12 | template 13 | class Iterator 14 | { 15 | public: 16 | /** The type of value being iterated over. */ 17 | typedef TValue Value; 18 | 19 | /** Virtual destructor. */ 20 | virtual ~Iterator() = default; 21 | 22 | /** 23 | Increments the iterator forward to the next value in the Collection. 24 | \return The iterator (typed as the concrete type). 25 | */ 26 | virtual TIterator& operator++() = 0; 27 | 28 | /** 29 | Returns the current value in iteration. 30 | \return The current value in iteration. 31 | */ 32 | virtual const TValue& operator*() const = 0; 33 | 34 | /** 35 | Tests iterators for inequality. 36 | \param other The iterator to compare with. 37 | \return true if different, false if the same. 38 | */ 39 | virtual bool operator!=(const TIterator& other) const = 0; 40 | }; 41 | } 42 | 43 | #endif // _NATIVE_ITERATOR_H_ 44 | -------------------------------------------------------------------------------- /src/core/include/lockscope.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_LOCK_SCOPE_H_ 2 | #define _NATIVE_LOCK_SCOPE_H_ 1 3 | 4 | // Module Dependencies 5 | #include "ilockable.h" 6 | 7 | namespace native 8 | { 9 | /** 10 | Automatically locks and unlocks an ILockable in its scope lifetime. 11 | */ 12 | class LockScope 13 | { 14 | public: 15 | /** 16 | Acquires a lock on the given ILockable. 17 | \param lock The lock to acquire. 18 | */ 19 | LockScope(ILockable& lock) : _lock(lock) { _lock.lock(); } 20 | 21 | /** 22 | Releases the lock on the scope's lockable object. 23 | */ 24 | ~LockScope() { _lock.release(); } 25 | 26 | private: 27 | // Instance Variables 28 | ILockable& _lock; 29 | }; 30 | } 31 | 32 | #endif // _NATIVE_LOCK_SCOPE_H_ 33 | 34 | -------------------------------------------------------------------------------- /src/core/include/mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_MUTEX_H_ 2 | #define _NATIVE_MUTEX_H_ 1 3 | 4 | // Local Dependencies 5 | #include "exception.h" 6 | #include "ilockable.h" 7 | 8 | namespace native 9 | { 10 | /** 11 | A Mutex is a resource locking mechanism, which can lock and release a 12 | resource and allow resource consumers to block until the resource is 13 | available. 14 | */ 15 | class Mutex : public ILockable 16 | { 17 | public: 18 | /** 19 | Creates an unnamed, in-process Mutex. The Mutex is initially 20 | unlocked. 21 | */ 22 | Mutex(); 23 | 24 | /** 25 | Move constructor. Moves the other Mutex to this instance. 26 | \param other The Mutex to move. 27 | */ 28 | Mutex(Mutex&& other) noexcept : _handle(other._handle) { other._handle = nullptr; } 29 | 30 | /** Destructor. */ 31 | ~Mutex(); 32 | 33 | /** 34 | Locks the Mutex. If the Mutex is already locked, this waits until 35 | it is released before claiming the lock. 36 | */ 37 | void lock() override; 38 | 39 | /** 40 | Attempts to lock the Mutex, without waiting. If the Mutex is already 41 | locked, it does not claim the lock. If the Mutex is free, this claims 42 | the lock. 43 | \return true if lock is claimed, false if already locked elsewhere. 44 | */ 45 | bool tryLock(); 46 | 47 | /** 48 | Releases the Mutex to allow other code to lock it. 49 | */ 50 | void release() override; 51 | 52 | private: 53 | // Instance Variables 54 | handle_t _handle; 55 | }; 56 | } 57 | 58 | #endif // _NATIVE_MUTEX_H_ 59 | 60 | -------------------------------------------------------------------------------- /src/core/include/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_CORE_PLATFORM_H_ 2 | #define _NATIVE_CORE_PLATFORM_H_ 1 3 | 4 | // Platform Detection 5 | #if defined(_WIN32) || defined(_WIN64) 6 | # define NATIVE_PLATFORM_WIN32 1 7 | #elif defined(__ANDROID__) 8 | # define NATIVE_PLATFORM_ANDROID 1 9 | #else 10 | # error No supported platform detected. 11 | #endif // NATIVE_PLATFORM_* 12 | 13 | // Processor Architecture 14 | #if defined(_WIN64) || defined(__x86_64__) || defined(__amd64__) 15 | # define NATIVE_ARCH_X64 1 16 | #elif defined(_WIN32) || defined(__i386__) || defined(_M_X86) || defined(__i686__) 17 | # define NATIVE_ARCH_X86 1 18 | #elif defined(__ARM_EABI__) || defined(_M_ARM) || defined(__arm__) 19 | # define NATIVE_ARCH_ARM 1 20 | #elif defined(__aarch64__) 21 | # define NATIVE_ARCH_ARM64 1 22 | #elif defined(__mips__) && (__mips__ < 5) 23 | # define NATIVE_ARCH_MIPS 1 24 | #else 25 | # error No supported processor architecture detected. 26 | #endif // NATIVE_ARCH_* 27 | 28 | // Pointer Bit Size 29 | #if defined(NATIVE_ARCH_X64) || defined(NATIVE_ARCH_ARM64) 30 | # define NATIVE_BIT_WIDTH 64 31 | #else 32 | # define NATIVE_BIT_WIDTH 32 33 | #endif // NATIVE_BIT_WIDTH 34 | 35 | // Form-Factors 36 | #if defined(NATIVE_PLATFORM_WIN32) 37 | # define NATIVE_FORM_DESKTOP 1 38 | #elif defined(NATIVE_PLATFORM_ANDROID) 39 | # define NATIVE_FORM_MOBILE 1 40 | #else 41 | # error Form-factor for current platform not defined. 42 | #endif 43 | 44 | #endif // _NATIVE_CORE_PLATFORM_H_ 45 | 46 | -------------------------------------------------------------------------------- /src/core/include/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_QUEUE_H_ 2 | #define _NATIVE_QUEUE_H_ 1 3 | 4 | // Module Dependencies 5 | #include "linkedlist.h" 6 | 7 | namespace native 8 | { 9 | /** 10 | A first-in-first-out list where values are "pushed" onto the Queue, and 11 | then the first added value can be "popped" from the Queue. 12 | */ 13 | template 14 | class Queue 15 | { 16 | public: 17 | /** 18 | Adds the given value to the Queue. 19 | \param value The value to add. 20 | */ 21 | void push(const TValue& value) { _list.append(value); } 22 | 23 | /** 24 | Removes the value from the end of the Queue and returns it. 25 | \return The removed value. 26 | */ 27 | TValue pop(); 28 | 29 | /** 30 | Returns a reference to the value at the end of the Queue. This 31 | does not remove the value from the Queue. 32 | \return The end value on the Queue. 33 | */ 34 | const TValue& peek() const; 35 | 36 | /** 37 | Gets the number of values in the Queue. 38 | \return The Queue size. 39 | */ 40 | size_t getSize() const noexcept { return _list.getLength(); } 41 | 42 | /** 43 | Tells whether the Queue is empty or not. 44 | \return true if empty, false if it contains values. 45 | */ 46 | bool isEmpty() const noexcept { return getSize() == 0; } 47 | 48 | private: 49 | // Instance Variables 50 | LinkedList _list; 51 | }; 52 | 53 | template 54 | TValue Queue::pop() 55 | { 56 | if (_list.getLength() == 0) 57 | throw InvalidStateException(); 58 | 59 | auto i = _list.begin(); 60 | TValue value = std::move(*i); 61 | _list.remove(i); 62 | return value; 63 | } 64 | 65 | template 66 | const TValue& Queue::peek() const 67 | { 68 | if (_list.getLength() == 0) 69 | throw InvalidStateException(); 70 | 71 | return *(_list.begin()); 72 | } 73 | } 74 | 75 | #endif // _NATIVE_QUEUE_H_ 76 | -------------------------------------------------------------------------------- /src/core/include/semaphore.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_SEMAPHORE_H_ 2 | #define _NATIVE_SEMAPHORE_H_ 1 3 | 4 | // Local Dependencies 5 | #include "exception.h" 6 | 7 | namespace native 8 | { 9 | /** 10 | Semaphore is a synchronisation primitive that maintains a count of 11 | available resources which can be acquired by waiting Threads. When 12 | the value of a Semaphore reaches zero 13 | */ 14 | class Semaphore 15 | { 16 | public: 17 | /** 18 | Creates the Semaphore with the given initial value. 19 | \param initialValue The initial value in the Semaphore. 20 | */ 21 | Semaphore(uint32_t initialValue = 0); 22 | 23 | /** 24 | Move constructor. Moves the other Semaphore to this instance. 25 | \param other The Semaphore to move. 26 | */ 27 | Semaphore(Semaphore&& other) noexcept; 28 | 29 | /** Destructor. */ 30 | ~Semaphore(); 31 | 32 | /** 33 | Acquires a slot in the Semaphore, therefore decrementing the Semaphore 34 | value. If the Semaphore value is zero, then the executing Thread blocks 35 | until there is a slot available. 36 | */ 37 | void acquire(); 38 | 39 | /** 40 | Tries to acquire a slot in the Semaphore without blocking. If the Semaphore 41 | value is zero, then the result is false and the calling thread will not block. 42 | Otherwise, the Semaphore value is decremented and true is returned. 43 | \return `true` if slot acquired, `false` if no slot available. 44 | */ 45 | bool tryAcquire(); 46 | 47 | /** 48 | Release's the current Thread's hold on one of the Semaphore slots by 49 | incrementing the Semaphore value. 50 | */ 51 | void release(); 52 | 53 | private: 54 | // Instance Variables 55 | handle_t _handle; 56 | }; 57 | } 58 | 59 | #endif // _NATIVE_SEMAPHORE_H_ 60 | 61 | -------------------------------------------------------------------------------- /src/core/include/singleton.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_SINGLETON_H_ 2 | #define _NATIVE_SINGLETON_H_ 1 3 | 4 | // Module Dependencies 5 | #include "spinlock.h" 6 | #include "system.h" 7 | 8 | namespace native 9 | { 10 | /** 11 | Singleton wraps a single instance of the given type. All instances of the 12 | same type returned by Singleton::get are the same instance, created during 13 | the first call to Singleton::get(). 14 | */ 15 | template 16 | class Singleton 17 | { 18 | public: 19 | // Prevent Creation 20 | Singleton() = delete; 21 | 22 | /** Retrieves the instance held by this Singleton. */ 23 | static T& get(); 24 | 25 | private: 26 | // Static Variables 27 | static SpinLock _lock; 28 | }; 29 | 30 | // ---------------------------------------------------------------------- // 31 | // Singleton Implementation // 32 | // ---------------------------------------------------------------------- // 33 | 34 | namespace internal 35 | { 36 | void singletonNotInitialised(); 37 | } 38 | 39 | template SpinLock Singleton::_lock; 40 | 41 | template 42 | T& Singleton::get() 43 | { 44 | static T* instance = nullptr; 45 | 46 | if (!instance) 47 | { 48 | _lock.lock(); 49 | 50 | try 51 | { 52 | if (!instance) 53 | { 54 | T* obj = new T(); 55 | 56 | // Make sure it is deleted later on. 57 | System::onExit([obj]() { delete obj; }); 58 | 59 | instance = obj; 60 | } 61 | } 62 | catch (...) { 63 | } 64 | 65 | _lock.release(); 66 | } 67 | 68 | if (!instance) 69 | internal::singletonNotInitialised(); 70 | 71 | return *instance; 72 | } 73 | } 74 | 75 | #endif // _NATIVE_SINGLETON_H_ 76 | -------------------------------------------------------------------------------- /src/core/include/spinlock.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_SPIN_LOCK_H_ 2 | #define _NATIVE_SPIN_LOCK_H_ 1 3 | 4 | // Module Dependencies 5 | #include "ilockable.h" 6 | #include "types.h" 7 | 8 | namespace native 9 | { 10 | /** 11 | SpinLock is a very light-weight mutual exclusion mechanism for thread 12 | protection. It does not utilise any OS functionality, so is very low 13 | on resources, and can be staticially initialised. 14 | 15 | This should never be used to protect a resource for more than a few 16 | execution statements, as it will leave competing threads executing. 17 | Use a Mutex when protecting a resource for longer periods. 18 | */ 19 | class SpinLock : public ILockable 20 | { 21 | public: 22 | /** Creates an unlocked SpinLock. */ 23 | SpinLock() noexcept; 24 | 25 | /** Destroys the SpinLock. */ 26 | ~SpinLock(); 27 | 28 | /** Waits for and aquires the lock on this SpinLock. */ 29 | void lock() override; 30 | 31 | /** Releases the current lock on this SpinLock. */ 32 | void release() override; 33 | 34 | /** 35 | Tells whether a lock is currently held on the SpinLock. 36 | \return true if locked, false if available. 37 | */ 38 | bool isLocked() const noexcept; 39 | 40 | private: 41 | // Instance Variables 42 | volatile int32_t _waitCount; 43 | }; 44 | } 45 | 46 | #endif // _NATIVE_SPIN_LOCK_H_ 47 | 48 | -------------------------------------------------------------------------------- /src/core/include/system.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_SYSTEM_H_ 2 | #define _NATIVE_SYSTEM_H_ 1 3 | 4 | // Module Dependencies 5 | #include "function.h" 6 | 7 | namespace native 8 | { 9 | /** 10 | System provides system-scoped functionality, which tends to not belong 11 | in its own class for one reason or another. 12 | */ 13 | class System 14 | { 15 | public: 16 | // Prevent Instantiation 17 | System() = delete; 18 | 19 | /** 20 | Registers the given Function to be called on program termination. 21 | \param func The Function to register. 22 | */ 23 | static void onExit(const Function& func); 24 | }; 25 | } 26 | 27 | #endif // _NATIVE_SYSTEM_H_ 28 | -------------------------------------------------------------------------------- /src/core/include/threadpool.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_THREAD_POOL_H_ 2 | #define _NATIVE_THREAD_POOL_H_ 1 3 | 4 | // Module Dependencies 5 | #include "conditionvariable.h" 6 | #include "function.h" 7 | #include "list.h" 8 | #include "mutex.h" 9 | #include "queue.h" 10 | #include "thread.h" 11 | 12 | namespace native 13 | { 14 | /** 15 | ThreadPool is a helper class which queues tasks to be executed on one of 16 | many available worker threads. The enqueued tasks are generally short- 17 | lived and/or repetitive, so the ThreadPool helps to remove some of the 18 | overhead of creating and destroying a Thread itself. 19 | 20 | ThreadPool is fully static as there should only be one pool of Threads, 21 | with a thread count generally correlating to the number of processor 22 | cores. 23 | */ 24 | class ThreadPool 25 | { 26 | public: 27 | // Prevent Instantiation 28 | ThreadPool() = delete; 29 | 30 | /** 31 | Enqueues a Function to be called on the next available Thread. 32 | \param task The Function to be executed. 33 | */ 34 | static void enqueue(const Function& task); 35 | 36 | private: 37 | // Variables 38 | static Queue> _tasks; 39 | static List _threads; 40 | static Mutex _lock; 41 | static ConditionVariable _taskAvailable; 42 | static bool _terminate; 43 | }; 44 | } 45 | 46 | #endif // _NATIVE_THREAD_POOL_H_ 47 | 48 | -------------------------------------------------------------------------------- /src/core/include/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_TYPES_H_ 2 | #define _NATIVE_TYPES_H_ 1 3 | 4 | // Standard Dependencies 5 | #include 6 | #include 7 | 8 | // Module Dependencies 9 | #include "platform.h" 10 | 11 | namespace native 12 | { 13 | // Integer Types 14 | typedef char int8_t; ///< A signed, 8-bit integer. 15 | typedef short int16_t; ///< A signed 16-bit integer. 16 | typedef int int32_t; ///< A signed 32-bit integer. 17 | typedef long long int64_t; ///< A signed 64-bit integer. 18 | typedef unsigned char uint8_t; ///< An unsigned, 8-bit integer. 19 | typedef unsigned short uint16_t; ///< An unsigned 16-bit integer. 20 | typedef unsigned int uint32_t; ///< An unsigned 32-bit integer. 21 | typedef unsigned long long uint64_t; ///< An unsigned 64-bit integer. 22 | 23 | #if NATIVE_BIT_WIDTH == 64 24 | typedef int64_t ptrint_t; ///< A pointer-sized integer. 25 | typedef uint64_t uptrint_t; ///< An unsigned, pointer-sized integer. 26 | #elif NATIVE_BIT_WIDTH == 32 27 | typedef int32_t ptrint_t; ///< A pointer-sized integer. 28 | typedef uint32_t uptrint_t; ///< An unsigned, pointer-sized integer. 29 | #else 30 | # error Unable to define pointer-sized types. 31 | #endif // NATIVE_ARCH_ 32 | 33 | // Basic, Non-Structure Types 34 | typedef unsigned char byte_t; ///< A single byte of data. 35 | typedef void* handle_t; ///< A platform-specific resource handle. 36 | typedef int32_t coord_t; ///< A co-ordinate value, which can be positive or negative. 37 | } 38 | 39 | #endif // _NATIVE_TYPES_H_ 40 | 41 | -------------------------------------------------------------------------------- /src/core/win32/mutex.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | 4 | // Local Dependencies 5 | #include "../include/exception.h" 6 | #include "../include/mutex.h" 7 | 8 | namespace native 9 | { 10 | Mutex::Mutex() 11 | { 12 | if ((_handle = ::CreateMutex(NULL, FALSE, NULL)) == NULL) 13 | throw Exception("Mutex::Mutex"); 14 | } 15 | 16 | Mutex::~Mutex() 17 | { 18 | ::CloseHandle(_handle); 19 | } 20 | 21 | void Mutex::lock() 22 | { 23 | switch (::WaitForSingleObject(_handle, INFINITE)) 24 | { 25 | case WAIT_OBJECT_0: 26 | return; 27 | 28 | case WAIT_TIMEOUT: 29 | throw InterruptException(); 30 | 31 | case WAIT_ABANDONED: 32 | throw InterruptException("Abandoned Mutex detected"); 33 | 34 | default: 35 | throw Exception("Mutex::lock"); 36 | } 37 | } 38 | 39 | bool Mutex::tryLock() 40 | { 41 | switch (::WaitForSingleObject(_handle, 0)) 42 | { 43 | case WAIT_OBJECT_0: 44 | return true; 45 | 46 | case WAIT_TIMEOUT: 47 | return false; 48 | 49 | case WAIT_ABANDONED: 50 | throw InterruptException("Abandoned Mutex detected"); 51 | 52 | default: 53 | throw Exception("Mutex::tryLock"); 54 | } 55 | } 56 | 57 | void Mutex::release() 58 | { 59 | if (::ReleaseMutex(_handle) == 0) 60 | throw Exception("Mutex::unlock"); 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/core/win32/semaphore.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | 4 | // Module Dependencies 5 | #include "../include/semaphore.h" 6 | 7 | namespace native 8 | { 9 | Semaphore::Semaphore(uint32_t initialValue) 10 | { 11 | if ((_handle = ::CreateSemaphore(NULL, initialValue, LONG_MAX, NULL)) == NULL) 12 | throw Exception("Mutex::Mutex"); 13 | } 14 | 15 | Semaphore::Semaphore(Semaphore&& other) noexcept : _handle(other._handle) 16 | { 17 | other._handle = nullptr; 18 | } 19 | 20 | Semaphore::~Semaphore() 21 | { 22 | ::CloseHandle(_handle); 23 | } 24 | 25 | void Semaphore::acquire() 26 | { 27 | switch (::WaitForSingleObject(_handle, INFINITE)) 28 | { 29 | case WAIT_OBJECT_0: 30 | return; 31 | 32 | case WAIT_TIMEOUT: 33 | throw InterruptException(); 34 | 35 | case WAIT_ABANDONED: 36 | throw InterruptException("Abandoned Semaphore detected"); 37 | 38 | default: 39 | throw Exception("Semaphore::acquire"); 40 | } 41 | } 42 | 43 | bool Semaphore::tryAcquire() 44 | { 45 | switch (::WaitForSingleObject(_handle, 0)) 46 | { 47 | case WAIT_OBJECT_0: 48 | return true; 49 | 50 | case WAIT_TIMEOUT: 51 | return false; 52 | 53 | case WAIT_ABANDONED: 54 | throw InterruptException("Abandoned Semaphore detected"); 55 | 56 | default: 57 | throw Exception("Semaphore::tryAcquire"); 58 | } 59 | } 60 | 61 | void Semaphore::release() 62 | { 63 | if (::ReleaseSemaphore(_handle, 1, NULL) == 0) 64 | throw Exception("Semaphore::release"); 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/core/win32/system.cpp: -------------------------------------------------------------------------------- 1 | // Standard Dependencies 2 | #include 3 | 4 | // Module Dependencies 5 | #include "../include/spinlock.h" 6 | #include "../include/stack.h" 7 | #include "../include/system.h" 8 | 9 | namespace native 10 | { 11 | void System::onExit(const Function& func) 12 | { 13 | static SpinLock lock; 14 | static Stack< Function >* funcs = nullptr; 15 | 16 | lock.lock(); 17 | 18 | if (funcs == nullptr) 19 | { 20 | funcs = new Stack< Function >(); 21 | 22 | // Register as a C++ atexit() handler. 23 | std::atexit([]() { 24 | while (funcs->getSize()) 25 | funcs->pop()(); 26 | 27 | delete funcs; 28 | }); 29 | } 30 | 31 | funcs->push(func); 32 | lock.release(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/core/win32/thread.cpp: -------------------------------------------------------------------------------- 1 | #define NO_STRICT 1 2 | 3 | // System Dependencies 4 | #include 5 | 6 | // Module Dependencies 7 | #include "../include/exception.h" 8 | #include "../include/thread.h" 9 | 10 | namespace native 11 | { 12 | static thread_local Thread* _current = nullptr; 13 | 14 | Thread::Thread(const Function& func) : _handle(nullptr), _func(func), _started(false), _id(0) 15 | { 16 | start(_func); 17 | } 18 | 19 | Thread::~Thread() 20 | { 21 | while (_handle != nullptr && !_started) 22 | yield(); 23 | } 24 | 25 | void Thread::start(const Function& func) 26 | { 27 | if (_handle != nullptr) 28 | throw InvalidStateException(); 29 | 30 | _func = func; 31 | 32 | // Create the Thread resource with the OS. 33 | _handle = ::CreateThread(NULL, 0, LPTHREAD_START_ROUTINE(&entryPoint), this, 0, NULL); 34 | 35 | if (_handle == NULL) 36 | throw InsufficientResourcesException(); 37 | } 38 | 39 | void Thread::join() const 40 | { 41 | ::WaitForSingleObject(_handle, INFINITE); 42 | } 43 | 44 | void Thread::sleep(uint32_t milliSeconds) 45 | { 46 | if (milliSeconds > MAXDWORD) 47 | milliSeconds = MAXDWORD; 48 | 49 | ::Sleep(milliSeconds); 50 | } 51 | 52 | void Thread::yield() 53 | { 54 | ::YieldProcessor(); 55 | } 56 | 57 | Thread* Thread::getCurrent() 58 | { 59 | return _current; 60 | } 61 | 62 | int64_t Thread::getCurrentId() 63 | { 64 | return ::GetCurrentThreadId(); 65 | } 66 | 67 | ptrint_t Thread::entryPoint(Thread* thread) 68 | { 69 | _current = thread; 70 | thread->_started = true; 71 | 72 | try 73 | { 74 | // Execute the Thread's Function. 75 | thread->_func(); 76 | } 77 | catch (...) 78 | { 79 | return 1; 80 | } 81 | 82 | _current = nullptr; 83 | return 0; 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /src/data/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/data/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${root_dir}/lib/${ANDROID_ABI}") 9 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 10 | 11 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 12 | 13 | ADD_LIBRARY(data SHARED ${sources}) 14 | -------------------------------------------------------------------------------- /src/data/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | minSdkVersion 15 9 | targetSdkVersion 26 10 | } 11 | 12 | buildTypes { 13 | release { 14 | minifyEnabled = false 15 | proguardFiles getDefaultProguardFile('proguard-android.txt') 16 | } 17 | } 18 | 19 | sourceSets { 20 | main { 21 | manifest.srcFile 'android/AndroidManifest.xml' 22 | } 23 | } 24 | 25 | externalNativeBuild { 26 | cmake { 27 | path 'android/CMakeLists.txt' 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/data/data.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/data/dummy.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/src/data/dummy.cpp -------------------------------------------------------------------------------- /src/io/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/io/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${root_dir}/lib/${ANDROID_ABI}") 9 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 10 | 11 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 12 | 13 | ADD_LIBRARY(core STATIC IMPORTED) 14 | 15 | ADD_LIBRARY(io SHARED ${sources}) 16 | 17 | SET_TARGET_PROPERTIES(core PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libcore.so") 18 | 19 | TARGET_LINK_LIBRARIES(io core) 20 | -------------------------------------------------------------------------------- /src/io/android/file.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | 4 | // Local Dependencies 5 | #include "../include/file.h" 6 | 7 | namespace native 8 | { 9 | namespace io 10 | { 11 | File::File(const String& path, Flags state) : _handle(nullptr) 12 | { 13 | open(path, state); 14 | } 15 | 16 | File::File(File&& other) noexcept : _handle(other._handle) 17 | { 18 | other._handle = nullptr; 19 | } 20 | 21 | void File::open(const String& path, Flags state) 22 | { 23 | throw NotImplementedException(); 24 | } 25 | 26 | void File::close() noexcept 27 | { 28 | if (_handle) 29 | { 30 | ::close(int(ptrint_t(_handle))); 31 | _handle = nullptr; 32 | } 33 | } 34 | 35 | size_t File::read(void* buffer, size_t maxBytes) 36 | { 37 | throw NotImplementedException(); 38 | } 39 | 40 | size_t File::write(const void* data, size_t bytes) 41 | { 42 | throw NotImplementedException(); 43 | } 44 | 45 | void File::deleteFromDisk(const String& path) 46 | { 47 | throw NotImplementedException(); 48 | } 49 | 50 | bool File::exists(const String& path) 51 | { 52 | throw NotImplementedException(); 53 | } 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/io/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | minSdkVersion 15 9 | targetSdkVersion 26 10 | } 11 | 12 | buildTypes { 13 | release { 14 | minifyEnabled = false 15 | proguardFiles getDefaultProguardFile('proguard-android.txt') 16 | } 17 | } 18 | 19 | sourceSets { 20 | main { 21 | manifest.srcFile 'android/AndroidManifest.xml' 22 | } 23 | } 24 | 25 | externalNativeBuild { 26 | cmake { 27 | path 'android/CMakeLists.txt' 28 | } 29 | } 30 | } 31 | 32 | dependencies { 33 | implementation project(':core') 34 | } -------------------------------------------------------------------------------- /src/io/common/memorystream.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/memorystream.h" 3 | 4 | namespace native 5 | { 6 | namespace io 7 | { 8 | MemoryStream::MemoryStream(const void* data, size_t length) : _length(length), _pos(0), _data(data) 9 | { 10 | } 11 | 12 | MemoryStream::MemoryStream(const ByteArray& array) : _array(array), _length(array.getLength()), _pos(0) 13 | { 14 | _data = _array.toArray(); 15 | } 16 | 17 | MemoryStream::MemoryStream(size_t initialCapacity) : _array(initialCapacity), _length(0), _pos(0), _data(nullptr) 18 | { 19 | } 20 | 21 | size_t MemoryStream::read(void* buffer, size_t maxBytes) 22 | { 23 | if (_pos >= _length) 24 | return 0; 25 | 26 | if (_length - _pos < maxBytes) 27 | maxBytes = _length - _pos; 28 | 29 | // May be reading from either _data or _array. 30 | const byte_t* data = _data ? (const byte_t*) _data : _array.toArray(); 31 | Memory::copy(buffer, &data[_pos], maxBytes); 32 | _pos += maxBytes; 33 | return maxBytes; 34 | } 35 | 36 | size_t MemoryStream::write(const void* data, size_t bytes) 37 | { 38 | if (_data != nullptr) 39 | throw IoException("Cannot write to MemoryStream for existing byte array."); 40 | 41 | // Ensure we have capacity to write to. 42 | if (getCapacity() < _pos + bytes) 43 | _array.setLength(internal::getCapacityForLength(_pos + bytes)); 44 | 45 | _array.set(_pos, (const byte_t*) data, bytes); 46 | _pos += bytes; 47 | 48 | if (_pos > _length) 49 | _length = _pos; 50 | 51 | return bytes; 52 | } 53 | 54 | void MemoryStream::clear() 55 | { 56 | _pos = _length = 0; 57 | _array.clear(); 58 | _data = nullptr; 59 | } 60 | 61 | void MemoryStream::seek(size_t position) 62 | { 63 | if (position > _length) 64 | position = _length; 65 | 66 | _pos = position; 67 | } 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/io/common/udpsocket.cpp: -------------------------------------------------------------------------------- 1 | // Local Dependencies 2 | #include "../include/udpsocket.h" 3 | 4 | namespace native 5 | { 6 | namespace io 7 | { 8 | 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/io/include/istream.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_IO_ISTREAM_H_ 2 | #define _NATIVE_IO_ISTREAM_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/exception.h" 6 | 7 | namespace native 8 | { 9 | namespace io 10 | { 11 | /** 12 | Interface for raw streaming of bytes between endpoints. 13 | */ 14 | class IStream 15 | { 16 | public: 17 | /** Virtual destructor. */ 18 | virtual ~IStream() = default; 19 | 20 | /** 21 | Reads bytes from the stream into the supplied buffer/array. 22 | \param buffer The memory location to place the bytes received. 23 | \param maxBytes The maximum number of bytes to read. 24 | \return The number of bytes actually read. 25 | */ 26 | virtual size_t read(void* buffer, size_t maxBytes) = 0; 27 | 28 | /** 29 | Writes bytes of data to the stream. 30 | \param data The data to write to the stream. 31 | \param bytes The number of bytes to write. 32 | \return The number of bytes written. 33 | */ 34 | virtual size_t write(const void* data, size_t bytes) = 0; 35 | }; 36 | 37 | /** 38 | Exception thrown an an IO error occurs. 39 | */ 40 | class IoException : public Exception 41 | { 42 | public: 43 | IoException(const char* message = "An IO error occurred") : Exception(message) {} 44 | }; 45 | } 46 | } 47 | 48 | #endif // _NATIVE_IO_ISTREAM_H_ 49 | 50 | -------------------------------------------------------------------------------- /src/io/include/socket.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_IO_SOCKET_H_ 2 | #define _NATIVE_IO_SOCKET_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/exception.h" 6 | 7 | // Local Dependencies 8 | #include "networkaddress.h" 9 | 10 | namespace native 11 | { 12 | namespace io 13 | { 14 | /** 15 | The basis for network communication. Various subclasses may implement 16 | various networking protocols. 17 | */ 18 | class Socket 19 | { 20 | public: 21 | /** Destructor. */ 22 | virtual ~Socket() { close(); } 23 | 24 | /** 25 | Closes the Socket. It can no longer perform any IO operations. 26 | */ 27 | void close() noexcept; 28 | 29 | /** 30 | Tells whether the Socket is closed or not. 31 | \return true if closed, false if connected. 32 | */ 33 | bool isClosed() const noexcept; 34 | 35 | /** 36 | Gets the socket descriptor for this Socket. 37 | \return The socket descriptor. 38 | */ 39 | handle_t getHandle() const noexcept { return _handle; } 40 | 41 | protected: 42 | /** 43 | Constructor. Creates a Socket with the given protocol. 44 | \param protocol The IP protocol to apply. 45 | \param version The IP version to use. 46 | */ 47 | Socket(IpProtocol protocol, IpVersion version = IpVersion::Any); 48 | 49 | private: 50 | // Instance Variables 51 | handle_t _handle; 52 | }; 53 | 54 | /** Exception thrown on failed Socket operations. */ 55 | class SocketException : public Exception 56 | { 57 | public: 58 | SocketException(const char* message = "Socket error") : Exception(message) {} 59 | }; 60 | } 61 | } 62 | 63 | #endif // _NATIVE_IO_SOCKET_H_ 64 | 65 | -------------------------------------------------------------------------------- /src/io/include/tcpsocket.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_IO_TCP_SOCKET_H_ 2 | #define _NATIVE_IO_TCP_SOCKET_H_ 1 3 | 4 | // Local Dependencies 5 | #include "istream.h" 6 | #include "socket.h" 7 | 8 | namespace native 9 | { 10 | namespace io 11 | { 12 | /** 13 | An endpoint for reading and writing over a TCP/IP connection. 14 | */ 15 | class TcpSocket : public Socket, public IStream 16 | { 17 | public: 18 | /** 19 | Constructor. 20 | \param version IP version. 21 | */ 22 | TcpSocket(IpVersion version = IpVersion::Any); 23 | 24 | /** 25 | Reads available data from the socket. Partial reads are allowed. 26 | \param buffer Location to store retrieved data. 27 | \param maxBytes The maximum number of bytes to read. 28 | \return The number of bytes read. 29 | */ 30 | virtual size_t read(void* buffer, size_t maxBytes) override; 31 | 32 | /** 33 | Writes data to the socket. Partial writes are allowed. 34 | \param data The data to write. 35 | \param bytes The number of bytes to write. 36 | \return The number of bytes written. 37 | */ 38 | virtual size_t write(const void* data, size_t bytes) override; 39 | }; 40 | } 41 | } 42 | 43 | #endif // _NATIVE_IO_TCP_SOCKET_H_ 44 | 45 | -------------------------------------------------------------------------------- /src/io/include/udpsocket.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_IO_UDP_SOCKET_H_ 2 | #define _NATIVE_IO_UDP_SOCKET_H_ 1 3 | 4 | // Local Dependencies 5 | #include "socket.h" 6 | 7 | namespace native 8 | { 9 | namespace io 10 | { 11 | class UdpSocket : public Socket 12 | { 13 | }; 14 | } 15 | } 16 | 17 | #endif // _NATIVE_IO_UDP_SOCKET_H_ 18 | 19 | -------------------------------------------------------------------------------- /src/io/io.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | net 6 | 7 | 8 | net 9 | 10 | 11 | net 12 | 13 | 14 | 15 | net 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | net 25 | 26 | 27 | net 28 | 29 | 30 | net 31 | 32 | 33 | net 34 | 35 | 36 | 37 | 38 | 39 | {1708034e-1495-481f-a309-2677cf3fe7ca} 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/ui/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/ui/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${root_dir}/lib/${ANDROID_ABI}") 9 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 10 | 11 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 12 | 13 | ADD_LIBRARY(core STATIC IMPORTED) 14 | ADD_LIBRARY(jnipp STATIC IMPORTED) 15 | 16 | ADD_LIBRARY(ui SHARED ${sources}) 17 | 18 | SET_TARGET_PROPERTIES(core PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libcore.so") 19 | SET_TARGET_PROPERTIES(jnipp PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libjnipp.so") 20 | 21 | TARGET_LINK_LIBRARIES(ui core jnipp) 22 | -------------------------------------------------------------------------------- /src/ui/android/alerts.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../../lib/jnipp/jnipp.h" 3 | 4 | // Module Dependencies 5 | #include "../include/alerts.h" 6 | #include "../include/app.h" 7 | 8 | namespace native 9 | { 10 | namespace ui 11 | { 12 | void Alerts::messageBox(Component*, const String& message, const String& title) 13 | { 14 | messageBox(message, title); 15 | } 16 | 17 | void Alerts::messageBox(const String& message, const String& title) 18 | { 19 | jni::Class ViewExtensions("libnative/ui/ViewExtensions"); 20 | ViewExtensions.call("messageBox(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V", 21 | (jni::Object*) App::getAppHandle(), message.toArray(), title.toArray()); 22 | } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/ui/android/androidapp.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../../lib/jnipp/jnipp.h" 3 | 4 | // Module Dependencies 5 | #include "../include/app.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | void init(_JNIEnv* env, jni::jobject activity) 12 | { 13 | jni::init(env); 14 | 15 | App::setAppHandle(new jni::Object(activity)); 16 | } 17 | } 18 | } 19 | 20 | using namespace native::ui; 21 | 22 | extern "C" 23 | { 24 | void Java_libnative_ui_MainActivity_onDestroyApp(_JNIEnv*, jni::jobject) { 25 | delete native::ui::App::getInstance(); 26 | } 27 | 28 | bool Java_libnative_ui_MainActivity_onAction(_JNIEnv*, jni::jobject, int actionId) { 29 | Action* action = Action::fromId(actionId); 30 | 31 | if (action == nullptr) 32 | return false; 33 | 34 | action->emit(); 35 | return true; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/ui/android/bitmap.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../../lib/jnipp/jnipp.h" 3 | 4 | // Library Dependencies 5 | #include "../include/bitmap.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | Bitmap::BitmapHandle::BitmapHandle(handle_t handle) : handle(handle) 12 | { 13 | } 14 | 15 | Bitmap::BitmapHandle::~BitmapHandle() 16 | { 17 | delete (jni::Object*) handle; 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /src/ui/android/brush.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../../lib/jnipp/jnipp.h" 3 | 4 | // External Dependencies 5 | #include "../../core/include/exception.h" 6 | 7 | // Module Dependencies 8 | #include "../include/brush.h" 9 | 10 | namespace native 11 | { 12 | namespace ui 13 | { 14 | Brush::BrushHandle::~BrushHandle() 15 | { 16 | delete (jni::Object*) handle; 17 | } 18 | 19 | Brush::Brush(const Color& color) : _shared(nullptr) 20 | { 21 | jni::Object paint = jni::Class("android/graphics/Paint").newInstance(); 22 | 23 | paint.call("setColor", int(color.toArgb())); 24 | 25 | _shared->handle = new jni::Object(paint); 26 | } 27 | 28 | Color Brush::getPrimaryColor() const 29 | { 30 | jni::Object* paint = (jni::Object*) getHandle(); 31 | 32 | return Color::fromArgb(paint->call("getColor")); 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/ui/android/componentadapterproperties.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_COMPONENT_ADAPTER_PROPERTIES_H_ 2 | #define _NATIVE_UI_COMPONENT_ADAPTER_PROPERTIES_H_ 1 3 | 4 | namespace native 5 | { 6 | namespace ui 7 | { 8 | // Forward Declarations 9 | class Component; 10 | 11 | /** 12 | Any properties required to create different types of Android 13 | Views. 14 | */ 15 | struct ComponentAdapterProperties 16 | { 17 | Component* component; 18 | 19 | const char* className; 20 | }; 21 | } 22 | } 23 | 24 | #endif // _NATIVE_UI_COMPONENT_ADAPTER_PROPERTIES_H_ 25 | 26 | -------------------------------------------------------------------------------- /src/ui/android/componentevent.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_COMPONENT_EVENT_H_ 2 | #define _NATIVE_UI_COMPONENT_EVENT_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/types.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | Details of a native event for an Android Component. 13 | */ 14 | struct ComponentEvent 15 | { 16 | enum EventId { 17 | onInput, 18 | onPaint, 19 | onSize 20 | }; 21 | 22 | EventId id; 23 | handle_t arg; 24 | }; 25 | } 26 | } 27 | 28 | #endif // _NATIVE_UI_COMPONENT_EVENT_H_ 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/ui/android/eventqueue.cpp: -------------------------------------------------------------------------------- 1 | // External Depdendencies 2 | #include "../../../lib/jnipp/jnipp.h" 3 | 4 | // Module Dependencies 5 | #include "../include/app.h" 6 | #include "../include/eventqueue.h" 7 | 8 | namespace native 9 | { 10 | namespace ui 11 | { 12 | // Static Variable Initialisations 13 | thread_local int EventQueue::_exitCode = 0; 14 | 15 | bool EventQueue::handleEvent(bool block) 16 | { 17 | throw NotImplementedException(); 18 | } 19 | 20 | void EventQueue::quitWithCode(int exitCode) 21 | { 22 | jni::Object* activity = (jni::Object*) App::getAppHandle(); 23 | 24 | _exitCode = exitCode; 25 | activity->call("finish"); 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/Button.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.MotionEvent; 6 | 7 | public class Button extends android.widget.Button implements INativeComponent { 8 | public Button(Context context) { 9 | super(context); 10 | } 11 | 12 | @Override 13 | public boolean onTouchEvent(MotionEvent event) { 14 | switch (event.getAction()) 15 | { 16 | case MotionEvent.ACTION_DOWN: 17 | case MotionEvent.ACTION_UP: 18 | case MotionEvent.ACTION_MOVE: 19 | return ViewExtensions.onInput(this, event); 20 | } 21 | 22 | return super.onTouchEvent(event); 23 | } 24 | 25 | @Override 26 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 27 | 28 | @Override 29 | public void onSizeChanged(int w, int h, int oldW, int oldH) { ViewExtensions.onSize(this, w, h); } 30 | } 31 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/Checkbox.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.MotionEvent; 6 | 7 | public class Checkbox extends android.widget.CheckBox implements INativeComponent { 8 | public Checkbox(Context context) { 9 | super(context); 10 | } 11 | 12 | @Override 13 | public boolean onTouchEvent(MotionEvent event) { 14 | switch (event.getAction()) 15 | { 16 | case MotionEvent.ACTION_DOWN: 17 | case MotionEvent.ACTION_UP: 18 | case MotionEvent.ACTION_MOVE: 19 | return ViewExtensions.onInput(this, event); 20 | } 21 | 22 | return super.onTouchEvent(event); 23 | } 24 | 25 | @Override 26 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 27 | 28 | @Override 29 | public void onSizeChanged(int w, int h, int oldW, int oldH) { ViewExtensions.onSize(this, w, h); } 30 | } 31 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/INativeComponent.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | public interface INativeComponent { 4 | } 5 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/InputComponent.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.MotionEvent; 6 | 7 | public class InputComponent extends android.widget.EditText implements INativeComponent { 8 | public InputComponent(Context context) { 9 | super(context); 10 | 11 | setMaxLines(1); 12 | } 13 | 14 | @Override 15 | public boolean onTouchEvent(MotionEvent event) { 16 | switch (event.getAction()) 17 | { 18 | case MotionEvent.ACTION_DOWN: 19 | case MotionEvent.ACTION_UP: 20 | case MotionEvent.ACTION_MOVE: 21 | return ViewExtensions.onInput(this, event); 22 | } 23 | 24 | return super.onTouchEvent(event); 25 | } 26 | 27 | @Override 28 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 29 | 30 | @Override 31 | public void onSizeChanged(int w, int h, int oldW, int oldH) { ViewExtensions.onSize(this, w, h); } 32 | } 33 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/NativeRunnable.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | public class NativeRunnable implements Runnable { 4 | private long _funcPtr; 5 | 6 | public NativeRunnable(long funcPtr) { 7 | this._funcPtr = funcPtr; 8 | } 9 | 10 | @Override 11 | public void run() { onRun(_funcPtr); } 12 | 13 | private native void onRun(long funcPtr); 14 | } 15 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/NumberPicker.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.MotionEvent; 6 | 7 | public class NumberPicker extends android.widget.NumberPicker implements INativeComponent { 8 | public NumberPicker(Context context) { 9 | super(context); 10 | 11 | setWrapSelectorWheel(false); 12 | 13 | // Set default min/max values. 14 | setMaxValue(Integer.MAX_VALUE); 15 | } 16 | 17 | @Override 18 | public boolean onTouchEvent(MotionEvent event) { 19 | switch (event.getAction()) 20 | { 21 | case MotionEvent.ACTION_DOWN: 22 | case MotionEvent.ACTION_UP: 23 | case MotionEvent.ACTION_MOVE: 24 | return ViewExtensions.onInput(this, event); 25 | } 26 | 27 | return super.onTouchEvent(event); 28 | } 29 | 30 | @Override 31 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 32 | 33 | @Override 34 | public void onSizeChanged(int w, int h, int oldW, int oldH) { 35 | super.onSizeChanged(w, h, oldW, oldH); 36 | ViewExtensions.onSize(this, w, h); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/ProgressBar.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.MotionEvent; 6 | 7 | public class ProgressBar extends android.widget.ProgressBar implements INativeComponent { 8 | public ProgressBar(Context context) { 9 | super(context, null, android.R.attr.progressBarStyleHorizontal); 10 | } 11 | 12 | @Override 13 | public boolean onTouchEvent(MotionEvent event) { 14 | switch (event.getAction()) 15 | { 16 | case MotionEvent.ACTION_DOWN: 17 | case MotionEvent.ACTION_UP: 18 | case MotionEvent.ACTION_MOVE: 19 | return ViewExtensions.onInput(this, event); 20 | } 21 | 22 | return super.onTouchEvent(event); 23 | } 24 | 25 | @Override 26 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 27 | 28 | @Override 29 | public void onSizeChanged(int w, int h, int oldW, int oldH) { 30 | super.onSizeChanged(w, h, oldW, oldH); 31 | ViewExtensions.onSize(this, w, h); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/RadioButton.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.MotionEvent; 6 | 7 | public class RadioButton extends android.widget.RadioButton implements INativeComponent { 8 | public RadioButton(Context context) { 9 | super(context); 10 | } 11 | 12 | @Override 13 | public boolean onTouchEvent(MotionEvent event) { 14 | switch (event.getAction()) 15 | { 16 | case MotionEvent.ACTION_DOWN: 17 | case MotionEvent.ACTION_UP: 18 | case MotionEvent.ACTION_MOVE: 19 | return ViewExtensions.onInput(this, event); 20 | } 21 | 22 | return super.onTouchEvent(event); 23 | } 24 | 25 | @Override 26 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 27 | 28 | @Override 29 | public void onSizeChanged(int w, int h, int oldW, int oldH) { ViewExtensions.onSize(this, w, h); } 30 | } 31 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/ScrollView.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.MotionEvent; 6 | import android.view.View; 7 | import android.widget.RelativeLayout; 8 | 9 | public class ScrollView extends android.widget.ScrollView implements INativeComponent { 10 | private RelativeLayout _layout; 11 | 12 | public ScrollView(Context context) { 13 | super(context); 14 | 15 | _layout = new RelativeLayout(context); 16 | super.addView(_layout); 17 | } 18 | 19 | @Override 20 | public void addView(View child) 21 | { 22 | _layout.addView(child); 23 | } 24 | 25 | @Override 26 | public boolean onTouchEvent(MotionEvent event) { 27 | switch (event.getAction()) 28 | { 29 | case MotionEvent.ACTION_DOWN: 30 | case MotionEvent.ACTION_UP: 31 | case MotionEvent.ACTION_MOVE: 32 | return ViewExtensions.onInput(this, event); 33 | } 34 | 35 | return super.onTouchEvent(event); 36 | } 37 | 38 | @Override 39 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 40 | 41 | @Override 42 | public void onSizeChanged(int w, int h, int oldW, int oldH) { 43 | super.onSizeChanged(w, h, oldW, oldH); 44 | ViewExtensions.onSize(this, w, h); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/TextArea.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.Gravity; 6 | import android.view.MotionEvent; 7 | 8 | public class TextArea extends android.widget.EditText implements INativeComponent { 9 | public TextArea(Context context) { 10 | super(context); 11 | 12 | setGravity(Gravity.TOP + Gravity.LEFT); 13 | } 14 | 15 | @Override 16 | public boolean onTouchEvent(MotionEvent event) { 17 | switch (event.getAction()) 18 | { 19 | case MotionEvent.ACTION_DOWN: 20 | case MotionEvent.ACTION_UP: 21 | case MotionEvent.ACTION_MOVE: 22 | return ViewExtensions.onInput(this, event); 23 | } 24 | 25 | return super.onTouchEvent(event); 26 | } 27 | 28 | @Override 29 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 30 | 31 | @Override 32 | public void onSizeChanged(int w, int h, int oldW, int oldH) { ViewExtensions.onSize(this, w, h); } 33 | } 34 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/TextComponent.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.MotionEvent; 6 | 7 | public class TextComponent extends android.widget.TextView implements INativeComponent { 8 | public TextComponent(Context context) { 9 | super(context); 10 | } 11 | 12 | @Override 13 | public boolean onTouchEvent(MotionEvent event) { 14 | switch (event.getAction()) 15 | { 16 | case MotionEvent.ACTION_DOWN: 17 | case MotionEvent.ACTION_UP: 18 | case MotionEvent.ACTION_MOVE: 19 | return ViewExtensions.onInput(this, event); 20 | } 21 | 22 | return super.onTouchEvent(event); 23 | } 24 | 25 | @Override 26 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 27 | 28 | @Override 29 | public void onSizeChanged(int w, int h, int oldW, int oldH) { ViewExtensions.onSize(this, w, h); } 30 | } 31 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/WebView.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.view.MotionEvent; 6 | import android.webkit.WebViewClient; 7 | 8 | public class WebView extends android.webkit.WebView implements INativeComponent { 9 | public WebView(Context context) { 10 | super(context); 11 | 12 | setWebViewClient(new WebViewClient()); 13 | getSettings().setJavaScriptEnabled(true); 14 | } 15 | 16 | @Override 17 | public boolean onTouchEvent(MotionEvent event) { 18 | switch (event.getAction()) 19 | { 20 | case MotionEvent.ACTION_DOWN: 21 | case MotionEvent.ACTION_UP: 22 | case MotionEvent.ACTION_MOVE: 23 | return ViewExtensions.onInput(this, event); 24 | } 25 | 26 | return super.onTouchEvent(event); 27 | } 28 | 29 | @Override 30 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 31 | 32 | @Override 33 | public void onSizeChanged(int w, int h, int oldW, int oldH) { 34 | super.onSizeChanged(w, h, oldW, oldH); 35 | ViewExtensions.onSize(this, w, h); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/ui/android/java/libnative/ui/Window.java: -------------------------------------------------------------------------------- 1 | package libnative.ui; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.graphics.Canvas; 6 | 7 | public class Window extends android.widget.RelativeLayout implements INativeComponent { 8 | public Window(Context context) { 9 | super(context); 10 | 11 | setWillNotDraw(false); 12 | 13 | // Window is the main view. 14 | if (context instanceof Activity) 15 | ((Activity) context).setContentView(this); 16 | } 17 | 18 | @Override 19 | protected void onDraw(Canvas canvas) { ViewExtensions.onPaint(this, canvas); } 20 | 21 | @Override 22 | public void onSizeChanged(int w, int h, int oldW, int oldH) { 23 | ViewExtensions.onSize(this, w, h); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/ui/android/lineargradientbrush.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../../lib/jnipp/jnipp.h" 3 | 4 | // External Dependencies 5 | #include "../../core/include/exception.h" 6 | 7 | // Module Dependencies 8 | #include "../include/app.h" 9 | #include "../include/lineargradientbrush.h" 10 | 11 | namespace native 12 | { 13 | namespace ui 14 | { 15 | static handle_t CreatePaint(Point p0, Point p1, Color c0, Color c1) 16 | { 17 | auto constructor = jni::Class("android/graphics/LinearGradient") 18 | .getConstructor("(FFFFIILandroid/graphics/Shader$TileMode;)V"); 19 | 20 | jni::Object shader = jni::Class("android/graphics/LinearGradient").newInstance( 21 | constructor, float(p0.x), float(p0.y), float(p1.x) * App::getDisplayScale(), float(p1.y) * App::getDisplayScale(), 22 | int(c0.toArgb()), int(c1.toArgb()), jni::Enum("android/graphics/Shader$TileMode").get("REPEAT") 23 | ); 24 | 25 | jni::Object paint = jni::Class("android/graphics/Paint").newInstance(); 26 | 27 | paint.call("setColor", int(c0.toArgb())); 28 | paint.call("setShader(Landroid/graphics/Shader;)Landroid/graphics/Shader;", shader); 29 | 30 | return (handle_t) new jni::Object(paint); 31 | } 32 | 33 | LinearGradientBrush::LinearGradientBrush(Point p0, Point p1, Color c0, Color c1) : Brush(CreatePaint(p0, p1, c0, c1)) 34 | { 35 | 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/ui/android/pen.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../../lib/jnipp/jnipp.h" 3 | 4 | // Module Dependencies 5 | #include "../include/app.h" 6 | #include "../include/pen.h" 7 | 8 | namespace native 9 | { 10 | namespace ui 11 | { 12 | Pen::Pen(const Color& color, float thickness) : _shared(nullptr), _thickness(thickness), _color(color) 13 | { 14 | jni::Object paint = jni::Class("android/graphics/Paint").newInstance(); 15 | 16 | paint.call("setColor", int(color.toArgb())); 17 | paint.call("setStrokeWidth", thickness * App::getDisplayScale()); 18 | paint.call("setStyle(Landroid/graphics/Paint$Style;)V", jni::Enum("android/graphics/Paint$Style").get("STROKE")); 19 | 20 | _shared->handle = new jni::Object(paint); 21 | } 22 | 23 | Pen::PenHandle::~PenHandle() 24 | { 25 | delete (jni::Object*) handle; 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/ui/android/webview.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../../lib/jnipp/jnipp.h" 3 | 4 | // Module Dependencies 5 | #include "componentadapterproperties.h" 6 | #include "../include/componentadapter.h" 7 | #include "../include/webview.h" 8 | 9 | namespace native 10 | { 11 | namespace ui 12 | { 13 | WebView::WebView() : Component(new WebViewAdapter(this)) 14 | { 15 | setAlignment(Align::Fill); 16 | } 17 | 18 | void WebView::navigate(const String& url) 19 | { 20 | WebViewAdapter* adapter = (WebViewAdapter*) getAdapter(); 21 | 22 | adapter->navigate(url); 23 | } 24 | 25 | void WebView::goBack() 26 | { 27 | WebViewAdapter* adapter = (WebViewAdapter*) getAdapter(); 28 | 29 | adapter->goBack(); 30 | } 31 | 32 | void WebView::goForward() 33 | { 34 | WebViewAdapter* adapter = (WebViewAdapter*) getAdapter(); 35 | 36 | adapter->goForward(); 37 | } 38 | 39 | void WebView::onSize(const Size& size) 40 | { 41 | Component::onSize(size); 42 | } 43 | 44 | /* 45 | WebViewAdapter Functions 46 | */ 47 | 48 | WebViewAdapter::WebViewAdapter(WebView* view) : ComponentAdapter({ view, "libnative/ui/WebView" }) 49 | { 50 | } 51 | 52 | WebViewAdapter::~WebViewAdapter() 53 | { 54 | } 55 | 56 | void WebViewAdapter::navigate(const String& url) 57 | { 58 | ((jni::Object*) getHandle())->call("loadUrl", url.toArray()); 59 | } 60 | 61 | void WebViewAdapter::goBack() 62 | { 63 | ((jni::Object*) getHandle())->call("goBack"); 64 | } 65 | 66 | void WebViewAdapter::goForward() 67 | { 68 | ((jni::Object*) getHandle())->call("goForward"); 69 | } 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/ui/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | minSdkVersion 15 9 | targetSdkVersion 26 10 | } 11 | 12 | buildTypes { 13 | release { 14 | minifyEnabled = false 15 | proguardFiles getDefaultProguardFile('proguard-android.txt') 16 | } 17 | } 18 | 19 | sourceSets { 20 | main { 21 | java.srcDir 'android' 22 | jni.srcDir 'android/java' 23 | manifest.srcFile 'android/AndroidManifest.xml' 24 | } 25 | } 26 | 27 | externalNativeBuild { 28 | cmake { 29 | path 'android/CMakeLists.txt' 30 | } 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation project(':core') 36 | implementation project(':jnipp') 37 | } 38 | -------------------------------------------------------------------------------- /src/ui/common/action.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../core/include/map.h" 3 | #include "../../core/include/spinlock.h" 4 | 5 | // Module Dependencies 6 | #include "../include/action.h" 7 | 8 | namespace native 9 | { 10 | namespace ui 11 | { 12 | static Map _actionMap; 13 | static int32_t _nextId = 100; 14 | static SpinLock _lock; 15 | 16 | ActionListener::~ActionListener() 17 | { 18 | // Remove from Action's subscriber lists. 19 | for (auto action : _actions) 20 | action->_listeners.remove(this); 21 | } 22 | 23 | Action::Action() 24 | { 25 | _lock.lock(); 26 | _actionMap.add(_id = ++_nextId, this); 27 | _lock.release(); 28 | } 29 | 30 | Action::~Action() 31 | { 32 | _lock.lock(); 33 | _actionMap.remove(_id); 34 | _lock.release(); 35 | 36 | // Trigger the callbacks in the ActionHosts. 37 | for (auto listener : _listeners) 38 | { 39 | listener->_actions.remove(this); 40 | listener->onActionDestroyed(this); 41 | } 42 | } 43 | 44 | void Action::setText(const String& text) 45 | { 46 | _text = text; 47 | 48 | // Trigger the callbacks in the listeners. 49 | for (auto listener : _listeners) 50 | listener->onActionUpdated(this); 51 | } 52 | 53 | void Action::addListener(ActionListener* listener) 54 | { 55 | if (listener) 56 | { 57 | _listeners.add(listener); 58 | listener->_actions.add(this); 59 | } 60 | } 61 | 62 | Action* Action::fromId(int32_t id) 63 | { 64 | Action* action = nullptr; 65 | 66 | _lock.lock(); 67 | if (_actionMap.containsKey(id)) 68 | action = _actionMap[id]; 69 | _lock.release(); 70 | 71 | return action; 72 | } 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /src/ui/common/button.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/componentadapter.h" 3 | #include "../include/button.h" 4 | 5 | namespace native 6 | { 7 | namespace ui 8 | { 9 | Button::Button() : TextComponent(new ButtonAdapter(this)) 10 | { 11 | } 12 | 13 | Button::Button(const String& text) : TextComponent(new ButtonAdapter(this)) 14 | { 15 | setText(text); 16 | } 17 | 18 | Size Button::getPreferredSize() const 19 | { 20 | Size size = TextComponent::getPreferredSize(); 21 | 22 | #ifdef NATIVE_FORM_MOBILE 23 | // Mobile needs bigger buttons with plenty of padding for fat fingers. 24 | size.width += coord_t(size.height * 2); 25 | size.height += coord_t(size.height * 1.5); 26 | #else 27 | size.width += coord_t(size.height); 28 | size.height += coord_t(size.height * 0.666667); 29 | #endif 30 | 31 | return size; 32 | } 33 | 34 | void Button::onPaint(Canvas& canvas) 35 | { 36 | Component::onPaint(canvas); 37 | } 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/ui/common/checkbox.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/componentadapter.h" 3 | #include "../include/checkbox.h" 4 | 5 | namespace native 6 | { 7 | namespace ui 8 | { 9 | Checkbox::Checkbox() : TextComponent(new CheckboxAdapter(this)), _checked(false) 10 | { 11 | } 12 | 13 | void Checkbox::setChecked(bool checked) 14 | { 15 | ((CheckboxAdapter*) getAdapter())->setChecked(checked); 16 | } 17 | 18 | Size Checkbox::getPreferredSize() const 19 | { 20 | Size size = TextComponent::getPreferredSize(); 21 | 22 | #ifdef NATIVE_FORM_MOBILE 23 | // TODO: Proper checkbox size calculation. 24 | return { size.width + 40, size.height + 5 }; 25 | #else 26 | // TODO: Proper checkbox size calculation. 27 | return { size.width + 10, size.height }; 28 | #endif 29 | } 30 | 31 | void Checkbox::onPaint(Canvas& canvas) 32 | { 33 | Component::onPaint(canvas); 34 | } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/ui/common/inputcomponent.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/app.h" 3 | #include "../include/componentadapter.h" 4 | #include "../include/inputcomponent.h" 5 | 6 | namespace native 7 | { 8 | namespace ui 9 | { 10 | InputComponent::InputComponent() : TextComponent(new InputAdapter(this)) 11 | { 12 | #ifdef NATIVE_PLATFORM_WIN32 13 | static const Pen BORDER_COLOR = Color(0x80, 0x80, 0x80); 14 | 15 | setBorder(BORDER_COLOR); 16 | #endif // NATIVE_PLATFORM_WIN32 17 | } 18 | 19 | InputComponent::InputComponent(InputAdapter* adapter) : TextComponent(adapter) 20 | { 21 | #ifdef NATIVE_PLATFORM_WIN32 22 | static const Pen BORDER_COLOR = Color(0x80, 0x80, 0x80); 23 | 24 | setBorder(BORDER_COLOR); 25 | #endif // NATIVE_PLATFORM_WIN32 26 | } 27 | 28 | Size InputComponent::getPreferredSize() const 29 | { 30 | String text = getText(); 31 | 32 | Size size = getFont().measureText(text.getLength() ? text : "Thank you very much"); 33 | 34 | #ifdef NATIVE_FORM_MOBILE 35 | size.width += coord_t(size.height * 2); 36 | size.height += coord_t(size.height * 1.5); 37 | #else 38 | size.width += coord_t(1 * App::getDisplayScale()); 39 | size.height += coord_t(1 * App::getDisplayScale()); 40 | #endif 41 | 42 | return size; 43 | } 44 | 45 | void InputComponent::onPaint(Canvas& canvas) 46 | { 47 | // Do default system painting. 48 | Component::onPaint(canvas); 49 | } 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/ui/common/label.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/label.h" 3 | 4 | namespace native 5 | { 6 | namespace ui 7 | { 8 | Label::Label() 9 | { 10 | } 11 | 12 | Label::Label(const String& text) : TextComponent(text) 13 | { 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/ui/common/numberpicker.cpp: -------------------------------------------------------------------------------- 1 | // Local Dependencies 2 | #include "../include/componentadapter.h" 3 | #include "../include/numberpicker.h" 4 | 5 | namespace native 6 | { 7 | namespace ui 8 | { 9 | NumberPicker::NumberPicker() : Component(new NumberPickerAdapter(this)) 10 | { 11 | #ifdef NATIVE_PLATFORM_WIN32 12 | static const Pen BORDER_COLOR = Color(0x80, 0x80, 0x80); 13 | 14 | setBorder(BORDER_COLOR); 15 | #endif // NATIVE_PLATFORM_WIN32 16 | } 17 | 18 | void NumberPicker::setValue(int value) 19 | { 20 | ((NumberPickerAdapter*) getAdapter())->setValue(value); 21 | } 22 | 23 | int NumberPicker::getValue() const 24 | { 25 | return ((NumberPickerAdapter*) getAdapter())->getValue(); 26 | } 27 | 28 | void NumberPicker::setRange(int min, int max) 29 | { 30 | ((NumberPickerAdapter*)getAdapter())->setRange(min, max); 31 | } 32 | 33 | int NumberPicker::getMinimum() const 34 | { 35 | return ((NumberPickerAdapter*) getAdapter())->getMinimum(); 36 | } 37 | 38 | int NumberPicker::getMaximum() const 39 | { 40 | return ((NumberPickerAdapter*) getAdapter())->getMaximum(); 41 | } 42 | 43 | Size NumberPicker::getPreferredSize() const 44 | { 45 | #ifdef NATIVE_PLATFORM_ANDROID 46 | // TODO: Calculate this. 47 | return { 100, 100 }; 48 | #else 49 | // TODO: Calculate this. 50 | return { 60, 25 }; 51 | #endif 52 | 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /src/ui/common/point.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../core/include/math.h" 3 | 4 | // Module Dependencies 5 | #include "../include/point.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | Point::Point(coord_t x, coord_t y) noexcept : x(x), y(y) 12 | { 13 | } 14 | 15 | void Point::set(coord_t x, coord_t y) noexcept 16 | { 17 | this->x = x; 18 | this->y = y; 19 | } 20 | 21 | coord_t Point::distanceFrom(Point other) noexcept 22 | { 23 | return Math::squareRoot((Math::abs(x - other.x) * Math::abs(x - other.x)) + (Math::abs(y - other.y) * Math::abs(y - other.y))); 24 | } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/ui/common/progressbar.cpp: -------------------------------------------------------------------------------- 1 | // Local Dependencies 2 | #include "../include/app.h" 3 | #include "../include/componentadapter.h" 4 | #include "../include/progressbar.h" 5 | 6 | namespace native 7 | { 8 | namespace ui 9 | { 10 | ProgressBar::ProgressBar() : Component(new ProgressBarAdapter(this)), _min(0), _max(100), _progress(0) 11 | { 12 | setMargins(coord_t(2 * App::getDisplayScale()), 0, coord_t(2 * App::getDisplayScale()), 0); 13 | } 14 | 15 | void ProgressBar::setRange(int min, int max) 16 | { 17 | _min = min; 18 | _max = max; 19 | 20 | ((ProgressBarAdapter*) getAdapter())->setMax(max - min); 21 | } 22 | 23 | void ProgressBar::setProgress(int progress) 24 | { 25 | _progress = progress; 26 | 27 | ((ProgressBarAdapter*) getAdapter())->setProgress(progress - _min); 28 | } 29 | 30 | Size ProgressBar::getPreferredSize() const 31 | { 32 | #ifdef NATIVE_FORM_MOBILE 33 | return { coord_t(100 * App::getDisplayScale()), coord_t(10 * App::getDisplayScale()) }; 34 | #else 35 | return { coord_t(160 * App::getDisplayScale()), coord_t(15 * App::getDisplayScale()) }; 36 | #endif // NATIVE_FORM_* 37 | } 38 | 39 | void ProgressBar::onSize(const Size& size) 40 | { 41 | #ifdef NATIVE_PLATFORM_WIN32 42 | // Get around an "order of calls" issue with Windows 43 | setProgress(_progress); 44 | #endif 45 | 46 | Component::onSize(size); 47 | } 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/ui/common/scrollview.cpp: -------------------------------------------------------------------------------- 1 | // Local Dependencies 2 | #include "../include/componentadapter.h" 3 | #include "../include/scrollview.h" 4 | 5 | namespace native 6 | { 7 | namespace ui 8 | { 9 | ScrollView::ScrollView() : LayoutComponent(new ScrollViewAdapter(this)) 10 | { 11 | } 12 | 13 | void ScrollView::onSize(const Size& size) 14 | { 15 | for (auto child : getChildren()) 16 | child->allocateArea(child->getPreferredSize()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/ui/common/size.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include "../../core/include/math.h" 3 | 4 | // Module Dependencies 5 | #include "../include/size.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | Size::Size() noexcept : width(0), height(0) 12 | { 13 | } 14 | 15 | Size::Size(coord_t width, coord_t height) noexcept : width(width), height(height) 16 | { 17 | } 18 | 19 | void Size::set(coord_t width, coord_t height) noexcept 20 | { 21 | this->width = width; 22 | this->height = height; 23 | } 24 | 25 | Size Size::combine(const Size& other) const noexcept 26 | { 27 | return { Math::max(width, other.width), Math::max(height, other.height) }; 28 | } 29 | 30 | Size Size::inflate(coord_t hamount, coord_t vamount) const noexcept 31 | { 32 | return { width + hamount, height + vamount }; 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/ui/common/textarea.cpp: -------------------------------------------------------------------------------- 1 | // Local Dependencies 2 | #include "../include/app.h" 3 | #include "../include/componentadapter.h" 4 | #include "../include/textarea.h" 5 | 6 | namespace native 7 | { 8 | namespace ui 9 | { 10 | TextArea::TextArea() : InputComponent(new TextAreaAdapter(this)) 11 | { 12 | } 13 | 14 | void TextArea::setScrollBars(bool horizontal, bool vertical) 15 | { 16 | TextAreaAdapter* adapter = (TextAreaAdapter*) getAdapter(); 17 | 18 | adapter->setScrollBars(horizontal, vertical); 19 | } 20 | 21 | Size TextArea::getPreferredSize() const 22 | { 23 | Size size = InputComponent::getPreferredSize(); 24 | 25 | return { coord_t(160 * App::getDisplayScale()), size.height * 5 }; 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/ui/common/textcomponent.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/app.h" 3 | #include "../include/canvas.h" 4 | #include "../include/componentadapter.h" 5 | #include "../include/textcomponent.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | TextComponent::TextComponent() : Component(new TextComponentAdapter(this)) 12 | { 13 | setFont(Font::getDefault()); 14 | setMargins(coord_t(2 * App::getDisplayScale()), 0, coord_t(2 * App::getDisplayScale()), 0); 15 | } 16 | 17 | TextComponent::TextComponent(const String& text) : Component(new TextComponentAdapter(this)) 18 | { 19 | setFont(Font::getDefault()); 20 | setText(text); 21 | setMargins(coord_t(2 * App::getDisplayScale()), 0, coord_t(2 * App::getDisplayScale()), 0); 22 | } 23 | 24 | TextComponent::TextComponent(IComponentAdapter* adapter) : Component(adapter) 25 | { 26 | setFont(Font::getDefault()); 27 | setMargins(coord_t(2 * App::getDisplayScale()), 0, coord_t(2 * App::getDisplayScale()), 0); 28 | } 29 | 30 | void TextComponent::setText(const String& text) 31 | { 32 | IComponentAdapter* adapter = getAdapter(); 33 | 34 | if (adapter) 35 | adapter->setText(text); 36 | 37 | _text = text; 38 | } 39 | 40 | void TextComponent::setFont(const Font& font) 41 | { 42 | IComponentAdapter* adapter = getAdapter(); 43 | 44 | if (adapter) 45 | adapter->setFont(font); 46 | 47 | _font = font; 48 | } 49 | 50 | Size TextComponent::getPreferredSize() const 51 | { 52 | return getFont().measureText(getText()); 53 | } 54 | 55 | void TextComponent::onPaint(Canvas& canvas) 56 | { 57 | // Paint the background... 58 | canvas.fillRectangle(getContentArea().getSize(), getBackground()); 59 | 60 | // Paint the text. 61 | canvas.drawText(getText(), getFont()); 62 | } 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/ui/common/window.cpp: -------------------------------------------------------------------------------- 1 | // Module Dependencies 2 | #include "../include/componentadapter.h" 3 | #include "../include/window.h" 4 | 5 | namespace native 6 | { 7 | namespace ui 8 | { 9 | Window::Window() : LayoutComponent(new WindowAdapter(this)) 10 | { 11 | setArea(getAdapter()->getArea()); 12 | setBackground(Color(0xFF, 0xFF, 0xFF)); 13 | } 14 | 15 | Window::Window(IComponentAdapter* adapter) : LayoutComponent(adapter) 16 | { 17 | setBackground(Color(0xFF, 0xFF, 0xFF)); 18 | } 19 | 20 | void Window::setTitle(const String& title) 21 | { 22 | IComponentAdapter* adapter = getAdapter(); 23 | 24 | if (adapter) 25 | adapter->setText(title); 26 | 27 | _title = title; 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/ui/include/alerts.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_DIALOGS_H_ 2 | #define _NATIVE_UI_DIALOGS_H_ 1 3 | 4 | // Module Dependencies 5 | #include "component.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | A set of predefined dialog popups for capturing and displaying common 13 | bits of information in an application. 14 | */ 15 | class Alerts 16 | { 17 | public: 18 | /** 19 | Displays a message box over the given Component, with a message 20 | and a title, along with an OK button to dismiss the message. 21 | \param owner The owner Component to display over. 22 | \param message The message to display. 23 | \param title The title at the top of the message box. 24 | */ 25 | static void messageBox(Component* owner, const String& message, const String& title); 26 | static void messageBox(Component& owner, const String& message, const String& title) { messageBox(&owner, message, title); } 27 | 28 | /** 29 | Displays a message box with the given message and title, along 30 | with an OK button to dismiss the message. 31 | \param message The message to display. 32 | \param title The title at the top of the message box. 33 | */ 34 | static void messageBox(const String& message, const String& title); 35 | }; 36 | } 37 | } 38 | 39 | #endif // _NATIVE_UI_DIALOGS_H_ 40 | 41 | -------------------------------------------------------------------------------- /src/ui/include/bitmap.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_BITMAP_H_ 2 | #define _NATIVE_UI_BITMAP_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/shared.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | Bitmap is an off-screen image representation. Bitmap is implemented as 13 | an underlying platform construct, allowing it to work well directly with 14 | the system's display drivers. 15 | */ 16 | class Bitmap 17 | { 18 | public: 19 | /** Create an invalid Bitmap handle. */ 20 | Bitmap() : _shared(nullptr) {} 21 | 22 | /** 23 | Gets the system resource handle. 24 | \return The system resource handle. 25 | */ 26 | handle_t getHandle() const noexcept { return _shared->handle; } 27 | 28 | private: 29 | /** Self-destroying Bitmap handle. */ 30 | struct BitmapHandle 31 | { 32 | BitmapHandle(handle_t handle); 33 | ~BitmapHandle(); 34 | 35 | handle_t handle; 36 | }; 37 | 38 | // Instance Variables 39 | Shared _shared; 40 | }; 41 | } 42 | } 43 | 44 | #endif // _NATIVE_UI_BITMAP_H_ 45 | 46 | -------------------------------------------------------------------------------- /src/ui/include/brush.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_BRUSH_H_ 2 | #define _NATIVE_UI_BRUSH_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/shared.h" 6 | 7 | // Module Dependencies 8 | #include "color.h" 9 | 10 | namespace native 11 | { 12 | namespace ui 13 | { 14 | /** 15 | A Brush is used to fill paint a region. 16 | */ 17 | class Brush 18 | { 19 | public: 20 | /** Create an invalid Brush handle. */ 21 | Brush() : _shared(nullptr) {} 22 | 23 | /** 24 | Creates a Brush which is a solid single color. 25 | \param color The color of the brush. 26 | */ 27 | Brush(const Color& color); 28 | 29 | /** 30 | Gets the main (primary) color for this brush. 31 | \return The main color. 32 | */ 33 | Color getPrimaryColor() const; 34 | 35 | /** 36 | Gets the system resource handle. 37 | \return The system resource handle. 38 | */ 39 | handle_t getHandle() const noexcept { return _shared->handle; } 40 | 41 | protected: 42 | /** 43 | Creates a Brush with the given system handle. Good for subclasses 44 | to instantiate with their own logical brush. 45 | \param handle The system handle. 46 | */ 47 | Brush(handle_t handle) : _shared(handle) {} 48 | 49 | private: 50 | /** Self-destroying Brush handle. */ 51 | struct BrushHandle 52 | { 53 | // Lifecycle Functions 54 | BrushHandle(handle_t handle) : handle(handle) {} 55 | ~BrushHandle(); 56 | 57 | // Instance Varaibles 58 | handle_t handle; 59 | }; 60 | 61 | // Instance Variables 62 | Shared _shared; 63 | }; 64 | } 65 | } 66 | 67 | #endif // _NATIVE_UI_BRUSH_H_ 68 | 69 | -------------------------------------------------------------------------------- /src/ui/include/button.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_BUTTON_H_ 2 | #define _NATIVE_UI_BUTTON_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/signal.h" 6 | 7 | // Module Dependencies 8 | #include "textcomponent.h" 9 | 10 | namespace native 11 | { 12 | namespace ui 13 | { 14 | /** 15 | An on-screen push button which can be clicked by the user in order 16 | to perform an action. 17 | */ 18 | class Button : public TextComponent 19 | { 20 | public: 21 | /** Default constructor. A Button with no text. */ 22 | Button(); 23 | 24 | /** 25 | Convenience constructor, to create a Button and set its text 26 | at the same time. 27 | \param text The button text to set. 28 | */ 29 | Button(const String& text); 30 | 31 | /** Signal emitted when the Button is clicked. */ 32 | Signal<> clicked; 33 | 34 | /** 35 | Calculates the preferred size of this Button based upon its contents. 36 | \return The preferred size. 37 | */ 38 | virtual Size getPreferredSize() const override; 39 | 40 | protected: 41 | /** 42 | Triggers the clicked Signal. 43 | \param event Ignored. 44 | */ 45 | virtual void onClick(const InputEvent& event) override { clicked(); } 46 | 47 | /** 48 | Paints the Button in its own system-defined way. 49 | \param canvas The Canvas to paint with. 50 | */ 51 | virtual void onPaint(Canvas& canvas) override; 52 | }; 53 | } 54 | } 55 | 56 | #endif // _NATIVE_UI_BUTTON_H_ 57 | -------------------------------------------------------------------------------- /src/ui/include/checkbox.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_CHECKBOX_H_ 2 | #define _NATIVE_UI_CHECKBOX_H_ 1 3 | 4 | // Module Dependencies 5 | #include "textcomponent.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | Allows the user to enter a true/false value by selecting or unselecting 13 | the check box component. 14 | */ 15 | class Checkbox : public TextComponent 16 | { 17 | public: 18 | /** Creates a Checkbox. */ 19 | Checkbox(); 20 | 21 | /** 22 | Checks or unchecks the Checkbox. 23 | \param checked true to check, false to uncheck. 24 | */ 25 | void setChecked(bool checked); 26 | 27 | /** 28 | Tells whether the Checkbox is currently checked or not. 29 | \return true if checked, false if unchecked. 30 | */ 31 | bool isChecked() const noexcept { return _checked; } 32 | 33 | /** 34 | Calculates the preferred size of this Checkbox based upon its text. 35 | \return The preferred size. 36 | */ 37 | virtual Size getPreferredSize() const override; 38 | 39 | protected: 40 | /** 41 | Paints the Checkbox in its own system-defined way. 42 | \param canvas The Canvas to paint with. 43 | */ 44 | virtual void onPaint(Canvas& canvas) override; 45 | 46 | private: 47 | // Instance Variables 48 | bool _checked; 49 | }; 50 | } 51 | } 52 | 53 | #endif // _NATIVE_UI_CHECKBOX_H_ 54 | 55 | -------------------------------------------------------------------------------- /src/ui/include/imenuadapter.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_IMENU_ADAPTER_H_ 2 | #define _NATIVE_UI_IMENU_ADAPTER_H_ 1 3 | 4 | namespace native 5 | { 6 | namespace ui 7 | { 8 | // Forward Declarations 9 | class Action; 10 | class Menu; 11 | 12 | class IMenuAdapter 13 | { 14 | public: 15 | virtual ~IMenuAdapter() = default; 16 | 17 | virtual void insert(size_t index, Action& action) = 0; 18 | virtual void insertSeparator(size_t index) = 0; 19 | virtual void insert(size_t index, Menu& menu) = 0; 20 | 21 | virtual void remove(Menu& menu) = 0; 22 | virtual void remove(Action& action) = 0; 23 | 24 | virtual void update(Action& action) = 0; 25 | virtual void update(Menu& menu) = 0; 26 | 27 | virtual handle_t getHandle() const = 0; 28 | }; 29 | } 30 | } 31 | 32 | #endif // _NATIVE_UI_IMENU_ADAPTER_H_ 33 | 34 | -------------------------------------------------------------------------------- /src/ui/include/inputcomponent.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_INPUT_COMPONENT_H_ 2 | #define _NATIVE_UI_INPUT_COMPONENT_H_ 1 3 | 4 | // Module Dependencies 5 | #include "componentadapter.h" 6 | #include "textcomponent.h" 7 | 8 | namespace native 9 | { 10 | namespace ui 11 | { 12 | /** 13 | An InputComponent allows the user to enter basic text input into the 14 | app. 15 | */ 16 | class InputComponent : public TextComponent 17 | { 18 | public: 19 | /** Default constructor. */ 20 | InputComponent(); 21 | 22 | /** 23 | Gets the preferred size for this Component. 24 | \return The preferred size. 25 | */ 26 | virtual Size getPreferredSize() const override; 27 | 28 | protected: 29 | /** 30 | Creates an InputComponent with the given adapter. 31 | \param adapter The input component adapter. 32 | */ 33 | InputComponent(InputAdapter* adapter); 34 | 35 | /** Draws the input. */ 36 | virtual void onPaint(Canvas& canvas) override; 37 | }; 38 | } 39 | } 40 | 41 | #endif // _NATIVE_UI_INPUT_COMPONENT_H_ 42 | 43 | -------------------------------------------------------------------------------- /src/ui/include/inputevent.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_INPUT_EVENT_H_ 2 | #define _NATIVE_UI_INPUT_EVENT_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/types.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | // Forward Declarations 12 | struct ComponentEvent; 13 | 14 | /** 15 | Comprises all of the available information about an input event for 16 | a Component. Input events are generated by mouse or touch actions, 17 | such pressing or releasing the mouse or touch on the Component, or 18 | swiping in a motion over the Component. 19 | */ 20 | struct InputEvent 21 | { 22 | /** Actions which can be performed. */ 23 | enum Action { 24 | Press = 1, 25 | Release, 26 | Motion, 27 | Click, 28 | ContextClick, 29 | Enter, 30 | Leave 31 | }; 32 | 33 | /** Devices or buttons which trigger the action. */ 34 | enum Source { 35 | Mouse = 0, ///< For Motion, Enter and Leave actions. 36 | LeftButton, ///< For `Press` or `Release` actions. 37 | MiddleButton, ///< For `Press` or `Release` actions. 38 | RightButton, ///< For `Press` or `Release` actions. 39 | BackButton, ///< For `Press` or `Release` actions. 40 | ForwardButton, ///< For `Press` or `Release` actions. 41 | Touch 42 | }; 43 | 44 | // Instance Variables 45 | Action action; 46 | Source source; 47 | coord_t x; 48 | coord_t y; 49 | ComponentEvent* nativeEvent; 50 | }; 51 | } 52 | } 53 | 54 | #endif // _NATIVE_UI_INPUT_EVENT_H_ 55 | 56 | -------------------------------------------------------------------------------- /src/ui/include/label.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_LABEL_H_ 2 | #define _NATIVE_UI_LABEL_H_ 1 3 | 4 | // Local Dependencies 5 | #include "textcomponent.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | Currently this doesn't implement anything further over a basic 13 | TextComponent. But, in the future it may... 14 | */ 15 | class Label : public TextComponent 16 | { 17 | public: 18 | /** Creates a Label with no text set. */ 19 | Label(); 20 | 21 | /** 22 | Creates the Label with the given text. 23 | \param text The text to set. 24 | */ 25 | Label(const String& text); 26 | }; 27 | } 28 | } 29 | 30 | #endif // _NATIVE_UI_LABEL_H_ 31 | 32 | -------------------------------------------------------------------------------- /src/ui/include/lineargradientbrush.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_LINEAR_GRADIENT_BRUSH_H_ 2 | #define _NATIVE_LINEAR_GRADIENT_BRUSH_H_ 1 3 | 4 | // Module Dependencies 5 | #include "brush.h" 6 | #include "point.h" 7 | 8 | namespace native 9 | { 10 | namespace ui 11 | { 12 | class LinearGradientBrush : public Brush 13 | { 14 | public: 15 | LinearGradientBrush(Point p0, Point p1, Color c0, Color c1); 16 | }; 17 | } 18 | } 19 | 20 | #endif // _NATIVE_LINEAR_GRADIENT_BRUSH_H_ 21 | 22 | -------------------------------------------------------------------------------- /src/ui/include/menuadapter.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_MENU_ADAPTER_H_ 2 | #define _NATIVE_UI_MENU_ADAPTER_H_ 1 3 | 4 | // Module Dependencies 5 | #include "imenuadapter.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | class MenuAdapter : public IMenuAdapter 12 | { 13 | public: 14 | MenuAdapter(); 15 | 16 | MenuAdapter(handle_t handle); 17 | 18 | ~MenuAdapter(); 19 | 20 | virtual void insert(size_t index, Action& action) override; 21 | virtual void insertSeparator(size_t index) override; 22 | virtual void insert(size_t index, Menu& menu) override; 23 | 24 | virtual void remove(Menu& menu) override; 25 | virtual void remove(Action& action) override; 26 | 27 | virtual void update(Action& action) override; 28 | virtual void update(Menu& menu) override; 29 | 30 | virtual handle_t getHandle() const override { return _handle; } 31 | 32 | private: 33 | // Instance Variables 34 | handle_t _handle; 35 | }; 36 | } 37 | } 38 | 39 | #endif // _NATIVE_UI_MENU_ADAPTER_H_ 40 | 41 | -------------------------------------------------------------------------------- /src/ui/include/numberpicker.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_NUMBER_PICKER_H_ 2 | #define _NATIVE_UI_NUMBER_PICKER_H_ 1 3 | 4 | // Local Dependencies 5 | #include "component.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | NumberPicker is an input Component which allows the user to select 13 | a number. 14 | */ 15 | class NumberPicker : public Component 16 | { 17 | public: 18 | /** Creates a NumberPicker with unbounded range. */ 19 | NumberPicker(); 20 | 21 | /** 22 | Sets the current value in the NumberPicker. 23 | \param value The value to set. 24 | */ 25 | void setValue(int value); 26 | 27 | /** 28 | Gets the current number value. 29 | \return The current value. 30 | */ 31 | int getValue() const; 32 | 33 | /** 34 | Sets the range of allows values (the minimum and maximum). 35 | \param min The minimum value. 36 | \param max The maximum value. 37 | */ 38 | void setRange(int min, int max); 39 | 40 | /** 41 | Gets the minimum value of the NumberPicker. 42 | \return The minimum value. 43 | */ 44 | int getMinimum() const; 45 | 46 | /** 47 | Gets the maximum allowed value in the NumberPicker. 48 | \return The maximum value 49 | */ 50 | int getMaximum() const; 51 | 52 | /** 53 | Gets the preferred size for this Component. 54 | \return The preferred size. 55 | */ 56 | virtual Size getPreferredSize() const override; 57 | }; 58 | } 59 | } 60 | 61 | #endif // _NATIVE_UI_NUMBER_PICKER_H_ 62 | 63 | -------------------------------------------------------------------------------- /src/ui/include/pen.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_PEN_H_ 2 | #define _NATIVE_UI_PEN_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/shared.h" 6 | 7 | // Module Dependencies 8 | #include "color.h" 9 | 10 | namespace native 11 | { 12 | namespace ui 13 | { 14 | /** 15 | A Pen is used to draw lines on a Canvas. 16 | */ 17 | class Pen 18 | { 19 | public: 20 | /** Create an invalid Pen handle. */ 21 | Pen() : _shared(nullptr), _thickness(0) {} 22 | 23 | /** 24 | Creates a Pen which is a solid single color. 25 | \param color The color of the brush. 26 | \param width The width of the pen stroke. 27 | */ 28 | Pen(const Color& color, float width = 1.0f); 29 | 30 | /** 31 | Gets the Color of this Pen. 32 | \return The Pen's color. 33 | */ 34 | Color getColor() const noexcept { return _color; } 35 | 36 | /** 37 | Gets the thickness of the Pen's drawing line, in pixels. 38 | \return The Pen's thickness. 39 | */ 40 | float getThickness() const noexcept { return _thickness; } 41 | 42 | /** 43 | Gets the system resource handle. 44 | \return The system resource handle. 45 | */ 46 | handle_t getHandle() const noexcept { return _shared->handle; } 47 | 48 | private: 49 | /** Shared pen handle, allowing Pen to be passed by value. */ 50 | struct PenHandle 51 | { 52 | // Lifecycle Functions 53 | PenHandle(handle_t handle) : handle(handle) {} 54 | ~PenHandle(); 55 | 56 | // Instance Variables 57 | handle_t handle; 58 | }; 59 | 60 | // Instance Variables 61 | Shared _shared; 62 | float _thickness; 63 | Color _color; 64 | }; 65 | } 66 | } 67 | 68 | #endif // _NATIVE_UI_PEN_H_ 69 | 70 | -------------------------------------------------------------------------------- /src/ui/include/progressbar.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_PROGRESS_BAR_H_ 2 | #define _NATIVE_UI_PROGRESS_BAR_H_ 3 | 4 | // Local Dependencies 5 | #include "component.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | ProgressBar is a Component which displays a loading progress or 13 | percentage value by displaying a horizontal bar and filling it 14 | with the current percentage value. 15 | */ 16 | class ProgressBar : public Component 17 | { 18 | public: 19 | /** 20 | Creates a progress bar with a range of 0-100 and a current 21 | progress value of 0. 22 | */ 23 | ProgressBar(); 24 | 25 | /** 26 | Sets the valid progress range. Defaults to 0-100. 27 | \param min The minimum valid value. 28 | \param max The maximum valid value. 29 | */ 30 | void setRange(int min, int max); 31 | 32 | /** 33 | Sets the current progress value. 34 | \param progress The current progress value. 35 | */ 36 | void setProgress(int progress); 37 | 38 | /** 39 | Gets the system-based preferred size of a ProgressBar. 40 | \return The preferred size. 41 | */ 42 | virtual Size getPreferredSize() const override; 43 | 44 | protected: 45 | /** Handles resizing. */ 46 | virtual void onSize(const Size& size) override; 47 | 48 | private: 49 | // Instance Variables 50 | int _min, _max, _progress; 51 | }; 52 | } 53 | } 54 | 55 | #endif // _NATIVE_UI_PROGRESS_BAR_H_ 56 | -------------------------------------------------------------------------------- /src/ui/include/scrollview.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_SCROLL_VIEW_H_ 2 | #define _NATIVE_UI_SCROLL_VIEW_H_ 1 3 | 4 | // Local Dependencies 5 | #include "layoutcomponent.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | class ScrollView : public LayoutComponent 12 | { 13 | public: 14 | ScrollView(); 15 | 16 | protected: 17 | virtual void onSize(const Size& size) override; 18 | }; 19 | } 20 | } 21 | 22 | #endif // _NATIVE_UI_SCROLL_VIEW_H_ 23 | 24 | -------------------------------------------------------------------------------- /src/ui/include/textarea.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_TEXT_AREA_H_ 2 | #define _NATIVE_UI_TEXT_AREA_H_ 1 3 | 4 | // Local Dependencies 5 | #include "inputcomponent.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | Displays an editable text box for capturing multi-line text input. 13 | */ 14 | class TextArea : public InputComponent 15 | { 16 | public: 17 | /** Default constructor. */ 18 | TextArea(); 19 | 20 | /** 21 | Either shows or hides the scroll bars. 22 | \param horizontal Whether to show the horizontal scroll bar. 23 | \param vertical Whether to show the vertical scroll bar. 24 | */ 25 | void setScrollBars(bool horizontal, bool vertical); 26 | 27 | /** 28 | Gets the preferred size for the TextArea. Currently this is 29 | just the height of 5 lines of text. 30 | \return The preferred size. 31 | */ 32 | virtual Size getPreferredSize() const override; 33 | }; 34 | } 35 | } 36 | 37 | #endif // _NATIVE_UI_TEXT_AREA_H_ 38 | 39 | -------------------------------------------------------------------------------- /src/ui/include/webview.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_WEB_VIEW_H_ 2 | #define _NATIVE_UI_WEB_VIEW_H_ 1 3 | 4 | // Module Dependencies 5 | #include "component.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | A WebView is a Component which displays rendered HTML within its 13 | content area. 14 | */ 15 | class WebView : public Component 16 | { 17 | public: 18 | /** Default constructor. */ 19 | WebView(); 20 | 21 | /** 22 | Navigates the browser to the specified URL. 23 | \param url The URL to navigate to. 24 | */ 25 | void navigate(const String& url); 26 | 27 | /** 28 | Navigates backward, like clicking the "back" button. 29 | */ 30 | void goBack(); 31 | 32 | /** 33 | Navigates forward, like clicking the "forward" button. 34 | */ 35 | void goForward(); 36 | 37 | protected: 38 | /** Updates the size of the WebView. */ 39 | virtual void onSize(const Size& size) override; 40 | }; 41 | } 42 | } 43 | 44 | #endif // _NATIVE_UI_WEB_VIEW_H_ 45 | 46 | -------------------------------------------------------------------------------- /src/ui/include/window.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_WINDOW_H_ 2 | #define _NATIVE_UI_WINDOW_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/string.h" 6 | 7 | // Module Dependencies 8 | #include "layoutcomponent.h" 9 | 10 | namespace native 11 | { 12 | namespace ui 13 | { 14 | /** 15 | A top-level Component. 16 | */ 17 | class Window : public LayoutComponent 18 | { 19 | public: 20 | /** Default constructor. */ 21 | Window(); 22 | 23 | /** 24 | Creates a Window with a different adapter. Usually best to just 25 | use the default constructor. This is good for inserting a mock 26 | adapter for testing purposes though. 27 | \param adapter The component adapter. 28 | */ 29 | Window(IComponentAdapter* adapter); 30 | 31 | /** 32 | Sets the title to display at the top of the Window. 33 | \param title The title text to display. 34 | */ 35 | void setTitle(const String& title); 36 | 37 | /** 38 | Gets the current title text for the Window. 39 | \return The current Window title. 40 | */ 41 | String getTitle() const { return _title; } 42 | 43 | private: 44 | // Instance Variables 45 | String _title; 46 | }; 47 | } 48 | } 49 | 50 | #endif // _NATIVE_UI_WINDOW_H_ 51 | 52 | -------------------------------------------------------------------------------- /src/ui/win32/alerts.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | 4 | // Module Dependencies 5 | #include "../include/alerts.h" 6 | #include "../include/layoutcomponent.h" 7 | 8 | namespace native 9 | { 10 | namespace ui 11 | { 12 | void Alerts::messageBox(Component* owner, const String& message, const String& title) 13 | { 14 | Component* tmp = owner; 15 | 16 | while (tmp && !tmp->getAdapter()) 17 | tmp = tmp->getParent(); 18 | 19 | IComponentAdapter* adapter = tmp ? tmp->getAdapter() : nullptr; 20 | 21 | ::MessageBox(adapter ? HWND(adapter->getHandle()) : NULL, message.toArray(), title.toArray(), MB_OK); 22 | } 23 | 24 | void Alerts::messageBox(const String& message, const String& title) 25 | { 26 | ::MessageBox(NULL, message.toArray(), title.toArray(), MB_OK); 27 | } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/ui/win32/bitmap.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | #include 4 | 5 | // Library Dependencies 6 | #include "../include/bitmap.h" 7 | 8 | namespace native 9 | { 10 | namespace ui 11 | { 12 | Bitmap::BitmapHandle::BitmapHandle(handle_t handle) : handle(handle) 13 | { 14 | } 15 | 16 | Bitmap::BitmapHandle::~BitmapHandle() 17 | { 18 | delete (Gdiplus::Bitmap*) handle; 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/ui/win32/brush.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | #include 4 | 5 | // Module Dependencies 6 | #include "../include/brush.h" 7 | #include "../include/canvas.h" 8 | 9 | namespace native 10 | { 11 | namespace ui 12 | { 13 | Brush::BrushHandle::~BrushHandle() 14 | { 15 | delete (Gdiplus::Brush*) handle; 16 | } 17 | 18 | Brush::Brush(const Color& color) : _shared(nullptr) 19 | { 20 | Gdiplus::Brush* brush = new Gdiplus::SolidBrush(Gdiplus::Color(color.alpha, color.red, color.green, color.blue)); 21 | 22 | if (brush->GetLastStatus() != Gdiplus::Ok) 23 | { 24 | delete brush; 25 | throw GraphicsException("Brush::Brush"); 26 | } 27 | 28 | _shared->handle = brush; 29 | } 30 | 31 | Color Brush::getPrimaryColor() const 32 | { 33 | Gdiplus::Color gdiColor; 34 | Gdiplus::Color colors[2]; 35 | 36 | switch (((Gdiplus::Brush*) getHandle())->GetType()) 37 | { 38 | case Gdiplus::BrushType::BrushTypeSolidColor: 39 | ((Gdiplus::SolidBrush*) getHandle())->GetColor(&gdiColor); 40 | return Color::fromArgb(gdiColor.GetValue()); 41 | 42 | case Gdiplus::BrushType::BrushTypeLinearGradient: 43 | ((Gdiplus::LinearGradientBrush*) getHandle())->GetLinearColors(colors); 44 | return Color::fromArgb(colors[0].GetValue()); 45 | 46 | default: 47 | throw InvalidStateException("Brush not in a supported state to determine its primary color"); 48 | } 49 | } 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/ui/win32/componentadapterproperties.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_COMPONENT_ADAPTER_PROPERTIES_H_ 2 | #define _NATIVE_UI_COMPONENT_ADAPTER_PROPERTIES_H_ 1 3 | 4 | // External Dependencies 5 | #include "../../core/include/types.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | // Forward Declarations 12 | class Component; 13 | 14 | /** 15 | Properties which can be used to define and create a win32 Window. 16 | */ 17 | struct ComponentAdapterProperties 18 | { 19 | Component* component; // The Component to bind to. 20 | 21 | const wchar_t* className; // The window class name, or null for default. 22 | uint32_t style; // The window style. 23 | uint32_t exStyle; // Extended window styles. 24 | }; 25 | } 26 | } 27 | 28 | #endif // _NATIVE_UI_COMPONENT_ADAPTER_PROPERTIES_H_ 29 | 30 | -------------------------------------------------------------------------------- /src/ui/win32/componentevent.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_UI_COMPONENT_EVENT_H_ 2 | #define _NATIVE_UI_COMPONENT_EVENT_H_ 1 3 | 4 | // System Dependencies 5 | #include 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | /** 12 | Details of a native event for a HWND in Win32. 13 | */ 14 | struct ComponentEvent 15 | { 16 | HWND hwnd; 17 | UINT msg; 18 | WPARAM wparam; 19 | LPARAM lparam; 20 | LRESULT result; 21 | 22 | /** This is the main callback for all Win32 Window events. */ 23 | static LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam); 24 | }; 25 | } 26 | } 27 | 28 | #endif // _NATIVE_UI_COMPONENT_EVENT_H_ 29 | 30 | -------------------------------------------------------------------------------- /src/ui/win32/eventqueue.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | 4 | // Module Dependencies 5 | #include "../include/eventqueue.h" 6 | 7 | namespace native 8 | { 9 | namespace ui 10 | { 11 | // Static Variable Initialisations 12 | thread_local int EventQueue::_exitCode = 0; 13 | 14 | bool EventQueue::handleEvent(bool block) 15 | { 16 | MSG msg = {}; 17 | BOOL result = 0; 18 | 19 | // Retrieve the message. 20 | result = block 21 | ? ::GetMessage(&msg, NULL, 0, 0) 22 | : ::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); 23 | 24 | if (result == -1) 25 | throw EventException(); 26 | 27 | HWND wnd = ::GetActiveWindow(); 28 | 29 | // Process the message. 30 | if (result > 0 && !::IsDialogMessage(wnd, &msg)) 31 | { 32 | ::TranslateMessage(&msg); 33 | ::DispatchMessage(&msg); 34 | } 35 | 36 | return result != 0; 37 | } 38 | 39 | void EventQueue::quitWithCode(int exitCode) 40 | { 41 | ::PostQuitMessage(_exitCode = exitCode); 42 | } 43 | } 44 | } 45 | 46 | -------------------------------------------------------------------------------- /src/ui/win32/lineargradientbrush.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | #include 4 | 5 | // Module Dependencies 6 | #include "../include/canvas.h" 7 | #include "../include/lineargradientbrush.h" 8 | 9 | namespace native 10 | { 11 | namespace ui 12 | { 13 | static Gdiplus::Brush* CreateBrush(Point p0, Point p1, Color c0, Color c1) 14 | { 15 | Gdiplus::Brush* brush = new Gdiplus::LinearGradientBrush( 16 | Gdiplus::Point(p0.x, p0.y), 17 | Gdiplus::Point(p1.x, p1.y), 18 | Gdiplus::Color(c0.alpha, c0.red, c0.green, c0.blue), 19 | Gdiplus::Color(c1.alpha, c1.red, c1.green, c1.blue) 20 | ); 21 | 22 | if (brush->GetLastStatus() != Gdiplus::Ok) 23 | { 24 | delete brush; 25 | throw GraphicsException("LinearGradientBrush::LinearGradientBrush"); 26 | } 27 | 28 | return brush; 29 | } 30 | 31 | LinearGradientBrush::LinearGradientBrush(Point p0, Point p1, Color c0, Color c1) 32 | : Brush(CreateBrush(p0, p1, c0, c1)) 33 | { 34 | } 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/ui/win32/pen.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | #include 4 | 5 | // Module Dependencies 6 | #include "../include/canvas.h" 7 | #include "../include/pen.h" 8 | 9 | namespace native 10 | { 11 | namespace ui 12 | { 13 | Pen::Pen(const Color& color, float width) : _shared(nullptr), _thickness(width), _color(color) 14 | { 15 | Gdiplus::Pen* pen = new Gdiplus::Pen(Gdiplus::Color(color.alpha, color.red, color.green, color.blue), width); 16 | 17 | if (pen->GetLastStatus() != Gdiplus::Ok) 18 | { 19 | delete pen; 20 | throw GraphicsException("Pen::Pen"); 21 | } 22 | 23 | _shared->handle = pen; 24 | } 25 | 26 | Pen::PenHandle::~PenHandle() 27 | { 28 | delete (Gdiplus::Pen*) handle; 29 | } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /tests/test/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | minSdkVersion 15 9 | targetSdkVersion 26 10 | } 11 | 12 | buildTypes { 13 | release { 14 | minifyEnabled = false 15 | proguardFiles getDefaultProguardFile('proguard-android.txt') 16 | } 17 | } 18 | 19 | sourceSets { 20 | main { 21 | manifest.srcFile 'src/android/AndroidManifest.xml' 22 | } 23 | } 24 | 25 | externalNativeBuild { 26 | cmake { 27 | path 'src/android/CMakeLists.txt' 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/test/include/log.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_TEST_LOG_H_ 2 | #define _NATIVE_TEST_LOG_H_ 1 3 | 4 | namespace native 5 | { 6 | namespace test 7 | { 8 | /** 9 | Logs the testing output to the relevant console. Note that this 10 | isn't always STDOUT, as a platform such as Android would want it 11 | sent to the debugger console output as STDOUT is directed nowhere. 12 | \param format A printf() style format string, with extra arguments. 13 | \param ... Formatted arguments, for the printf() style formatting. 14 | */ 15 | void log(const char* format, ...); 16 | } 17 | } 18 | 19 | #endif // _NATIVE_TEST_LOG_H_ 20 | -------------------------------------------------------------------------------- /tests/test/include/testregistry.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_TEST_TEST_REGISTRY_H_ 2 | #define _NATIVE_TEST_TEST_REGISTRY_H_ 1 3 | 4 | namespace native 5 | { 6 | namespace test 7 | { 8 | // Forward Declarations 9 | class UnitTest; 10 | 11 | /** 12 | The prototype for a test function, as created when using the TEST() 13 | macro. 14 | */ 15 | typedef void (*TestFunction)(UnitTest*); 16 | 17 | /** 18 | TestRegistry is a singleton class in which all unit tests declared 19 | by the TEST() macro are automatically registered for execution. 20 | */ 21 | class TestRegistry 22 | { 23 | public: 24 | /** 25 | Runs all registered unit tests and displays their results to 26 | the output console. 27 | \return The number of failed tests. 28 | */ 29 | static int runAllTests(); 30 | 31 | /** 32 | Registers a UnitTest to be executed when runAllTests() is called. 33 | \param test The UnitTest to be executed. 34 | */ 35 | static void registerTest(UnitTest& test); 36 | }; 37 | } 38 | } 39 | 40 | #endif // _NATIVE_TEST_TEST_REGISTRY_H_ 41 | -------------------------------------------------------------------------------- /tests/test/src/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/test/src/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${root_dir}/lib/${ANDROID_ABI}") 9 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 10 | 11 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 12 | 13 | ADD_LIBRARY(testing SHARED ${sources}) 14 | 15 | TARGET_LINK_LIBRARIES(testing log) 16 | -------------------------------------------------------------------------------- /tests/test/src/android/java/libnative/test/TestActivity.java: -------------------------------------------------------------------------------- 1 | package libnative.test; 2 | 3 | import android.app.Activity; 4 | import android.content.pm.ActivityInfo; 5 | import android.content.pm.PackageManager; 6 | import android.os.Bundle; 7 | 8 | 9 | public class TestActivity extends Activity { 10 | // Static Variables 11 | private static boolean _libIsLoaded = false; 12 | private static final String META_LIB_NAME = "libnative.test.lib_name"; 13 | 14 | @Override 15 | public void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | loadNativeLibrary(); 18 | onCreate(); 19 | finish(); 20 | } 21 | 22 | private native void onCreate(); 23 | 24 | private void loadNativeLibrary() 25 | { 26 | if (!_libIsLoaded) { 27 | try { 28 | ActivityInfo info = getPackageManager().getActivityInfo(getIntent().getComponent(), PackageManager.GET_META_DATA); 29 | if (info.metaData != null) { 30 | String libName = info.metaData.getString(META_LIB_NAME); 31 | 32 | if (libName == null) 33 | throw new RuntimeException(META_LIB_NAME + " meta-data tag not provided in manifest"); 34 | 35 | System.loadLibrary(libName); 36 | _libIsLoaded = true; 37 | } 38 | } catch (PackageManager.NameNotFoundException e) { 39 | throw new RuntimeException("Error getting native library name", e); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/test/src/android/log.cpp: -------------------------------------------------------------------------------- 1 | // System Dependencies 2 | #include 3 | 4 | // Module Dependencies 5 | #include "../../include/log.h" 6 | 7 | namespace native 8 | { 9 | namespace test 10 | { 11 | void log(const char* format, ...) 12 | { 13 | va_list args; 14 | 15 | va_start(args, format); 16 | __android_log_vprint(ANDROID_LOG_INFO, "native-test", format, args); 17 | va_end(args); 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /tests/test/src/common/testregistry.cpp: -------------------------------------------------------------------------------- 1 | // Standard Dependencies 2 | #include 3 | #include 4 | 5 | // Module Dependencies 6 | #include "../../include/log.h" 7 | #include "../../include/testregistry.h" 8 | #include "../../include/unittest.h" 9 | 10 | // Namespace Usage 11 | using namespace std; 12 | 13 | namespace native 14 | { 15 | namespace test 16 | { 17 | list* tests = nullptr; 18 | 19 | int TestRegistry::runAllTests() 20 | { 21 | int failureCount = 0; 22 | 23 | if (tests) 24 | { 25 | list failures; 26 | std::clock_t start = std::clock(); 27 | 28 | for (UnitTest& test : *tests) 29 | { 30 | int result = test.run(); 31 | log("Executing test %-50s => %s.\n", test.getName(), result ? "Failed" : "Success"); 32 | 33 | if (result) 34 | failures.push_back(test); 35 | 36 | failureCount += result; 37 | } 38 | 39 | double duration = (std::clock() - start) / (double) CLOCKS_PER_SEC; 40 | 41 | log("\nTesting complete in %.4f sec. %d succeeded, %d failed.\n\n", duration, (int) (tests->size() - failureCount), failureCount); 42 | 43 | if (failureCount > 0) 44 | { 45 | log("Failed tests:\n"); 46 | 47 | for (UnitTest& test : failures) 48 | log(" - %s\n", test.getName()); 49 | 50 | log("\n"); 51 | } 52 | } 53 | 54 | return failureCount; 55 | } 56 | 57 | void TestRegistry::registerTest(UnitTest& test) 58 | { 59 | if (tests == nullptr) 60 | tests = new std::list(); 61 | 62 | tests->push_back(test); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/test/src/common/unittest.cpp: -------------------------------------------------------------------------------- 1 | // Standard Dependencies 2 | #include 3 | #include 4 | 5 | // Module Dependencies 6 | #include "../../include/unittest.h" 7 | 8 | namespace native 9 | { 10 | namespace test 11 | { 12 | UnitTest::UnitTest(TestFunction function, const char* name) : _function(function), _name(name), _failureCount(0) 13 | { 14 | TestRegistry::registerTest(*this); 15 | } 16 | 17 | int UnitTest::run() 18 | { 19 | try 20 | { 21 | _function(this); 22 | } 23 | catch (...) 24 | { 25 | fail(); 26 | } 27 | 28 | return _failureCount; 29 | } 30 | 31 | bool isEqual(const char* lhs, const char* rhs) 32 | { 33 | if (!lhs || !rhs) 34 | return !lhs && !rhs; 35 | 36 | return std::strcmp(lhs, rhs) == 0; 37 | } 38 | 39 | bool isEqual(const wchar_t* lhs, const wchar_t* rhs) 40 | { 41 | if (!lhs || !rhs) 42 | return !lhs && !rhs; 43 | 44 | return std::wcscmp(lhs, rhs) == 0; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/test/src/win32/log.cpp: -------------------------------------------------------------------------------- 1 | // Standard Dependencies 2 | #include 3 | #include 4 | 5 | // Module Dependencies 6 | #include "../../include/log.h" 7 | 8 | // Namespace Usage 9 | using namespace std; 10 | 11 | namespace native 12 | { 13 | namespace test 14 | { 15 | void log(const char* format, ...) 16 | { 17 | va_list args; 18 | 19 | va_start(args, format); 20 | vprintf(format, args); 21 | va_end(args); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tests/test/test.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/unittests/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion '28.0.3' 6 | 7 | defaultConfig { 8 | applicationId = 'libnative.test.unittests' 9 | minSdkVersion 15 10 | targetSdkVersion 26 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled = false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt') 17 | } 18 | } 19 | 20 | sourceSets { 21 | main { 22 | java.srcDir 'src/android' 23 | jni.srcDir 'src' 24 | manifest.srcFile 'src/android/AndroidManifest.xml' 25 | res.srcDir 'src/android/res' 26 | } 27 | } 28 | 29 | externalNativeBuild { 30 | cmake { 31 | path 'src/android/CMakeLists.txt' 32 | } 33 | } 34 | } 35 | 36 | dependencies { 37 | implementation project(':ui') 38 | implementation project(':data') 39 | implementation project(':io') 40 | implementation project(':testing') 41 | } 42 | -------------------------------------------------------------------------------- /tests/unittests/src/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/unittests/src/android/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.4.1) 2 | 3 | GET_FILENAME_COMPONENT(root_dir "../../../.." ABSOLUTE) 4 | 5 | INCLUDE_DIRECTORIES("${root_dir}/include") 6 | LINK_DIRECTORIES("${root_dir}/lib/${ANDROID_ABI}") 7 | 8 | SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DANDROID_STL=c++_static -std=gnu++11 -fexceptions") 9 | 10 | FILE(GLOB sources ../*.cpp ../common/*.cpp ../android/*.cpp) 11 | 12 | ADD_LIBRARY(ui STATIC IMPORTED) 13 | ADD_LIBRARY(core STATIC IMPORTED) 14 | ADD_LIBRARY(data STATIC IMPORTED) 15 | ADD_LIBRARY(io STATIC IMPORTED) 16 | ADD_LIBRARY(jnipp STATIC IMPORTED) 17 | ADD_LIBRARY(testing STATIC IMPORTED) 18 | 19 | ADD_LIBRARY(notepad SHARED ${sources}) 20 | 21 | SET_TARGET_PROPERTIES(ui PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libui.so") 22 | SET_TARGET_PROPERTIES(core PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libcore.so") 23 | SET_TARGET_PROPERTIES(data PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libdata.so") 24 | SET_TARGET_PROPERTIES(io PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libio.so") 25 | SET_TARGET_PROPERTIES(jnipp PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libjnipp.so") 26 | SET_TARGET_PROPERTIES(testing PROPERTIES IMPORTED_LOCATION "${root_dir}/lib/${ANDROID_ABI}/libtesting.so") 27 | 28 | TARGET_LINK_LIBRARIES(notepad ui core data io jnipp testing) 29 | -------------------------------------------------------------------------------- /tests/unittests/src/android/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/tests/unittests/src/android/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /tests/unittests/src/android/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/tests/unittests/src/android/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /tests/unittests/src/android/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/tests/unittests/src/android/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /tests/unittests/src/android/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/tests/unittests/src/android/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /tests/unittests/src/core/asciicodec.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | TEST(AsciiCodec_encode) 9 | { 10 | wchar_t str[] = L"Hello\x20AC"; 11 | byte_t buffer[42]; 12 | size_t size = 42; 13 | size_t length = 6; 14 | 15 | StringCodec* codec = StringCodec::byName(L"ASCII"); 16 | 17 | codec->encode(buffer, size, str, length); 18 | 19 | buffer[size] = '\0'; 20 | 21 | ASSERT_EQUAL((const char*) buffer, "Hello?"); 22 | } 23 | 24 | TEST(AsciiCodec_decode) 25 | { 26 | byte_t bytes[] = "Hello\xF0"; 27 | wchar_t buffer[7]; 28 | size_t size = 7; 29 | size_t length = 6; 30 | 31 | StringCodec* codec = StringCodec::byName(L"ASCII"); 32 | 33 | codec->decode(buffer, size, bytes, length); 34 | 35 | buffer[size] = L'\0'; 36 | 37 | ASSERT_EQUAL(buffer, L"Hello?"); 38 | } 39 | -------------------------------------------------------------------------------- /tests/unittests/src/core/conditionvariable.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | TEST(ConditionVariable_waitsToBeSignalled) 9 | { 10 | bool signalled = false; 11 | bool handled = false; 12 | Mutex lock; // Lock for "signalled" and "handled" 13 | ConditionVariable cond(lock); 14 | 15 | // Start a thread that waits for a condition. 16 | Thread thread([&]() { 17 | lock.lock(); 18 | 19 | cond.wait(); 20 | 21 | handled = signalled; 22 | 23 | lock.release(); 24 | }); 25 | 26 | Thread::sleep(100); 27 | 28 | // Update the signalled condition. 29 | lock.lock(); 30 | signalled = true; 31 | lock.release(); 32 | 33 | cond.signalOne(); 34 | 35 | // Wait for the worker thread. 36 | thread.join(); 37 | 38 | ASSERT(handled); 39 | } 40 | 41 | TEST(ConditionVariable_signalAllReleasesAll) 42 | { 43 | Mutex lock; 44 | ConditionVariable cond(lock); 45 | Thread threads[10]; 46 | int finished = 0; 47 | 48 | for (auto& thread : threads) 49 | thread.start([&]() { 50 | lock.lock(); 51 | 52 | cond.wait(); 53 | 54 | Atomic::increment(finished); 55 | 56 | lock.release(); 57 | }); 58 | 59 | Thread::sleep(100); 60 | 61 | cond.signalAll(); 62 | 63 | for (const auto& thread : threads) 64 | thread.join(); 65 | 66 | ASSERT(finished == 10); 67 | } -------------------------------------------------------------------------------- /tests/unittests/src/core/convert.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | TEST(Convert_toInt) 9 | { 10 | ASSERT(Convert::toInt(L"1234") == 1234); 11 | } 12 | 13 | TEST(Convert_toFloat) 14 | { 15 | ASSERT(Convert::toFloat(L"1234.0") == 1234.0); 16 | } 17 | -------------------------------------------------------------------------------- /tests/unittests/src/core/datetime.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | using namespace native::test; 8 | 9 | TEST(DateTime_toString) 10 | { 11 | DateTime date(2016, 8, 3); 12 | 13 | date.setTimeZoneOffset(0); // So the test doesn't depend on current time zone. 14 | 15 | ASSERT_EQUAL(date.toString(), L"2016-08-03T00:00:00.000Z"); 16 | } 17 | 18 | TEST(DateTime_addDays) 19 | { 20 | DateTime date(2016, 12, 31); 21 | 22 | date.addDays(1); 23 | 24 | ASSERT(date.getDay() == 1); 25 | ASSERT(date.getMonth() == January); 26 | ASSERT(date.getYear() == 2017); 27 | ASSERT(date.getWeekDay() == Sunday); 28 | ASSERT(date.getHour() == 0); 29 | ASSERT(date.getMinute() == 0); 30 | ASSERT(date.getSecond() == 0); 31 | ASSERT(date.getMilliSecond() == 0); 32 | } 33 | 34 | -------------------------------------------------------------------------------- /tests/unittests/src/core/function.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | struct FunctionHelper 9 | { 10 | FunctionHelper(int value) : _value(value) {} 11 | 12 | static int staticFunc(int x) { return x + 1; } 13 | int memberFunc() const { return _value + 1; } 14 | 15 | int _value; 16 | }; 17 | 18 | TEST(Function_lambda) 19 | { 20 | int value = 1; 21 | 22 | Function plusOne = [](int x) { return x + 1; }; 23 | 24 | ASSERT(plusOne(value) == value + 1); 25 | } 26 | 27 | TEST(Function_static) 28 | { 29 | int value = 1; 30 | 31 | Function plusOne = &FunctionHelper::staticFunc; 32 | 33 | ASSERT(plusOne(value) == value + 1); 34 | } 35 | 36 | TEST(Function_member) 37 | { 38 | int value = 1; 39 | FunctionHelper helper(value); 40 | 41 | Function plusOne(helper, &FunctionHelper::memberFunc); 42 | 43 | ASSERT(plusOne() == value + 1); 44 | } 45 | -------------------------------------------------------------------------------- /tests/unittests/src/core/hash.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | TEST(hash_sameResultOnSameData) 9 | { 10 | char a[] = "This is something to hash"; 11 | char b[] = "This is something to hash"; 12 | 13 | ASSERT(hash(a, sizeof(a)) == hash(b, sizeof(b))); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /tests/unittests/src/core/linkedlist.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | int getSum(LinkedList& list) 9 | { 10 | int sum = 0; 11 | 12 | for (auto i : list) 13 | sum += i; 14 | 15 | return sum; 16 | } 17 | 18 | TEST(LinkedList_initializer_list) 19 | { 20 | LinkedList list = { 0, 1, 2, 3, 4 }; 21 | 22 | ASSERT(list.getLength() == 5); 23 | } 24 | 25 | TEST(LinkedList_add) 26 | { 27 | LinkedList list; 28 | 29 | list.add(1); 30 | 31 | ASSERT(*list.begin() == 1); 32 | } 33 | 34 | TEST(LinkedList_iterator) 35 | { 36 | LinkedList list = { 0, 1, 2, 3, 4 }; 37 | 38 | ASSERT(getSum(list) == 10); 39 | } 40 | -------------------------------------------------------------------------------- /tests/unittests/src/core/list.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | class NonTrivial 9 | { 10 | public: 11 | int value; 12 | 13 | NonTrivial(int x = 0) : value(x * 10) {} 14 | }; 15 | 16 | int getSum(List& list) 17 | { 18 | int sum = 0; 19 | 20 | for (auto i : list) 21 | sum += i; 22 | 23 | return sum; 24 | } 25 | 26 | TEST(List_initializer_list) 27 | { 28 | List list = { 0, 1, 2, 3, 4 }; 29 | 30 | ASSERT(list.getLength() == 5); 31 | } 32 | 33 | TEST(List_add) 34 | { 35 | List list; 36 | 37 | list.add(1); 38 | 39 | ASSERT(list[0] == 1); 40 | } 41 | 42 | TEST(List_iterator) 43 | { 44 | List list = { 0, 1, 2, 3, 4 }; 45 | 46 | ASSERT(getSum(list) == 10); 47 | } 48 | 49 | TEST(List_insert_remove) 50 | { 51 | List str; 52 | 53 | for (auto ch : "testing") 54 | str.add(ch); 55 | 56 | str.insert(3, 'X'); 57 | 58 | ASSERT(str[7] == 'g'); 59 | 60 | str.removeAt(3); 61 | 62 | ASSERT(str[6] == 'g'); 63 | } 64 | 65 | TEST(List_nonTrivial) 66 | { 67 | List list; 68 | 69 | for (int i = 0; i < 5; ++i) 70 | list.add(i); 71 | 72 | int sum = 0; 73 | 74 | for (auto i : list) 75 | sum += i.value; 76 | 77 | ASSERT(sum == 100); 78 | } 79 | -------------------------------------------------------------------------------- /tests/unittests/src/core/map.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | /** Helper function which adds up all keys and values, for verification. */ 9 | static int getSum(Map& map) 10 | { 11 | int sum = 0; 12 | 13 | for (auto& pair : map) 14 | sum += pair.key + pair.value; 15 | 16 | return sum; 17 | } 18 | 19 | TEST(Map_defaultConstructor) 20 | { 21 | Map map; 22 | 23 | ASSERT(map.getLength() == 0); 24 | } 25 | 26 | TEST(Map_initializerListConstructor) 27 | { 28 | Map map = { 29 | { 1, 10 }, 30 | { 2, 20 } 31 | }; 32 | 33 | ASSERT(map.getLength() == 2); 34 | } 35 | 36 | TEST(Map_add) 37 | { 38 | Map map; 39 | 40 | map.add(1, 2); 41 | 42 | ASSERT(map.getLength() == 1); 43 | } 44 | 45 | TEST(Map_get) 46 | { 47 | Map map = { 48 | { 1, 10 }, 49 | { 2, 20 } 50 | }; 51 | 52 | ASSERT(map[1] == 10); 53 | ASSERT(map[2] == 20); 54 | } 55 | 56 | TEST(Map_iterate) 57 | { 58 | Map map; 59 | 60 | map.add(1, 10); 61 | map.add(2, 20); 62 | map.add(3, 30); 63 | 64 | ASSERT(getSum(map) == 66); 65 | } 66 | 67 | 68 | TEST(Map_remove) 69 | { 70 | Map map; 71 | 72 | map.add(1, 10); 73 | map.add(2, 20); 74 | map.add(3, 30); 75 | 76 | if (map.containsKey(2)) 77 | map.remove(2); 78 | 79 | ASSERT(getSum(map) == 44); 80 | 81 | // This should do nothing. 82 | map.remove(2); 83 | 84 | ASSERT(map.getLength() == 2); 85 | } 86 | -------------------------------------------------------------------------------- /tests/unittests/src/core/math.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | TEST(Math_min) 9 | { 10 | ASSERT(Math::min(10, 20) == 10); 11 | } 12 | 13 | TEST(Math_max) 14 | { 15 | ASSERT(Math::max(10, 20) == 20); 16 | } 17 | 18 | TEST(Math_abs) 19 | { 20 | ASSERT(Math::abs(-1) == 1); 21 | ASSERT(Math::abs(1) == 1); 22 | } 23 | 24 | TEST(Math_squareRoot) 25 | { 26 | ASSERT(Math::squareRoot(100) == 10); 27 | ASSERT(Math::squareRoot(99) == 9); // Integer truncation. 28 | } 29 | 30 | TEST(Math_randomIsWithinBounds) 31 | { 32 | for (int i = 0; i < 10; i++) 33 | { 34 | int x = Math::random(10, 100); 35 | ASSERT(x >= 10 && x < 100); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tests/unittests/src/core/queue.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | TEST(Queue_pushPop) 9 | { 10 | Queue queue; 11 | 12 | queue.push(1); 13 | queue.push(2); 14 | queue.push(3); 15 | 16 | ASSERT(queue.pop() == 1); 17 | ASSERT(queue.pop() == 2); 18 | ASSERT(queue.pop() == 3); 19 | } 20 | -------------------------------------------------------------------------------- /tests/unittests/src/core/semaphore.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | TEST(Semaphore_tryAcquireDoesNotBlock) 9 | { 10 | Semaphore semaphore = 1; 11 | 12 | semaphore.acquire(); // Decrements to zero (locked). 13 | 14 | ASSERT(semaphore.tryAcquire() == false); 15 | semaphore.release(); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /tests/unittests/src/core/set.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | /** Helper function which adds up all keys and values, for verification. */ 9 | static int getSum(Set& set) 10 | { 11 | int sum = 0; 12 | 13 | for (auto value : set) 14 | sum += value; 15 | 16 | return sum; 17 | } 18 | 19 | TEST(Set_add) 20 | { 21 | Set set; 22 | 23 | set.add(1); 24 | 25 | ASSERT(set.getLength() == 1); 26 | } 27 | 28 | TEST(Set_iterate) 29 | { 30 | Set set = { 1, 2, 3 }; 31 | 32 | ASSERT(getSum(set) == 6); 33 | } 34 | 35 | TEST(Set_remove) 36 | { 37 | Set set; 38 | 39 | set.add(1); 40 | set.add(2); 41 | set.add(3); 42 | 43 | if (set.contains(2)) 44 | set.remove(2); 45 | 46 | ASSERT(getSum(set) == 4); 47 | 48 | // Should do nothing, silently. 49 | set.remove(2); 50 | 51 | ASSERT(set.getLength() == 2); 52 | } 53 | -------------------------------------------------------------------------------- /tests/unittests/src/core/stack.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | TEST(Stack_pushPop) 9 | { 10 | Stack stack; 11 | 12 | stack.push(1); 13 | stack.push(2); 14 | stack.push(3); 15 | 16 | ASSERT(stack.pop() == 3); 17 | ASSERT(stack.pop() == 2); 18 | ASSERT(stack.pop() == 1); 19 | } 20 | 21 | TEST(Stack_peek) 22 | { 23 | Stack stack; 24 | 25 | stack.push(1); 26 | stack.push(2); 27 | stack.push(3); 28 | 29 | ASSERT(stack.peek() == 3); 30 | ASSERT(stack.peek() == 3); 31 | } 32 | 33 | -------------------------------------------------------------------------------- /tests/unittests/src/core/string.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/tests/unittests/src/core/string.cpp -------------------------------------------------------------------------------- /tests/unittests/src/core/task.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | // Static Variables 9 | static bool hasUpdated = false; 10 | static thread_local bool tlHasUpdated = false; 11 | 12 | TEST(Task_start) 13 | { 14 | hasUpdated = false; 15 | 16 | Task task([]() { hasUpdated = true; }); 17 | 18 | task.join(); 19 | 20 | ASSERT(hasUpdated); 21 | } 22 | 23 | TEST(Task_assertIsOwnThread) 24 | { 25 | tlHasUpdated = false; 26 | 27 | Task task([]() { tlHasUpdated = true; }); 28 | task.join(); 29 | 30 | ASSERT(!tlHasUpdated); 31 | } 32 | 33 | TEST(Task_generatesResult) 34 | { 35 | Task task([]() { 36 | Thread::sleep(10); 37 | return 100; 38 | }); 39 | 40 | ASSERT(task.getResult() == 100); 41 | } 42 | 43 | -------------------------------------------------------------------------------- /tests/unittests/src/core/thread.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | // Static Variables 9 | static bool hasUpdated = false; 10 | static thread_local bool tlHasUpdated = false; 11 | 12 | // Helper Functions 13 | static void doUpdate() { hasUpdated = true; } 14 | static void doUpdateTl() { tlHasUpdated = true; } 15 | 16 | TEST(Thread_joinWaitsForCompletion) 17 | { 18 | hasUpdated = false; 19 | 20 | Thread thread([] { 21 | Thread::sleep(10); 22 | hasUpdated = true; 23 | }); 24 | 25 | thread.join(); 26 | 27 | ASSERT(hasUpdated); 28 | } 29 | 30 | TEST(Thread_start) 31 | { 32 | hasUpdated = false; 33 | 34 | Thread thread(&doUpdate); 35 | thread.join(); 36 | 37 | ASSERT(hasUpdated); 38 | } 39 | 40 | TEST(Thread_isOwnThread) 41 | { 42 | tlHasUpdated = false; 43 | 44 | Thread thread(&doUpdateTl); 45 | thread.join(); 46 | 47 | ASSERT(!tlHasUpdated); 48 | } 49 | -------------------------------------------------------------------------------- /tests/unittests/src/core/threadpool.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | 8 | TEST(ThreadPool_enqueueExecutesFunction) 9 | { 10 | bool hasUpdated = false; 11 | 12 | ThreadPool::enqueue([&] { 13 | hasUpdated = true; 14 | }); 15 | 16 | Thread::sleep(100); 17 | 18 | ASSERT(hasUpdated); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /tests/unittests/src/core/types.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | using namespace native; 6 | 7 | TEST(Types_PrimitiveTypeSizesAreCorrect) 8 | { 9 | ASSERT(sizeof(native::int8_t) == 1); 10 | ASSERT(sizeof(native::int16_t) == 2); 11 | ASSERT(sizeof(native::int32_t) == 4); 12 | ASSERT(sizeof(native::int64_t) == 8); 13 | 14 | ASSERT(sizeof(native::uint8_t) == 1); 15 | ASSERT(sizeof(native::uint16_t) == 2); 16 | ASSERT(sizeof(native::uint32_t) == 4); 17 | ASSERT(sizeof(native::uint64_t) == 8); 18 | 19 | ASSERT(sizeof(native::ptrint_t) == sizeof(void*)); 20 | ASSERT(sizeof(native::uptrint_t) == sizeof(void*)); 21 | 22 | ASSERT(sizeof(native::byte_t) == 1); 23 | } 24 | -------------------------------------------------------------------------------- /tests/unittests/src/core/utf8codec.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mitchdowd/native/a690e0d5957953b3a8d0f7bb5f193292fa9feb28/tests/unittests/src/core/utf8codec.cpp -------------------------------------------------------------------------------- /tests/unittests/src/core/variant.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | using namespace native::test; 8 | 9 | TEST(Variant_defaultConstructorIsNull) 10 | { 11 | Variant var; 12 | 13 | ASSERT(var.isNull()); 14 | } 15 | 16 | TEST(Variant_stringToInt) 17 | { 18 | Variant var = "123"; 19 | 20 | ASSERT(var.toInt() == 123); 21 | } 22 | 23 | TEST(Variant_intToString) 24 | { 25 | Variant var = 123; 26 | 27 | ASSERT(var.toString() == L"123"); 28 | } 29 | 30 | TEST(Variant_getType) 31 | { 32 | Variant var = 123; 33 | 34 | ASSERT(var.getType() == VariantType::Int); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /tests/unittests/src/io/memorystream.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Namespace Usage 6 | using namespace native; 7 | using namespace native::io; 8 | 9 | TEST(MemoryStream_initialCapacity) 10 | { 11 | MemoryStream stream(1024); 12 | 13 | ASSERT(stream.getCapacity() == 1024); 14 | } 15 | 16 | TEST(MemoryStream_write) 17 | { 18 | MemoryStream stream; 19 | 20 | stream.write("Hello world", 11); 21 | 22 | ASSERT(stream.getPosition() == 11); 23 | ASSERT(stream.getCapacity() >= 11); 24 | ASSERT(stream.getLength() == 11); 25 | } 26 | 27 | TEST(MemoryStream_clear) 28 | { 29 | MemoryStream stream(1024); 30 | 31 | stream.write("Hello world", 11); 32 | 33 | stream.clear(); 34 | 35 | ASSERT(stream.getPosition() == 0); 36 | ASSERT(stream.getLength() == 0); 37 | ASSERT(stream.getCapacity() == 0); 38 | } 39 | 40 | TEST(MemoryStream_seek) 41 | { 42 | MemoryStream stream; 43 | 44 | stream.write("Hello world", 11); 45 | stream.seek(0); 46 | 47 | ASSERT(stream.getPosition() == 0); 48 | 49 | stream.seek(999); 50 | 51 | ASSERT(stream.getPosition() == stream.getLength()); 52 | } 53 | 54 | TEST(MemoryStream_read) 55 | { 56 | MemoryStream stream; 57 | 58 | stream.write("Hello world", 12); 59 | stream.seek(0); 60 | 61 | char buffer[30]; 62 | size_t result = stream.read(buffer, stream.getLength()); 63 | 64 | ASSERT(result == stream.getLength()); 65 | ASSERT(stream.getPosition() == stream.getLength()); 66 | ASSERT_EQUAL(buffer, "Hello world"); 67 | } 68 | 69 | TEST(MemoryStream_initialArray) 70 | { 71 | MemoryStream stream("Hello world", 12); 72 | 73 | ASSERT_THROWS(stream.write("test", 4), IoException); 74 | 75 | char buffer[30]; 76 | size_t result = stream.read(buffer, stream.getLength()); 77 | 78 | ASSERT(result == stream.getLength()); 79 | ASSERT(stream.getPosition() == stream.getLength()); 80 | ASSERT_EQUAL(buffer, "Hello world"); 81 | } 82 | 83 | -------------------------------------------------------------------------------- /tests/unittests/src/main.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | 4 | NATIVE_TEST_MAIN() 5 | -------------------------------------------------------------------------------- /tests/unittests/src/ui/color.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | // Namespace Usage 8 | using namespace native; 9 | using namespace native::ui; 10 | 11 | TEST(Color_toRgb) 12 | { 13 | Color color(0x55, 0x66, 0x77); 14 | 15 | ASSERT(color.toRgb() == 0x00556677); 16 | } 17 | 18 | TEST(Color_toArgb) 19 | { 20 | Color color(0x44, 0x55, 0x66, 0x77); 21 | 22 | ASSERT(color.toArgb() == 0x44556677); 23 | } 24 | 25 | TEST(Color_darken) 26 | { 27 | Color color(0x80, 0x40, 0x20); 28 | 29 | ASSERT(color.darken(50).toRgb() == 0x00402010); 30 | } 31 | 32 | TEST(Color_lighten) 33 | { 34 | Color color(0, 0, 0); 35 | 36 | ASSERT(color.lighten(50).toRgb() == 0x007F7F7F); 37 | } 38 | 39 | TEST(Color_fromRgb) 40 | { 41 | Color color1(0x12, 0x34, 0x56); 42 | Color color2 = Color::fromRgb(color1.toRgb()); 43 | 44 | ASSERT(color1.toRgb() == color2.toRgb()); 45 | } 46 | 47 | -------------------------------------------------------------------------------- /tests/unittests/src/ui/layoutcomponent.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Local Dependencies 6 | #include "mockcomponentadapter.h" 7 | 8 | // Namespace Usage 9 | using namespace native::test; 10 | using namespace native::ui; 11 | 12 | TEST(LayoutComponent_addChildAddsToChildren) 13 | { 14 | LayoutComponent parent; 15 | Component child; 16 | 17 | parent.addChild(child); 18 | 19 | ASSERT(parent.getChildren()[0] == &child); 20 | } 21 | 22 | TEST(LayoutComponent_addChildUpdatesAdapterParent) 23 | { 24 | MockComponentAdapter* parentAdapter = new MockComponentAdapter(); 25 | MockComponentAdapter* childAdapter = new MockComponentAdapter(); 26 | 27 | LayoutComponent parent(parentAdapter); 28 | LayoutComponent mid; 29 | Component child(childAdapter); 30 | 31 | mid.addChild(child); 32 | 33 | ASSERT(childAdapter->getParent() == nullptr); 34 | 35 | parent.addChild(mid); 36 | 37 | ASSERT(childAdapter->getParent() == parentAdapter); 38 | } 39 | 40 | TEST(LayoutComponent_addChildRemovesFromPreviousParent) 41 | { 42 | LayoutComponent firstParent, secondParent; 43 | Component child; 44 | 45 | firstParent.addChild(child); 46 | secondParent.addChild(child); 47 | 48 | ASSERT(firstParent.getChildren().getLength() == 0); 49 | } 50 | 51 | TEST(LayoutComponent_destructorRemovesChildren) 52 | { 53 | Component child; 54 | 55 | { 56 | LayoutComponent parent; 57 | 58 | parent.addChild(child); 59 | } 60 | 61 | ASSERT(child.getParent() == nullptr); 62 | } 63 | 64 | TEST(LayoutComponent_childGetsFullContentArea) 65 | { 66 | LayoutComponent parent; 67 | Component child; 68 | 69 | child.setAlignment(Align::Fill); 70 | parent.addChild(child); 71 | parent.setArea({ 0, 0, 100, 100 }); 72 | 73 | Rectangle area = child.getArea(); 74 | 75 | ASSERT(area.width == 100 && area.height == 100); 76 | ASSERT(area.x == 0 && area.y == 0); 77 | } 78 | 79 | -------------------------------------------------------------------------------- /tests/unittests/src/ui/mockcomponentadapter.h: -------------------------------------------------------------------------------- 1 | #ifndef _NATIVE_TEST_MOCK_COMPONENT_ADAPTER_H_ 2 | #define _NATIVE_TEST_MOCK_COMPONENT_ADAPTER_H_ 1 3 | 4 | // External Dependencies 5 | #include 6 | 7 | namespace native 8 | { 9 | namespace test 10 | { 11 | class MockComponentAdapter : public ui::IComponentAdapter 12 | { 13 | public: 14 | MockComponentAdapter() : _parent(nullptr), _visible(false) {} 15 | 16 | virtual void setParent(ui::IComponentAdapter* parent) override { _parent = parent; } 17 | 18 | ui::IComponentAdapter* getParent() const { return _parent; } 19 | 20 | virtual void setVisible(bool visible) override { _visible = visible; } 21 | 22 | virtual bool isVisible() const override { return _visible; } 23 | 24 | virtual void setEnabled(bool enable) override {} 25 | 26 | virtual void setArea(const ui::Rectangle& area) override { _area = area; } 27 | 28 | virtual ui::Rectangle getArea() const override { return _area; } 29 | 30 | virtual ui::Rectangle getContentArea() const override { return _area.getSize(); } 31 | 32 | virtual void setText(const String& text) override {} 33 | 34 | virtual void setFont(const ui::Font& font) override {} 35 | 36 | virtual void invalidate(const ui::Rectangle& area) override {} 37 | 38 | virtual handle_t getHandle() const noexcept override { return nullptr; } 39 | 40 | virtual void doInput(const ui::InputEvent& event) override {} 41 | 42 | virtual void doPaint(ui::Canvas& canvas) override {} 43 | 44 | virtual void invokeAsync(const Function& func) override { func(); } 45 | 46 | private: 47 | // Instance Variables 48 | ui::IComponentAdapter* _parent; 49 | bool _visible; 50 | ui::Rectangle _area; 51 | }; 52 | } 53 | } 54 | 55 | #endif // _NATIVE_TEST_MOCK_COMPONENT_ADAPTER_H_ 56 | -------------------------------------------------------------------------------- /tests/unittests/src/ui/point.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | #include 5 | 6 | // Namespace Usage 7 | using namespace native; 8 | using namespace native::ui; 9 | 10 | TEST(Point_distanceFrom) 11 | { 12 | Point a(10, 10); 13 | Point b(10, 20); 14 | 15 | ASSERT(a.distanceFrom(b) == 10); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /tests/unittests/src/ui/rectangle.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | #include 5 | 6 | // Namespace Usage 7 | using namespace native; 8 | using namespace native::ui; 9 | 10 | TEST(Rectangle_containsPoint) 11 | { 12 | Rectangle rect(100, 100, 100, 100); 13 | 14 | ASSERT(rect.containsPoint(Point(100, 100))); 15 | ASSERT(!rect.containsPoint(Point(200, 200))); 16 | } 17 | 18 | TEST(Rectangle_inflate) 19 | { 20 | Rectangle rect(100, 100, 100, 100); 21 | 22 | rect = rect.inflate(10); 23 | 24 | ASSERT(rect.x == 90 && rect.y == 90); 25 | ASSERT(rect.width == 120 && rect.height == 120); 26 | } 27 | 28 | TEST(Rectangle_deflate) 29 | { 30 | Rectangle rect(100, 100, 100, 100); 31 | 32 | rect = rect.deflate(10); 33 | 34 | ASSERT(rect.x == 110 && rect.y == 110); 35 | ASSERT(rect.width == 80 && rect.height == 80); 36 | } 37 | 38 | TEST(Rectangle_offset) 39 | { 40 | Rectangle rect(100, 100, 100, 100); 41 | 42 | rect = rect.offset(10, 10); 43 | 44 | ASSERT(rect.x == 110 && rect.y == 110); 45 | ASSERT(rect.width == 100 && rect.height == 100); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /tests/unittests/src/ui/size.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | #include 5 | 6 | // Namespace Usage 7 | using namespace native; 8 | using namespace native::ui; 9 | 10 | TEST(Size_combine) 11 | { 12 | Size size(10, 20); 13 | Size combination = size.combine(Size(20, 10)); 14 | 15 | ASSERT(combination.width == 20 && combination.height == 20); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /tests/unittests/src/ui/window.cpp: -------------------------------------------------------------------------------- 1 | // External Dependencies 2 | #include 3 | #include 4 | 5 | // Local Dependencies 6 | #include "mockcomponentadapter.h" 7 | 8 | // Namespace Usage 9 | using namespace native::ui; 10 | 11 | TEST(Window_setTitle) 12 | { 13 | Window window(new native::test::MockComponentAdapter()); 14 | 15 | window.setTitle(L"Testing"); 16 | 17 | ASSERT_EQUAL(window.getTitle(), L"Testing"); 18 | } 19 | 20 | --------------------------------------------------------------------------------