diff --git a/legacy/eobj/.gitignore b/legacy/eobj/.gitignore new file mode 100644 index 0000000000..030ee40a71 --- /dev/null +++ b/legacy/eobj/.gitignore @@ -0,0 +1,5 @@ +*.swp +Session.vim +tags +.clang_complete +/build diff --git a/legacy/eobj/CMakeLists.txt b/legacy/eobj/CMakeLists.txt new file mode 100644 index 0000000000..9095d24af7 --- /dev/null +++ b/legacy/eobj/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 2.6) +project(eobj) +set(EOBJ_VERSION_MAJOR 0) +set(EOBJ_VERSION_MINOR 1) +set(EOBJ_VERSION_MICRO 0) +set(EOBJ_VERSION ${EOBJ_VERSION_MAJOR}.${EOBJ_VERSION_MINOR}.${EOBJ_VERSION_MICRO}) + +set(PACKAGE ${CMAKE_PROJECT_NAME}) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") + +include_directories ("${PROJECT_BINARY_DIR}") + +find_package(Eina REQUIRED) +find_package(Evas REQUIRED) +find_package(Elementary REQUIRED) + +# likely put this into an FindCompilerAttribute.cmake: +INCLUDE(CheckCSourceCompiles) +SET(HAVE___ATTRIBUTE__) +CHECK_C_SOURCE_COMPILES( + "void foo (int bar __attribute__((unused)) ) { } + static void baz (void) __attribute__((unused)); + static void baz (void) { } + int main(){} + " HAVE___ATTRIBUTE__ + ) + +ADD_DEFINITIONS(-DPACKAGE_BIN_DIR="${CMAKE_INSTALL_PREFIX}/bin" + -DPACKAGE_DATA_DIR="${CMAKE_INSTALL_PREFIX}/share/${CMAKE_PROJECT_NAME}" + -DPACKAGE_LIB_DIR="${CMAKE_INSTALL_PREFIX}/lib") + +ADD_DEFINITIONS(-DHAVE_CONFIG_H) + +configure_file ( + "${PROJECT_SOURCE_DIR}/cmakeconfig.h.in" + "${PROJECT_BINARY_DIR}/config.h" + ) + +include(EFLCheck) + +add_subdirectory(lib) +add_subdirectory(examples/evas) +add_subdirectory(examples/mixin) +add_subdirectory(examples/signals) +add_subdirectory(examples/access) +add_subdirectory(examples/constructors) + +add_subdirectory(tests EXCLUDE_FROM_ALL) + diff --git a/legacy/eobj/cmake/Modules/EFLCheck.cmake b/legacy/eobj/cmake/Modules/EFLCheck.cmake new file mode 100644 index 0000000000..f72932533b --- /dev/null +++ b/legacy/eobj/cmake/Modules/EFLCheck.cmake @@ -0,0 +1,12 @@ +include(CTest) +ENABLE_TESTING() +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure) + +find_package(Check) +set (CHECK_ENABLED ${CHECK_FOUND}) + +set(EFL_COVERAGE false CACHE BOOL "Whether coverage support should be built.'") +if (EFL_COVERAGE) + include(EFLlcov REQUIRED) + ENABLE_COVERAGE() +endif (EFL_COVERAGE) diff --git a/legacy/eobj/cmake/Modules/EFLlcov.cmake b/legacy/eobj/cmake/Modules/EFLlcov.cmake new file mode 100644 index 0000000000..e151df99e8 --- /dev/null +++ b/legacy/eobj/cmake/Modules/EFLlcov.cmake @@ -0,0 +1,31 @@ +macro(ENABLE_COVERAGE) + if (CHECK_ENABLED) + find_program(LCOV_BINARY lcov HINTS ${EFL_LCOV_PATH}) + find_program(GENHTML_BINARY genhtml HINTS ${EFL_LCOV_PATH}) + set(EFL_COVERAGE_CFLAGS "-fprofile-arcs -ftest-coverage") + set(EFL_COVERAGE_LIBS "gcov") + endif (CHECK_ENABLED) + + if (DEFINED LCOV_BINARY) + set(EFL_COVERAGE_ENABLED true) + add_custom_target(lcov-reset + COMMAND rm -rf ${CMAKE_BINARY_DIR}/coverage + COMMAND find ${CMAKE_BINARY_DIR} -name "*.gcda" -delete + COMMAND ${LCOV_BINARY} --zerocounters --directory ${CMAKE_BINARY_DIR} + ) + + add_custom_target(lcov-report + COMMAND mkdir ${CMAKE_BINARY_DIR}/coverage + COMMAND ${LCOV_BINARY} --capture --compat-libtool --output-file ${CMAKE_BINARY_DIR}/coverage/coverage.info --directory ${CMAKE_BINARY_DIR} + COMMAND ${LCOV_BINARY} --remove ${CMAKE_BINARY_DIR}/coverage/coverage.info '*.h' --output-file ${CMAKE_BINARY_DIR}/coverage/coverage.cleaned.info + COMMAND ${GENHTML_BINARY} -t "${PACKAGE}" -o "${CMAKE_BINARY_DIR}/coverage/html" "${CMAKE_BINARY_DIR}/coverage/coverage.cleaned.info" + COMMAND echo "Coverage Report at ${CMAKE_BINARY_DIR}/coverage/html" + ) + + add_custom_target(coverage + COMMAND ${CMAKE_MAKE_PROGRAM} lcov-reset + COMMAND ${CMAKE_MAKE_PROGRAM} check + COMMAND ${CMAKE_MAKE_PROGRAM} lcov-report + ) + endif (DEFINED LCOV_BINARY) +endmacro(ENABLE_COVERAGE) diff --git a/legacy/eobj/cmake/Modules/FindCheck.cmake b/legacy/eobj/cmake/Modules/FindCheck.cmake new file mode 100644 index 0000000000..795b61554f --- /dev/null +++ b/legacy/eobj/cmake/Modules/FindCheck.cmake @@ -0,0 +1,28 @@ +# - Try to find check +# Once done this will define +# CHECK_FOUND - System has check +# CHECK_INCLUDE_DIRS - The check include directories +# CHECK_LIBRARIES - The libraries needed to use check +# CHECK_DEFINITIONS - Compiler switches required for using check + +find_package(PkgConfig) +pkg_check_modules(PC_LIBCHECK QUIET check) +set(CHECK_DEFINITIONS ${PC_LIBCHECK_CFLAGS_OTHER}) + +find_path(CHECK_INCLUDE_DIR check.h + HINTS ${PC_LIBCHECK_INCLUDEDIR} ${PC_LIBCHECK_INCLUDE_DIRS} + PATH_SUFFIXES check ) + +find_library(CHECK_LIBRARY NAMES check + HINTS ${PC_LIBCHECK_LIBDIR} ${PC_LIBCHECK_LIBRARY_DIRS} ) + +set(CHECK_LIBRARIES ${CHECK_LIBRARY} ) +set(CHECK_INCLUDE_DIRS ${CHECK_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set CHECK_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(check DEFAULT_MSG + CHECK_LIBRARY CHECK_INCLUDE_DIR) + +mark_as_advanced(CHECK_INCLUDE_DIR CHECK_LIBRARY ) diff --git a/legacy/eobj/cmake/Modules/FindEcore.cmake b/legacy/eobj/cmake/Modules/FindEcore.cmake new file mode 100644 index 0000000000..97783472b3 --- /dev/null +++ b/legacy/eobj/cmake/Modules/FindEcore.cmake @@ -0,0 +1,59 @@ +# - Try to find ecore +# Once done this will define +# ECORE_FOUND - System has ecore +# ECORE_INCLUDE_DIRS - The ecore include directories +# ECORE_LIBRARIES - The libraries needed to use ecore +# ECORE_DEFINITIONS - Compiler switches required for using ecore + +# Use FIND_PACKAGE( Ecore COMPONENTS ... ) to enable modules +IF( Ecore_FIND_COMPONENTS ) + FOREACH( component ${Ecore_FIND_COMPONENTS} ) + STRING( TOUPPER ${component} _COMPONENT ) + SET( ECORE_USE_${_COMPONENT} 1 ) + ENDFOREACH( component ) +ENDIF( Ecore_FIND_COMPONENTS ) + +find_package(PkgConfig) +pkg_check_modules(PC_LIBECORE QUIET ecore) +set(ECORE_DEFINITIONS ${PC_LIBECORE_CFLAGS_OTHER}) + +find_path(ECORE_INCLUDE_DIR Ecore.h + HINTS ${PC_LIBECORE_INCLUDEDIR} ${PC_LIBECORE_INCLUDE_DIRS} + PATH_SUFFIXES ecore ) + +find_library(ECORE_LIBRARY NAMES ecore + HINTS ${PC_LIBECORE_LIBDIR} ${PC_LIBECORE_LIBRARY_DIRS} ) + +set(ECORE_LIBRARIES ${ECORE_LIBRARY} ) +set(ECORE_INCLUDE_DIRS ${ECORE_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set ECORE_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(ecore DEFAULT_MSG + ECORE_LIBRARY ECORE_INCLUDE_DIR) + +mark_as_advanced( ECORE_INCLUDE_DIR ECORE_LIBRARY ) + +if (ECORE_USE_ECORE-X) + pkg_check_modules(PC_LIBECORE_X QUIET ecore-x) + set(ECORE_X_DEFINITIONS ${PC_LIBECORE_X_CFLAGS_OTHER}) + + find_path(ECORE_X_INCLUDE_DIR Ecore_X.h + HINTS ${PC_LIBECORE_X_INCLUDEDIR} ${PC_LIBECORE_X_INCLUDE_DIRS} + PATH_SUFFIXES ecore ) + + find_library(ECORE_X_LIBRARY NAMES ecore_x + HINTS ${PC_LIBECORE_X_LIBDIR} ${PC_LIBECORE_X_LIBRARY_DIRS} ) + + set(ECORE_X_LIBRARIES ${ECORE_X_LIBRARY} ) + set(ECORE_X_INCLUDE_DIRS ${ECORE_X_INCLUDE_DIR} ) + + include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set ECORE_X_FOUND to TRUE +# if all listed variables are TRUE + find_package_handle_standard_args(ecore_x DEFAULT_MSG + ECORE_X_LIBRARY ECORE_X_INCLUDE_DIR) + + mark_as_advanced( ECORE_X_INCLUDE_DIR ECORE_X_LIBRARY ) +endif (ECORE_USE_ECORE-X) diff --git a/legacy/eobj/cmake/Modules/FindEdje.cmake b/legacy/eobj/cmake/Modules/FindEdje.cmake new file mode 100644 index 0000000000..927b31d5f1 --- /dev/null +++ b/legacy/eobj/cmake/Modules/FindEdje.cmake @@ -0,0 +1,28 @@ +# - Try to find edje +# Once done this will define +# EDJE_FOUND - System has edje +# EDJE_INCLUDE_DIRS - The edje include directories +# EDJE_LIBRARIES - The libraries needed to use edje +# EDJE_DEFINITIONS - Compiler switches required for using edje + +find_package(PkgConfig) +pkg_check_modules(PC_LIBEDJE QUIET edje) +set(EDJE_DEFINITIONS ${PC_LIBEDJE_CFLAGS_OTHER}) + +find_path(EDJE_INCLUDE_DIR Edje.h + HINTS ${PC_LIBEDJE_INCLUDEDIR} ${PC_LIBEDJE_INCLUDE_DIRS} + PATH_SUFFIXES edje ) + +find_library(EDJE_LIBRARY NAMES edje + HINTS ${PC_LIBEDJE_LIBDIR} ${PC_LIBEDJE_LIBRARY_DIRS} ) + +set(EDJE_LIBRARIES ${EDJE_LIBRARY} ) +set(EDJE_INCLUDE_DIRS ${EDJE_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set EDJE_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(edje DEFAULT_MSG + EDJE_LIBRARY EDJE_INCLUDE_DIR) + +mark_as_advanced(EDJE_INCLUDE_DIR EDJE_LIBRARY ) diff --git a/legacy/eobj/cmake/Modules/FindEet.cmake b/legacy/eobj/cmake/Modules/FindEet.cmake new file mode 100644 index 0000000000..ae215d330c --- /dev/null +++ b/legacy/eobj/cmake/Modules/FindEet.cmake @@ -0,0 +1,28 @@ +# - Try to find eet +# Once done this will define +# EET_FOUND - System has eet +# EET_INCLUDE_DIRS - The eet include directories +# EET_LIBRARIES - The libraries needed to use eet +# EET_DEFINITIONS - Compiler switches required for using eet + +find_package(PkgConfig) +pkg_check_modules(PC_LIBEET QUIET eet) +set(EET_DEFINITIONS ${PC_LIBEET_CFLAGS_OTHER}) + +find_path(EET_INCLUDE_DIR Eet.h + HINTS ${PC_LIBEET_INCLUDEDIR} ${PC_LIBEET_INCLUDE_DIRS} + PATH_SUFFIXES eet ) + +find_library(EET_LIBRARY NAMES eet + HINTS ${PC_LIBEET_LIBDIR} ${PC_LIBEET_LIBRARY_DIRS} ) + +set(EET_LIBRARIES ${EET_LIBRARY} ) +set(EET_INCLUDE_DIRS ${EET_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set EET_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(eet DEFAULT_MSG + EET_LIBRARY EET_INCLUDE_DIR) + +mark_as_advanced( EET_INCLUDE_DIR EET_LIBRARY ) diff --git a/legacy/eobj/cmake/Modules/FindEfreet.cmake b/legacy/eobj/cmake/Modules/FindEfreet.cmake new file mode 100644 index 0000000000..d245206f11 --- /dev/null +++ b/legacy/eobj/cmake/Modules/FindEfreet.cmake @@ -0,0 +1,28 @@ +# - Try to find efreet +# Once done this will define +# EFREET_FOUND - System has efreet +# EFREET_INCLUDE_DIRS - The efreet include directories +# EFREET_LIBRARIES - The libraries needed to use efreet +# EFREET_DEFINITIONS - Compiler switches required for using efreet + +find_package(PkgConfig) +pkg_check_modules(PC_LIBEFREET QUIET efreet) +set(EFREET_DEFINITIONS ${PC_LIBEFREET_CFLAGS_OTHER}) + +find_path(EFREET_INCLUDE_DIR Efreet.h + HINTS ${PC_LIBEFREET_INCLUDEDIR} ${PC_LIBEFREET_INCLUDE_DIRS} + PATH_SUFFIXES efreet ) + +find_library(EFREET_LIBRARY NAMES efreet + HINTS ${PC_LIBEFREET_LIBDIR} ${PC_LIBEFREET_LIBRARY_DIRS} ) + +set(EFREET_LIBRARIES ${EFREET_LIBRARY} ) +set(EFREET_INCLUDE_DIRS ${EFREET_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set EFREET_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(efreet DEFAULT_MSG + EFREET_LIBRARY EFREET_INCLUDE_DIR) + +mark_as_advanced(EFREET_INCLUDE_DIR EFREET_LIBRARY ) diff --git a/legacy/eobj/cmake/Modules/FindEina.cmake b/legacy/eobj/cmake/Modules/FindEina.cmake new file mode 100644 index 0000000000..acbd799f3e --- /dev/null +++ b/legacy/eobj/cmake/Modules/FindEina.cmake @@ -0,0 +1,28 @@ +# - Try to find eina +# Once done this will define +# EINA_FOUND - System has eina +# EINA_INCLUDE_DIRS - The eina include directories +# EINA_LIBRARIES - The libraries needed to use eina +# EINA_DEFINITIONS - Compiler switches required for using eina + +find_package(PkgConfig) +pkg_check_modules(PC_LIBEINA QUIET eina) +set(EINA_DEFINITIONS ${PC_LIBEINA_CFLAGS_OTHER}) + +find_path(EINA_INCLUDE_DIR Eina.h + HINTS ${PC_LIBEINA_INCLUDEDIR} ${PC_LIBEINA_INCLUDE_DIRS} + PATH_SUFFIXES eina ) + +find_library(EINA_LIBRARY NAMES eina + HINTS ${PC_LIBEINA_LIBDIR} ${PC_LIBEINA_LIBRARY_DIRS} ) + +set(EINA_LIBRARIES ${EINA_LIBRARY} ) +set(EINA_INCLUDE_DIRS ${EINA_INCLUDE_DIR} "${EINA_INCLUDE_DIR}/eina" ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set EINA_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(eina DEFAULT_MSG + EINA_LIBRARY EINA_INCLUDE_DIR) + +mark_as_advanced(EINA_INCLUDE_DIR EINA_LIBRARY ) diff --git a/legacy/eobj/cmake/Modules/FindElementary.cmake b/legacy/eobj/cmake/Modules/FindElementary.cmake new file mode 100644 index 0000000000..5b75bfcedd --- /dev/null +++ b/legacy/eobj/cmake/Modules/FindElementary.cmake @@ -0,0 +1,28 @@ +# - Try to find elementary +# Once done this will define +# ELEMENTARY_FOUND - System has elementary +# ELEMENTARY_INCLUDE_DIRS - The elementary include directories +# ELEMENTARY_LIBRARIES - The libraries needed to use elementary +# ELEMENTARY_DEFINITIONS - Compiler switches required for using elementary + +find_package(PkgConfig) +pkg_check_modules(PC_LIBELEMENTARY QUIET elementary) +set(ELEMENTARY_DEFINITIONS ${PC_LIBELEMENTARY_CFLAGS_OTHER}) + +find_path(ELEMENTARY_INCLUDE_DIR Elementary.h + HINTS ${PC_LIBELEMENTARY_INCLUDEDIR} ${PC_LIBELEMENTARY_INCLUDE_DIRS} + PATH_SUFFIXES elementary ) + +find_library(ELEMENTARY_LIBRARY NAMES elementary + HINTS ${PC_LIBELEMENTARY_LIBDIR} ${PC_LIBELEMENTARY_LIBRARY_DIRS} ) + +set(ELEMENTARY_LIBRARIES ${ELEMENTARY_LIBRARY} ) +set(ELEMENTARY_INCLUDE_DIRS ${PC_LIBELEMENTARY_INCLUDEDIR} ${PC_LIBELEMENTARY_INCLUDE_DIRS} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set ELEMENTARY_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(elementary DEFAULT_MSG + ELEMENTARY_LIBRARY ELEMENTARY_INCLUDE_DIR) + +mark_as_advanced(ELEMENTARY_INCLUDE_DIR ELEMENTARY_LIBRARY ) diff --git a/legacy/eobj/cmake/Modules/FindEvas.cmake b/legacy/eobj/cmake/Modules/FindEvas.cmake new file mode 100644 index 0000000000..fe980d3541 --- /dev/null +++ b/legacy/eobj/cmake/Modules/FindEvas.cmake @@ -0,0 +1,28 @@ +# - Try to find evas +# Once done this will define +# EVAS_FOUND - System has evas +# EVAS_INCLUDE_DIRS - The evas include directories +# EVAS_LIBRARIES - The libraries needed to use evas +# EVAS_DEFINITIONS - Compiler switches required for using evas + +find_package(PkgConfig) +pkg_check_modules(PC_LIBEVAS QUIET evas) +set(EVAS_DEFINITIONS ${PC_LIBEVAS_CFLAGS_OTHER}) + +find_path(EVAS_INCLUDE_DIR Evas.h + HINTS ${PC_LIBEVAS_INCLUDEDIR} ${PC_LIBEVAS_INCLUDE_DIRS} + PATH_SUFFIXES evas ) + +find_library(EVAS_LIBRARY NAMES evas + HINTS ${PC_LIBEVAS_LIBDIR} ${PC_LIBEVAS_LIBRARY_DIRS} ) + +set(EVAS_LIBRARIES ${EVAS_LIBRARY} ) +set(EVAS_INCLUDE_DIRS ${EVAS_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +# handle the QUIETLY and REQUIRED arguments and set EVAS_FOUND to TRUE +# if all listed variables are TRUE +find_package_handle_standard_args(evas DEFAULT_MSG + EVAS_LIBRARY EVAS_INCLUDE_DIR) + +mark_as_advanced(EVAS_INCLUDE_DIR EVAS_LIBRARY ) diff --git a/legacy/eobj/cmake/Modules/MakeDistcheck.cmake b/legacy/eobj/cmake/Modules/MakeDistcheck.cmake new file mode 100644 index 0000000000..1f383a5994 --- /dev/null +++ b/legacy/eobj/cmake/Modules/MakeDistcheck.cmake @@ -0,0 +1,122 @@ +# - adds support for the 'make distcheck' command -*- cmake -*- +# Dependencies: +# 1. CPack generating ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.gz. +# 2. Having a "dist" target, e.g: +# add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) +# Usage: +# add_distcheck() ... called exactly once per project in the top-level +# CMakeLists.txt; it adds the 'dist' and 'distcheck' +# targets +# +# This module implements the 'make dist' and 'make distcheck' +# commands. +# It supports the following variables: +# +# DISTCHECK_TMPDIR ... directory for temporary files +# DISTCHECK_FILENAME ... basename of existing tar.gz.; defaults to +# ${CPACK_SOURCE_PACKAGE_FILE_NAME} +# DISTCHECK_CMAKEFLAGS +# ... flags which are given to 'cmake' by 'make distcheck' +# DISTCHECK_BUILDTARGETS +# ... the build-targets tried by 'make distcheck'; +# defaults to nothing (--> all) +# DISTCHECK_INSTALLTARGETS +# ... the install-targets tried by 'make distcheck'; +# defaults to 'install' +# +# Example: +# --- top-level CMakeLists.txt --- +# add_subdirectory(foo) +# ... +# ... +# set(CPACK_PACKAGE_VERSION_MAJOR ${ECRIRE_VERSION_MAJOR}) +# set(CPACK_PACKAGE_VERSION_MINOR ${ECRIRE_VERSION_MINOR}) +# set(CPACK_PACKAGE_VERSION_PATCH ${ECRIRE_VERSION_MICRO}) +# set(CPACK_SOURCE_GENERATOR "TGZ") +# set(CPACK_SOURCE_IGNORE_FILES +# "${CMAKE_BINARY_DIR};/.git/;~$;${CPACK_SOURCE_IGNORE_FILES}") +# include(CPack) +# add_custom_target(dist COMMAND ${CMAKE_MAKE_PROGRAM} package_source) +# +# find_package(Distcheck) +# add_distcheck() +# +# +# Copyright (C) 2012 Tom Hacohen +# Based on the work done by: +# Copyright (C) 2006 Enrico Scholz +# +# Redistribution and use, with or without modification, are permitted +# provided that the following conditions are met: +# +# 1. Redistributions must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# 2. The name of the author may not be used to endorse or promote +# products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +macro(add_distcheck) + set(MakeDist_FOUND 1) + + set(DISTCHECK_TMPDIR "${CMAKE_BINARY_DIR}/.make-dist" CACHE PATH "directory for temporary files created by'make dist*'") + set(DISTCHECK_FILENAME ${CPACK_SOURCE_PACKAGE_FILE_NAME} CACHE PATH "basename of the tarball created by 'make dist'") + set(DISTCHECK_CMAKEFLAGS CACHE STRING "flags which are given to 'cmake' by 'make distcheck'") + set(DISTCHECK_BUILDTARGETS "" CACHE STRING "build-target(s) tried by 'make distcheck'") + set(DISTCHECK_INSTALLTARGETS install CACHE STRING "install-target(s) tried by 'make distcheck'") + + mark_as_advanced(DISTCHECK_TMPDIR DISTCHECK_FILENAME DISTCHECK_CMAKEFLAGS DISTCHECK_BUILDTARGETS DISTCHECK_INSTALLTARGETS) + + set(DISTCHECK_BASESOURCEDIR "${DISTCHECK_TMPDIR}/source") + set(DISTCHECK_SOURCEDIR "${DISTCHECK_BASESOURCEDIR}/${DISTCHECK_FILENAME}") + set(DISTCHECK_BUILDDIR "${DISTCHECK_TMPDIR}/build") + set(DISTCHECK_INSTALLTARGETS "install") + add_custom_target(distcheck + # Create the tarball + COMMAND ${CMAKE_MAKE_PROGRAM} dist + + # Create the temp dir. + COMMAND chmod -Rf a+w "${DISTCHECK_TMPDIR}" 2>/dev/null || : + COMMAND rm -rf "${DISTCHECK_TMPDIR}" + COMMAND mkdir -p "${DISTCHECK_SOURCEDIR}" "${DISTCHECK_BUILDDIR}" + + # extract tarball + COMMAND tar xzf ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.gz -C "${DISTCHECK_BASESOURCEDIR}" + # write-protect sources to detect modifies-sourcetree bugs + COMMAND chmod -R a-w "${DISTCHECK_SOURCEDIR}" + + COMMAND cd "${DISTCHECK_BUILDDIR}" && ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX:PATH="${DISTCHECK_TMPDIR}/install" ${DISTCHECK_CMAKEFLAGS} "${DISTCHECK_SOURCEDIR}" + + COMMAND cd "${DISTCHECK_BUILDDIR}" && ${CMAKE_MAKE_PROGRAM} ${DISTCHECK_BUILDTARGETS} + + # execute 'make install' without DESTDIR + COMMAND cd "${DISTCHECK_BUILDDIR}" && ${CMAKE_MAKE_PROGRAM} ${DISTCHECK_INSTALLTARGETS} DESTDIR= + # write protect installation path to detect writing outside of DESTDIR + COMMAND chmod -R a-w "${DISTCHECK_TMPDIR}/install" + # execute 'make install' with DESTDIR and move the files to a better location + COMMAND cd "${DISTCHECK_BUILDDIR}" && ${CMAKE_MAKE_PROGRAM} ${DISTCHECK_INSTALLTARGETS} DESTDIR="${DISTCHECK_TMPDIR}/install-tmp" + COMMAND mv "${DISTCHECK_TMPDIR}/install-tmp/${DISTCHECK_TMPDIR}/install" "${DISTCHECK_TMPDIR}/install-destdir" + + # generate list of files which were installed by the both 'make + # install' commands above and compare them + COMMAND cd "${DISTCHECK_TMPDIR}/install" && find -type f | sort > ../files.install + COMMAND cd "${DISTCHECK_TMPDIR}/install-destdir" && find -type f | sort > ../files.destdir + COMMAND cd "${DISTCHECK_TMPDIR}" && diff files.install files.destdir + + # cleanup tmpdir + COMMAND chmod -R u+Xw "${DISTCHECK_TMPDIR}" 2>/dev/null || : + COMMAND rm -rf "${DISTCHECK_TMPDIR}" + ) +endmacro(add_distcheck) + diff --git a/legacy/eobj/cmakeconfig.h.in b/legacy/eobj/cmakeconfig.h.in new file mode 100644 index 0000000000..aeccf65ff7 --- /dev/null +++ b/legacy/eobj/cmakeconfig.h.in @@ -0,0 +1,13 @@ +#define PACKAGE "@CMAKE_PROJECT_NAME@" +#define PACKAGE_NAME PACKAGE +#define VERSION "@EOBJ_VERSION@" +#define VMAJ @EOBJ_VERSION_MAJOR@ +#define VMIN @EOBJ_VERSION_MINOR@ +#define VMIC @EOBJ_VERSION_MICRO@ + +#cmakedefine HAVE___ATTRIBUTE__ +#ifdef HAVE___ATTRIBUTE__ +#define __UNUSED__ __attribute__((unused)) +#else +#define __UNUSED__ +#endif diff --git a/legacy/eobj/examples/access/CMakeLists.txt b/legacy/eobj/examples/access/CMakeLists.txt new file mode 100644 index 0000000000..c704a2fd7a --- /dev/null +++ b/legacy/eobj/examples/access/CMakeLists.txt @@ -0,0 +1,23 @@ +LIST(APPEND ACCESS_CC_SOURCES + main.c + simple.c + inherit.c + ) + +include_directories( + ${EINA_INCLUDE_DIRS} + ${EVAS_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/lib + ) + +add_executable(access ${ACCESS_CC_SOURCES}) + +get_target_property(eobj_LIB_FILE eobj LOCATION) +target_link_libraries(access + ${EINA_LIBRARIES} + ${eobj_LIB_FILE} + ) + +add_dependencies(access eobj) + +add_test(Example_access access) diff --git a/legacy/eobj/examples/access/inherit.c b/legacy/eobj/examples/access/inherit.c new file mode 100644 index 0000000000..c7c4377b00 --- /dev/null +++ b/legacy/eobj/examples/access/inherit.c @@ -0,0 +1,66 @@ +#include "eobj.h" +#include "simple.h" +#include "simple_protected.h" + +#include "inherit.h" + +EAPI Eobj_Op INHERIT_BASE_ID = 0; + +static Eobj_Class *_my_class = NULL; + +static void +_prot_print(Eobj *obj, Eobj_Op op, va_list *list) +{ + Simple_Protected_Data *pd = eobj_data_get(obj, SIMPLE_CLASS); + (void) op; + (void) list; + printf("%s %d\n", __func__, pd->protected_x1); +} + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT), _prot_print), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +inherit_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(INHERIT_SUB_ID_PROT_PRINT, "", "Print protected var x1."), + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Class_Description class_desc = { + "Inherit", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(&INHERIT_BASE_ID, op_desc, INHERIT_SUB_ID_LAST), + NULL, + 0, + _constructor, + _destructor, + _class_constructor, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, SIMPLE_CLASS, NULL); +} diff --git a/legacy/eobj/examples/access/inherit.h b/legacy/eobj/examples/access/inherit.h new file mode 100644 index 0000000000..4188c111fb --- /dev/null +++ b/legacy/eobj/examples/access/inherit.h @@ -0,0 +1,20 @@ +#ifndef INHERIT_H +#define INHERIT_H + +#include "eobj.h" + +extern EAPI Eobj_Op INHERIT_BASE_ID; + +enum { + INHERIT_SUB_ID_PROT_PRINT, + INHERIT_SUB_ID_LAST +}; + +#define INHERIT_ID(sub_id) (INHERIT_BASE_ID + sub_id) + +#define INHERIT_PROT_PRINT() INHERIT_ID(INHERIT_SUB_ID_PROT_PRINT) + +#define INHERIT_CLASS inherit_class_get() +const Eobj_Class *inherit_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/access/main.c b/legacy/eobj/examples/access/main.c new file mode 100644 index 0000000000..1102b368f8 --- /dev/null +++ b/legacy/eobj/examples/access/main.c @@ -0,0 +1,23 @@ +#include "eobj.h" +#include "simple.h" +#include "inherit.h" + +int +main(int argc, char *argv[]) +{ + (void) argc; + (void) argv; + eobj_init(); + + Eobj *obj = eobj_add(INHERIT_CLASS, NULL); + + eobj_do(obj, SIMPLE_A_SET(1), INHERIT_PROT_PRINT()); + + Simple_Public_Data *pd = eobj_data_get(obj, SIMPLE_CLASS); + printf("Pub: %d\n", pd->public_x2); + + eobj_unref(obj); + eobj_shutdown(); + return 0; +} + diff --git a/legacy/eobj/examples/access/simple.c b/legacy/eobj/examples/access/simple.c new file mode 100644 index 0000000000..96a67d513a --- /dev/null +++ b/legacy/eobj/examples/access/simple.c @@ -0,0 +1,85 @@ +#include "eobj.h" +#include "simple.h" +#include "simple_protected.h" + +EAPI Eobj_Op SIMPLE_BASE_ID = 0; + +typedef struct +{ + Simple_Protected_Data protected; + int a; +} Private_Data; + +EAPI const Eobj_Event_Description _SIG_A_CHANGED = + EOBJ_EVENT_DESCRIPTION("a,changed", "i", "Called when a has changed."); + +static Eobj_Class *_my_class = NULL; + +static void +_a_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + Private_Data *pd = eobj_data_get(obj, _my_class); + (void) op; + int a; + a = va_arg(*list, int); + pd->a = a; + printf("%s %d\n", __func__, pd->a); + + pd->protected.protected_x1 = a + 1; + pd->protected.public.public_x2 = a + 2; + + eobj_event_callback_call(obj, SIG_A_CHANGED, &pd->a); +} + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +simple_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"), + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Event_Description *event_desc[] = { + SIG_A_CHANGED, + NULL + }; + + static const Eobj_Class_Description class_desc = { + "Simple", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST), + event_desc, + sizeof(Private_Data), + _constructor, + _destructor, + _class_constructor, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, EOBJ_CLASS_BASE, NULL); +} diff --git a/legacy/eobj/examples/access/simple.h b/legacy/eobj/examples/access/simple.h new file mode 100644 index 0000000000..ec752051ed --- /dev/null +++ b/legacy/eobj/examples/access/simple.h @@ -0,0 +1,28 @@ +#ifndef SIMPLE_H +#define SIMPLE_H + +#include "eobj.h" + +extern EAPI Eobj_Op SIMPLE_BASE_ID; + +enum { + SIMPLE_SUB_ID_A_SET, + SIMPLE_SUB_ID_LAST +}; + +typedef struct +{ + int public_x2; +} Simple_Public_Data; + +#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id) + +#define SIMPLE_A_SET(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EOBJ_TYPECHECK(int, a) + +extern const Eobj_Event_Description _SIG_A_CHANGED; +#define SIG_A_CHANGED (&(_SIG_A_CHANGED)) + +#define SIMPLE_CLASS simple_class_get() +const Eobj_Class *simple_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/access/simple_protected.h b/legacy/eobj/examples/access/simple_protected.h new file mode 100644 index 0000000000..ff2fb7e93f --- /dev/null +++ b/legacy/eobj/examples/access/simple_protected.h @@ -0,0 +1,12 @@ +#ifndef SIMPLE_PROTECTED_H +#define SIMPLE_PROTECTED_H + +#include "simple.h" + +typedef struct +{ + Simple_Public_Data public; + int protected_x1; +} Simple_Protected_Data; + +#endif diff --git a/legacy/eobj/examples/constructors/CMakeLists.txt b/legacy/eobj/examples/constructors/CMakeLists.txt new file mode 100644 index 0000000000..5ba872c9d4 --- /dev/null +++ b/legacy/eobj/examples/constructors/CMakeLists.txt @@ -0,0 +1,26 @@ +LIST(APPEND CONSTRUCTORS_CC_SOURCES + main.c + simple.c + simple2.c + simple3.c + simple4.c + mixin.c + ) + +include_directories( + ${EINA_INCLUDE_DIRS} + ${EVAS_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/lib + ) + +add_executable(constructors ${CONSTRUCTORS_CC_SOURCES}) + +get_target_property(eobj_LIB_FILE eobj LOCATION) +target_link_libraries(constructors + ${EINA_LIBRARIES} + ${eobj_LIB_FILE} + ) + +add_dependencies(constructors eobj) + +add_test(Example_constructors constructors) diff --git a/legacy/eobj/examples/constructors/main.c b/legacy/eobj/examples/constructors/main.c new file mode 100644 index 0000000000..3ed8c71dd9 --- /dev/null +++ b/legacy/eobj/examples/constructors/main.c @@ -0,0 +1,73 @@ +#include "eobj.h" +#include "simple.h" +#include "simple2.h" +#include "simple3.h" +#include "simple4.h" +#include "mixin.h" + +int my_init_count = 0; + +int +main(int argc, char *argv[]) +{ + int ret = 0; + (void) argc; + (void) argv; + eobj_init(); + + Eobj *obj = eobj_add(SIMPLE_CLASS, NULL); + + if (my_init_count != 2) + { + printf("Error! my_init_count == %d\n", my_init_count); + ret = 1; + } + + eobj_do(obj, SIMPLE_A_SET(1), SIMPLE_B_SET(2)); + + int a, b; + eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b), MIXIN_ADD_AND_PRINT(5)); + + eobj_unref(obj); + + if (my_init_count != 0) + { + printf("Error! my_init_count == %d\n", my_init_count); + ret = 1; + } + + obj = eobj_add(SIMPLE2_CLASS, NULL); + if (obj) + { + printf("Error! obj is supposed to be NULL.\n"); + ret = 1; + } + + obj = eobj_add(SIMPLE3_CLASS, NULL); + if (obj) + { + printf("Error! obj is supposed to be NULL.\n"); + ret = 1; + } + + my_init_count = 0; + obj = eobj_add(SIMPLE4_CLASS, NULL); + + if (my_init_count != 2) + { + printf("Error! my_init_count == %d\n", my_init_count); + ret = 1; + } + + eobj_unref(obj); + + if (my_init_count != 0) + { + printf("Error! my_init_count == %d\n", my_init_count); + ret = 1; + } + + eobj_shutdown(); + return ret; +} + diff --git a/legacy/eobj/examples/constructors/mixin.c b/legacy/eobj/examples/constructors/mixin.c new file mode 100644 index 0000000000..fa93f9bb05 --- /dev/null +++ b/legacy/eobj/examples/constructors/mixin.c @@ -0,0 +1,71 @@ +#include "eobj.h" +#include "mixin.h" +#include "simple.h" + +EAPI Eobj_Op MIXIN_BASE_ID = 0; + +static Eobj_Class *_my_class = NULL; + +static void +_add_and_print_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + (void) op; + int a, b, x; + eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b)); + x = va_arg(*list, const int); + printf("%s %d\n", __func__, a + b + x); +} + +extern int my_init_count; + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); + + my_init_count++; +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); + + my_init_count--; +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), _add_and_print_set), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +mixin_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(MIXIN_SUB_ID_ADD_AND_SET, "i", "Add A + B + param and print it"), + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Class_Description class_desc = { + "Mixin", + EOBJ_CLASS_TYPE_MIXIN, + EOBJ_CLASS_DESCRIPTION_OPS(&MIXIN_BASE_ID, op_desc, MIXIN_SUB_ID_LAST), + NULL, + 0, + _constructor, + _destructor, + _class_constructor, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, EOBJ_CLASS_BASE, NULL); +} diff --git a/legacy/eobj/examples/constructors/mixin.h b/legacy/eobj/examples/constructors/mixin.h new file mode 100644 index 0000000000..d5efae20ca --- /dev/null +++ b/legacy/eobj/examples/constructors/mixin.h @@ -0,0 +1,20 @@ +#ifndef MIXIN_H +#define MIXIN_H + +#include "eobj.h" + +extern EAPI Eobj_Op MIXIN_BASE_ID; + +enum { + MIXIN_SUB_ID_ADD_AND_SET, + MIXIN_SUB_ID_LAST +}; + +#define MIXIN_ID(sub_id) (MIXIN_BASE_ID + sub_id) + +#define MIXIN_ADD_AND_PRINT(x) MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), EOBJ_TYPECHECK(int, x) + +#define MIXIN_CLASS mixin_class_get() +const Eobj_Class *mixin_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/constructors/simple.c b/legacy/eobj/examples/constructors/simple.c new file mode 100644 index 0000000000..3f2f4af7a8 --- /dev/null +++ b/legacy/eobj/examples/constructors/simple.c @@ -0,0 +1,98 @@ +#include "eobj.h" +#include "mixin.h" +#include "simple.h" + +EAPI Eobj_Op SIMPLE_BASE_ID = 0; + +typedef struct +{ + int a; + int b; +} Private_Data; + +static Eobj_Class *_my_class = NULL; + +#define _GET_SET_FUNC(name) \ +static void \ +_##name##_get(Eobj *obj, Eobj_Op op, va_list *list) \ +{ \ + Private_Data *pd = eobj_data_get(obj, _my_class); \ + (void) op; \ + int *name; \ + name = va_arg(*list, int *); \ + *name = pd->name; \ + printf("%s %d\n", __func__, pd->name); \ +} \ +static void \ +_##name##_set(Eobj *obj, Eobj_Op op, va_list *list) \ +{ \ + Private_Data *pd = eobj_data_get(obj, _my_class); \ + (void) op; \ + int name; \ + name = va_arg(*list, int); \ + pd->name = name; \ + printf("%s %d\n", __func__, pd->name); \ +} + +_GET_SET_FUNC(a) +_GET_SET_FUNC(b) + +extern int my_init_count; + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); + + my_init_count++; +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); + + my_init_count--; +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set), + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set), + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +simple_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"), + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"), + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "i", "Set property B"), + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "i", "Get property B"), + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Class_Description class_desc = { + "Simple", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST), + NULL, + sizeof(Private_Data), + _constructor, + _destructor, + _class_constructor, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, EOBJ_CLASS_BASE, MIXIN_CLASS, NULL); +} diff --git a/legacy/eobj/examples/constructors/simple.h b/legacy/eobj/examples/constructors/simple.h new file mode 100644 index 0000000000..4baf2b0dd5 --- /dev/null +++ b/legacy/eobj/examples/constructors/simple.h @@ -0,0 +1,26 @@ +#ifndef SIMPLE_H +#define SIMPLE_H + +#include "eobj.h" + +extern EAPI Eobj_Op SIMPLE_BASE_ID; + +enum { + SIMPLE_SUB_ID_A_SET, + SIMPLE_SUB_ID_A_GET, + SIMPLE_SUB_ID_B_SET, + SIMPLE_SUB_ID_B_GET, + SIMPLE_SUB_ID_LAST +}; + +#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id) + +#define SIMPLE_A_SET(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EOBJ_TYPECHECK(int, a) +#define SIMPLE_A_GET(a) SIMPLE_ID(SIMPLE_SUB_ID_A_GET), EOBJ_TYPECHECK(int *, a) +#define SIMPLE_B_SET(b) SIMPLE_ID(SIMPLE_SUB_ID_B_SET), EOBJ_TYPECHECK(int, b) +#define SIMPLE_B_GET(b) SIMPLE_ID(SIMPLE_SUB_ID_B_GET), EOBJ_TYPECHECK(int *, b) + +#define SIMPLE_CLASS simple_class_get() +const Eobj_Class *simple_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/constructors/simple2.c b/legacy/eobj/examples/constructors/simple2.c new file mode 100644 index 0000000000..3f76e529c0 --- /dev/null +++ b/legacy/eobj/examples/constructors/simple2.c @@ -0,0 +1,40 @@ +#include "eobj.h" +#include "mixin.h" +#include "simple2.h" + +static Eobj_Class *_my_class = NULL; + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); + + eobj_constructor_error_set(obj); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); +} + +const Eobj_Class * +simple2_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Class_Description class_desc = { + "Simple2", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), + NULL, + 0, + _constructor, + _destructor, + NULL, + NULL + }; + + _my_class = eobj_class_new(&class_desc, EOBJ_CLASS_BASE, NULL); + return _my_class; +} diff --git a/legacy/eobj/examples/constructors/simple2.h b/legacy/eobj/examples/constructors/simple2.h new file mode 100644 index 0000000000..215f385611 --- /dev/null +++ b/legacy/eobj/examples/constructors/simple2.h @@ -0,0 +1,9 @@ +#ifndef SIMPLE2_H +#define SIMPLE2_H + +#include "eobj.h" + +#define SIMPLE2_CLASS simple2_class_get() +const Eobj_Class *simple2_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/constructors/simple3.c b/legacy/eobj/examples/constructors/simple3.c new file mode 100644 index 0000000000..76c12bebfa --- /dev/null +++ b/legacy/eobj/examples/constructors/simple3.c @@ -0,0 +1,38 @@ +#include "eobj.h" +#include "mixin.h" +#include "simple3.h" + +static Eobj_Class *_my_class = NULL; + +static void +_constructor(Eobj *obj) +{ + (void) obj; +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); +} + +const Eobj_Class * +simple3_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Class_Description class_desc = { + "Simple3", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), + NULL, + 0, + _constructor, + _destructor, + NULL, + NULL + }; + + _my_class = eobj_class_new(&class_desc, EOBJ_CLASS_BASE, NULL); + return _my_class; +} diff --git a/legacy/eobj/examples/constructors/simple3.h b/legacy/eobj/examples/constructors/simple3.h new file mode 100644 index 0000000000..1ef3a178ab --- /dev/null +++ b/legacy/eobj/examples/constructors/simple3.h @@ -0,0 +1,9 @@ +#ifndef SIMPLE3_H +#define SIMPLE3_H + +#include "eobj.h" + +#define SIMPLE3_CLASS simple3_class_get() +const Eobj_Class *simple3_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/constructors/simple4.c b/legacy/eobj/examples/constructors/simple4.c new file mode 100644 index 0000000000..6bc323c3a8 --- /dev/null +++ b/legacy/eobj/examples/constructors/simple4.c @@ -0,0 +1,39 @@ +#include "eobj.h" +#include "mixin.h" +#include "simple.h" +#include "simple4.h" + +static Eobj_Class *_my_class = NULL; + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); +} + +const Eobj_Class * +simple4_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Class_Description class_desc = { + "Simple4", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), + NULL, + 0, + _constructor, + _destructor, + NULL, + NULL + }; + + _my_class = eobj_class_new(&class_desc, SIMPLE_CLASS, MIXIN_CLASS, NULL); + return _my_class; +} diff --git a/legacy/eobj/examples/constructors/simple4.h b/legacy/eobj/examples/constructors/simple4.h new file mode 100644 index 0000000000..92ecc44c04 --- /dev/null +++ b/legacy/eobj/examples/constructors/simple4.h @@ -0,0 +1,9 @@ +#ifndef SIMPLE4_H +#define SIMPLE4_H + +#include "eobj.h" + +#define SIMPLE4_CLASS simple4_class_get() +const Eobj_Class *simple4_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/evas/CMakeLists.txt b/legacy/eobj/examples/evas/CMakeLists.txt new file mode 100644 index 0000000000..ca19049c17 --- /dev/null +++ b/legacy/eobj/examples/evas/CMakeLists.txt @@ -0,0 +1,26 @@ +LIST(APPEND EVAS_CC_SOURCES + elw_box.c + elw_boxedbutton.c + elw_win.c + elw_button.c + evas_obj.c + test.c + ) + +include_directories( + ${EINA_INCLUDE_DIRS} + ${EVAS_INCLUDE_DIRS} + ${ELEMENTARY_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/lib + ) + +add_executable(evas ${EVAS_CC_SOURCES}) +get_target_property(eobj_LIB_FILE eobj LOCATION) +target_link_libraries(evas + ${EINA_LIBRARIES} + ${EVAS_LIBRARIES} + ${ELEMENTARY_LIBRARIES} + ${eobj_LIB_FILE} + ) + +add_dependencies(evas eobj) diff --git a/legacy/eobj/examples/evas/elw_box.c b/legacy/eobj/examples/evas/elw_box.c new file mode 100644 index 0000000000..4156d088c0 --- /dev/null +++ b/legacy/eobj/examples/evas/elw_box.c @@ -0,0 +1,88 @@ +#include + +#include "eobj.h" +#include "evas_obj.h" +#include "elw_box.h" + +EAPI Eobj_Op ELW_BOX_BASE_ID = 0; + +typedef struct +{ + Evas_Object *bx; +} Widget_Data; + +static Eobj_Class *_my_class = NULL; + +static void +_pack_end(Eobj *obj, Eobj_Op op, va_list *list) +{ + Widget_Data *wd = eobj_data_get(obj, _my_class); + (void) op; + Eobj *child_obj; + child_obj = va_arg(*list, Eobj *); + /* FIXME: Ref and the later uref child_obj here... */ + elm_box_pack_end(wd->bx, eobj_evas_object_get(child_obj)); +} + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); + + Widget_Data *wd = eobj_data_get(obj, _my_class); + + /* FIXME: An hack, because our tree is not yet only Eobj */ + wd->bx = elm_box_add(eobj_evas_object_get(eobj_parent_get(obj))); + evas_object_size_hint_align_set(wd->bx, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(wd->bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + + eobj_evas_object_set(obj, wd->bx); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); + + //Widget_Data *wd = eobj_data_get(obj, _my_class); + /* FIXME: Commented out because it's automatically done because our tree + * is not made of only eobj */ +// evas_object_del(wd->bx); +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(ELW_BOX_ID(ELW_BOX_SUB_ID_PACK_END), _pack_end), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +elw_box_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(ELW_BOX_SUB_ID_PACK_END, "o", "Pack obj at the end of box."), + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Class_Description class_desc = { + "Elw Box", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(&ELW_BOX_BASE_ID, op_desc, ELW_BOX_SUB_ID_LAST), + NULL, + sizeof(Widget_Data), + _constructor, + _destructor, + _class_constructor, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, EVAS_OBJ_CLASS, NULL); +} + diff --git a/legacy/eobj/examples/evas/elw_box.h b/legacy/eobj/examples/evas/elw_box.h new file mode 100644 index 0000000000..0e91fd01c3 --- /dev/null +++ b/legacy/eobj/examples/evas/elw_box.h @@ -0,0 +1,20 @@ +#ifndef ELW_BOX_H +#define ELW_BOX_H + +#include "eobj.h" + +extern EAPI Eobj_Op ELW_BOX_BASE_ID; + +enum { + ELW_BOX_SUB_ID_PACK_END, + ELW_BOX_SUB_ID_LAST +}; + +#define ELW_BOX_ID(sub_id) (ELW_BOX_BASE_ID + sub_id) + +#define ELW_BOX_PACK_END(obj) ELW_BOX_ID(ELW_BOX_SUB_ID_PACK_END), EOBJ_TYPECHECK(Eobj *, obj) + +#define ELW_BOX_CLASS elw_box_class_get() +const Eobj_Class *elw_box_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/evas/elw_boxedbutton.c b/legacy/eobj/examples/evas/elw_boxedbutton.c new file mode 100644 index 0000000000..a50b484c00 --- /dev/null +++ b/legacy/eobj/examples/evas/elw_boxedbutton.c @@ -0,0 +1,56 @@ +#include + +#include "eobj.h" +#include "evas_obj.h" +#include "elw_box.h" +#include "elw_button.h" +#include "elw_boxedbutton.h" + +typedef struct +{ +// Evas_Object *bx; +} Widget_Data; + +static Eobj_Class *_my_class = NULL; + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); + + Eobj *bt = eobj_add(ELW_BUTTON_CLASS, obj); + eobj_composite_object_attach(obj, bt); + eobj_event_callback_forwarder_add(bt, SIG_CLICKED, obj); + eobj_do(bt, EVAS_OBJ_VISIBILITY_SET(EINA_TRUE)); + + eobj_do(obj, ELW_BOX_PACK_END(bt)); + eobj_unref(bt); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); +} + +const Eobj_Class * +elw_boxedbutton_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Class_Description class_desc = { + "Elw BoxedButton", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), + NULL, + sizeof(Widget_Data), + _constructor, + _destructor, + NULL, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, ELW_BOX_CLASS, + ELW_BUTTON_CLASS, NULL); +} + diff --git a/legacy/eobj/examples/evas/elw_boxedbutton.h b/legacy/eobj/examples/evas/elw_boxedbutton.h new file mode 100644 index 0000000000..89cfdbba0b --- /dev/null +++ b/legacy/eobj/examples/evas/elw_boxedbutton.h @@ -0,0 +1,9 @@ +#ifndef ELW_BOXEDBUTTON_H +#define ELW_BOXEDBUTTON_H + +#include "eobj.h" + +#define ELW_BOXEDBUTTON_CLASS elw_boxedbutton_class_get() +const Eobj_Class *elw_boxedbutton_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/evas/elw_button.c b/legacy/eobj/examples/evas/elw_button.c new file mode 100644 index 0000000000..6979ccfbae --- /dev/null +++ b/legacy/eobj/examples/evas/elw_button.c @@ -0,0 +1,118 @@ +#include + +#include "eobj.h" +#include "evas_obj.h" +#include "elw_button.h" + +EAPI Eobj_Op ELW_BUTTON_BASE_ID = 0; + +EAPI const Eobj_Event_Description _SIG_CLICKED = + EOBJ_EVENT_DESCRIPTION("clicked", "", "Called when there was a click."); + +typedef struct +{ + Evas_Object *bt; +} Widget_Data; + +static Eobj_Class *_my_class = NULL; + +static void +_position_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + (void) op; + (void) obj; + Evas_Coord x, y; + x = va_arg(*list, Evas_Coord); + y = va_arg(*list, Evas_Coord); + printf("But set position %d,%d\n", x, y); + eobj_class_parent_do(obj, _my_class, EVAS_OBJ_POSITION_SET(x, y)); +} + +static void +_text_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + Widget_Data *wd = eobj_data_get(obj, _my_class); + (void) op; + const char *text; + text = va_arg(*list, const char *); + elm_object_text_set(wd->bt, text); +} + +static void +_btn_clicked(void *data, Evas_Object *evas_obj, void *event_info) +{ + (void) evas_obj; + (void) event_info; + Eobj *obj = data; + eobj_event_callback_call(obj, SIG_CLICKED, NULL); +} + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); + + Widget_Data *wd = eobj_data_get(obj, _my_class); + + /* FIXME: An hack, because our tree is not yet only Eobj */ + wd->bt = elm_button_add(eobj_evas_object_get(eobj_parent_get(obj))); + evas_object_size_hint_align_set(wd->bt, EVAS_HINT_FILL, EVAS_HINT_FILL); + evas_object_size_hint_weight_set(wd->bt, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_smart_callback_add(wd->bt, "clicked", _btn_clicked, obj); + + eobj_evas_object_set(obj, wd->bt); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); + + //Widget_Data *wd = eobj_data_get(obj, _my_class); + /* FIXME: Commented out because it's automatically done because our tree + * is not made of only eobj */ + //evas_object_del(wd->bt); +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(ELW_BUTTON_ID(ELW_BUTTON_SUB_ID_TEXT_SET), _text_set), + EOBJ_OP_FUNC_DESCRIPTION(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_POSITION_SET), _position_set), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +elw_button_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(ELW_BUTTON_SUB_ID_TEXT_SET, "s", "Text of a text supporting evas object."), // FIXME: This ID sholudn't really be defined here... + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Event_Description *event_desc[] = { + SIG_CLICKED, + NULL + }; + + static const Eobj_Class_Description class_desc = { + "Elw Button", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(&ELW_BUTTON_BASE_ID, op_desc, ELW_BUTTON_SUB_ID_LAST), + event_desc, + sizeof(Widget_Data), + _constructor, + _destructor, + _class_constructor, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, EVAS_OBJ_CLASS, NULL); +} + diff --git a/legacy/eobj/examples/evas/elw_button.h b/legacy/eobj/examples/evas/elw_button.h new file mode 100644 index 0000000000..a4da9e7ffd --- /dev/null +++ b/legacy/eobj/examples/evas/elw_button.h @@ -0,0 +1,24 @@ +#ifndef ELW_BUTTON_H +#define ELW_BUTTON_H + +#include "eobj.h" + +extern EAPI Eobj_Op ELW_BUTTON_BASE_ID; + +enum { + ELW_BUTTON_SUB_ID_TEXT_SET, + ELW_BUTTON_SUB_ID_LAST +}; + +#define ELW_BUTTON_ID(sub_id) (ELW_BUTTON_BASE_ID + sub_id) + +/* FIXME Doesn't belong here, but just for the example... */ +#define ELW_BUTTON_TEXT_SET(obj) ELW_BUTTON_ID(ELW_BUTTON_SUB_ID_TEXT_SET), EOBJ_TYPECHECK(const char *, obj) + +extern const Eobj_Event_Description _SIG_CLICKED; +#define SIG_CLICKED (&(_SIG_CLICKED)) + +#define ELW_BUTTON_CLASS elw_button_class_get() +const Eobj_Class *elw_button_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/evas/elw_win.c b/legacy/eobj/examples/evas/elw_win.c new file mode 100644 index 0000000000..9457170112 --- /dev/null +++ b/legacy/eobj/examples/evas/elw_win.c @@ -0,0 +1,76 @@ +#include + +#include "eobj.h" +#include "evas_obj.h" +#include "elw_win.h" + +typedef struct +{ + Evas_Object *win; + Evas_Object *bg; +} Widget_Data; + +static Eobj_Class *_my_class = NULL; + +static void +my_win_del(void *data, Evas_Object *obj, void *event_info) +{ + /* called when my_win_main is requested to be deleted */ + elm_exit(); /* exit the program's main loop that runs in elm_run() */ + (void) data; + (void) obj; + (void) event_info; +} + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); + + Widget_Data *wd = eobj_data_get(obj, _my_class); + + /* FIXME: Will actually do something about those when I care... */ + wd->win = elm_win_add(NULL, "eobj-test", ELM_WIN_BASIC); + elm_win_title_set(wd->win, "Eobj Test"); + elm_win_autodel_set(wd->win, EINA_TRUE); + evas_object_smart_callback_add(wd->win, "delete,request", my_win_del, NULL); + + wd->bg = elm_bg_add(wd->win); + elm_win_resize_object_add(wd->win, wd->bg); + evas_object_size_hint_weight_set(wd->bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + evas_object_show(wd->bg); + + eobj_evas_object_set(obj, wd->win); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); + + //Widget_Data *wd = eobj_data_get(obj, _my_class); + /* FIXME: Commented out because it's automatically done because our tree + * is not made of only eobj */ +// evas_object_del(wd->bx); +} + +const Eobj_Class * +elw_win_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Class_Description class_desc = { + "Elw Box", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), + NULL, + sizeof(Widget_Data), + _constructor, + _destructor, + NULL, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, EVAS_OBJ_CLASS, NULL); +} + diff --git a/legacy/eobj/examples/evas/elw_win.h b/legacy/eobj/examples/evas/elw_win.h new file mode 100644 index 0000000000..32b984c7fa --- /dev/null +++ b/legacy/eobj/examples/evas/elw_win.h @@ -0,0 +1,9 @@ +#ifndef ELW_WIN_H +#define ELW_WIN_H + +#include "eobj.h" + +#define ELW_WIN_CLASS elw_win_class_get() +const Eobj_Class *elw_win_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/evas/evas_obj.c b/legacy/eobj/examples/evas/evas_obj.c new file mode 100644 index 0000000000..b7d518ff4b --- /dev/null +++ b/legacy/eobj/examples/evas/evas_obj.c @@ -0,0 +1,153 @@ +#include + +#include "eobj.h" +#include "evas_obj.h" + +static Eobj_Class *_my_class = NULL; + +EAPI Eobj_Op EVAS_OBJ_BASE_ID = 0; + +typedef struct +{ + Eina_List *children; +} Widget_Data; + +static void +_position_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + Evas_Object *evas_obj = eobj_evas_object_get(obj); + (void) op; + Evas_Coord x, y; + x = va_arg(*list, Evas_Coord); + y = va_arg(*list, Evas_Coord); + evas_object_move(evas_obj, x, y); +} + +static void +_size_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + Evas_Object *evas_obj = eobj_evas_object_get(obj); + (void) op; + Evas_Coord w, h; + w = va_arg(*list, Evas_Coord); + h = va_arg(*list, Evas_Coord); + evas_object_resize(evas_obj, w, h); +} + +static void +_color_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + Evas_Object *evas_obj = eobj_evas_object_get(obj); + (void) op; + int r, g, b, a; + r = va_arg(*list, int); + g = va_arg(*list, int); + b = va_arg(*list, int); + a = va_arg(*list, int); + evas_object_color_set(evas_obj, r, g, b, a); +} + +static void +_color_get(Eobj *obj, Eobj_Op op, va_list *list) +{ + Evas_Object *evas_obj = eobj_evas_object_get(obj); + (void) op; + int *r, *g, *b, *a; + r = va_arg(*list, int*); + g = va_arg(*list, int*); + b = va_arg(*list, int*); + a = va_arg(*list, int*); + evas_object_color_get(evas_obj, r, g, b, a); +} + +static void +_visibility_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + Evas_Object *evas_obj = eobj_evas_object_get(obj); + (void) op; + Eina_Bool v; + v = va_arg(*list, int); + if (v) evas_object_show(evas_obj); + else evas_object_hide(evas_obj); +} + +static void +_child_add(Eobj *obj, Eobj_Op op, va_list *list) +{ + Widget_Data *wd = eobj_data_get(obj, _my_class); + (void) op; + Eobj *child; + child = va_arg(*list, Eobj *); + wd->children = eina_list_append(wd->children, eobj_ref(child)); +} + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); + + /* Add type check. */ + Eobj *parent = eobj_parent_get(obj); + if (parent) + eobj_do(parent, EVAS_OBJ_CHILD_ADD(obj)); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); + + Widget_Data *wd = eobj_data_get(obj, _my_class); + + Eobj *child; + EINA_LIST_FREE(wd->children, child) + { + eobj_del(child); + } +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_POSITION_SET), _position_set), + EOBJ_OP_FUNC_DESCRIPTION(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_SIZE_SET), _size_set), + EOBJ_OP_FUNC_DESCRIPTION(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_SET), _color_set), + EOBJ_OP_FUNC_DESCRIPTION(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_GET), _color_get), + EOBJ_OP_FUNC_DESCRIPTION(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_VISIBILITY_SET), _visibility_set), + EOBJ_OP_FUNC_DESCRIPTION(EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_CHILD_ADD), _child_add), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +evas_object_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_POSITION_SET, "ii", "Position of an evas object."), + EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_SIZE_SET, "ii", "Size of an evas object."), + EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_COLOR_SET, "iiii", "Color of an evas object."), + EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_COLOR_GET, "iiii", "Color of an evas object."), + EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_VISIBILITY_SET, "b", "Visibility of an evas object."), + EOBJ_OP_DESCRIPTION(EVAS_OBJ_SUB_ID_CHILD_ADD, "o", "Add a child eobj."), + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Class_Description class_desc = { + "Evas Object", + EOBJ_CLASS_TYPE_REGULAR_NO_INSTANT, + EOBJ_CLASS_DESCRIPTION_OPS(&EVAS_OBJ_BASE_ID, op_desc, EVAS_OBJ_SUB_ID_LAST), + NULL, + sizeof(Widget_Data), + _constructor, + _destructor, + _class_constructor, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, EOBJ_CLASS_BASE, NULL); +} diff --git a/legacy/eobj/examples/evas/evas_obj.h b/legacy/eobj/examples/evas/evas_obj.h new file mode 100644 index 0000000000..1f2a50f417 --- /dev/null +++ b/legacy/eobj/examples/evas/evas_obj.h @@ -0,0 +1,45 @@ +#ifndef EVAS_OBJ_H +#define EVAS_OBJ_H + +#include "eobj.h" + +extern EAPI Eobj_Op EVAS_OBJ_BASE_ID; + +enum { + EVAS_OBJ_SUB_ID_POSITION_SET, + EVAS_OBJ_SUB_ID_SIZE_SET, + EVAS_OBJ_SUB_ID_COLOR_SET, + EVAS_OBJ_SUB_ID_COLOR_GET, + EVAS_OBJ_SUB_ID_VISIBILITY_SET, + EVAS_OBJ_SUB_ID_CHILD_ADD, + EVAS_OBJ_SUB_ID_LAST +}; + +#define EVAS_OBJ_ID(sub_id) (EVAS_OBJ_BASE_ID + sub_id) + +#define EVAS_OBJ_POSITION_SET(x, y) EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_POSITION_SET), EOBJ_TYPECHECK(Evas_Coord, x), EOBJ_TYPECHECK(Evas_Coord, y) +#define EVAS_OBJ_SIZE_SET(w, h) EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_SIZE_SET), EOBJ_TYPECHECK(Evas_Coord, w), EOBJ_TYPECHECK(Evas_Coord, h) +#define EVAS_OBJ_COLOR_SET(r, g, b, a) EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_SET), EOBJ_TYPECHECK(int, r), EOBJ_TYPECHECK(int, g), EOBJ_TYPECHECK(int, b), EOBJ_TYPECHECK(int, a) +#define EVAS_OBJ_COLOR_GET(r, g, b, a) EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_COLOR_GET), EOBJ_TYPECHECK(int *, r), EOBJ_TYPECHECK(int *, g), EOBJ_TYPECHECK(int *, b), EOBJ_TYPECHECK(int *, a) +#define EVAS_OBJ_VISIBILITY_SET(v) EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_VISIBILITY_SET), EOBJ_TYPECHECK(Eina_Bool, v) +#define EVAS_OBJ_CHILD_ADD(child) EVAS_OBJ_ID(EVAS_OBJ_SUB_ID_CHILD_ADD), EOBJ_TYPECHECK(Eobj *, child) + +#define EVAS_OBJ_CLASS evas_object_class_get() +const Eobj_Class *evas_object_class_get(void) EINA_CONST; + +#define EVAS_OBJ_STR "Evas_Obj" +/* FIXME: Hack in the meanwhile. */ +static inline Evas_Object * +eobj_evas_object_get(Eobj *obj) +{ + return eobj_generic_data_get(obj, EVAS_OBJ_STR); +} + +/* FIXME: Hack in the meanwhile. */ +static inline void +eobj_evas_object_set(Eobj *obj, Evas_Object *evas_obj) +{ + eobj_generic_data_set(obj, EVAS_OBJ_STR, evas_obj); +} + +#endif diff --git a/legacy/eobj/examples/evas/test.c b/legacy/eobj/examples/evas/test.c new file mode 100644 index 0000000000..0145cbb33e --- /dev/null +++ b/legacy/eobj/examples/evas/test.c @@ -0,0 +1,64 @@ +#include + +#include "evas_obj.h" +#include "elw_button.h" +#include "elw_box.h" +#include "elw_boxedbutton.h" +#include "elw_win.h" + +Eina_Bool +_btn_clicked_cb(void *data, Eobj *obj, const Eobj_Event_Description *desc, void *event_info) +{ + (void) obj; + (void) event_info; + const Eobj_Class *klass = eobj_class_get(obj); + printf("%s obj-type:'%s' data:'%s'\n", desc->name, eobj_class_name_get(klass), (const char *) data); + + return EINA_TRUE; +} + +int +main(int argc, char *argv[]) +{ + Evas_Coord winw, winh; + { + winw = 400; + winh = 400; + } + + elm_init(argc, argv); + eobj_init(); + + Eobj *win = eobj_add(ELW_WIN_CLASS, NULL); + eobj_do(win, EVAS_OBJ_SIZE_SET(winw, winh), EVAS_OBJ_VISIBILITY_SET(EINA_TRUE)); + + Eobj *bt = eobj_add(ELW_BUTTON_CLASS, win); + eobj_do(bt, EVAS_OBJ_POSITION_SET(25, 25), + EVAS_OBJ_SIZE_SET(50, 50), + EVAS_OBJ_COLOR_SET(255, 0, 0, 255), + ELW_BUTTON_TEXT_SET("Click"), + EVAS_OBJ_VISIBILITY_SET(EINA_TRUE)); + eobj_event_callback_add(bt, SIG_CLICKED, _btn_clicked_cb, "btn"); + + int r, g, b, a; + eobj_do(bt, EVAS_OBJ_COLOR_GET(&r, &g, &b, &a)); + printf("RGBa(%d, %d, %d, %d)\n", r, g, b, a); + + Eobj *bx = eobj_add(ELW_BOXEDBUTTON_CLASS, win); + eobj_do(bx, EVAS_OBJ_POSITION_SET(100, 100), + EVAS_OBJ_SIZE_SET(70, 70), + EVAS_OBJ_COLOR_SET(0, 0, 255, 255), + ELW_BUTTON_TEXT_SET("Click2"), + EVAS_OBJ_VISIBILITY_SET(EINA_TRUE)); + eobj_event_callback_add(bx, SIG_CLICKED, _btn_clicked_cb, "bxedbtn"); + + elm_run(); + + eobj_unref(bx); + eobj_unref(bt); + eobj_unref(win); + eobj_shutdown(); + elm_shutdown(); + return 0; +} + diff --git a/legacy/eobj/examples/mixin/CMakeLists.txt b/legacy/eobj/examples/mixin/CMakeLists.txt new file mode 100644 index 0000000000..21393aef77 --- /dev/null +++ b/legacy/eobj/examples/mixin/CMakeLists.txt @@ -0,0 +1,23 @@ +LIST(APPEND MIXIN_CC_SOURCES + main.c + simple.c + mixin.c + ) + +include_directories( + ${EINA_INCLUDE_DIRS} + ${EVAS_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/lib + ) + +add_executable(mixin ${MIXIN_CC_SOURCES}) + +get_target_property(eobj_LIB_FILE eobj LOCATION) +target_link_libraries(mixin + ${EINA_LIBRARIES} + ${eobj_LIB_FILE} + ) + +add_dependencies(mixin eobj) + +add_test(Example_mixin mixin) diff --git a/legacy/eobj/examples/mixin/main.c b/legacy/eobj/examples/mixin/main.c new file mode 100644 index 0000000000..47987f413c --- /dev/null +++ b/legacy/eobj/examples/mixin/main.c @@ -0,0 +1,23 @@ +#include "eobj.h" +#include "simple.h" +#include "mixin.h" + +int +main(int argc, char *argv[]) +{ + (void) argc; + (void) argv; + eobj_init(); + + Eobj *obj = eobj_add(SIMPLE_CLASS, NULL); + + eobj_do(obj, SIMPLE_A_SET(1), SIMPLE_B_SET(2)); + + int a, b; + eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b), MIXIN_ADD_AND_PRINT(5)); + + eobj_unref(obj); + eobj_shutdown(); + return 0; +} + diff --git a/legacy/eobj/examples/mixin/mixin.c b/legacy/eobj/examples/mixin/mixin.c new file mode 100644 index 0000000000..365e4057d6 --- /dev/null +++ b/legacy/eobj/examples/mixin/mixin.c @@ -0,0 +1,67 @@ +#include "eobj.h" +#include "mixin.h" +#include "simple.h" + +EAPI Eobj_Op MIXIN_BASE_ID = 0; + +static Eobj_Class *_my_class = NULL; + +static void +_add_and_print_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + (void) op; + int a, b, x; + eobj_do(obj, SIMPLE_A_GET(&a), SIMPLE_B_GET(&b)); + x = va_arg(*list, const int); + printf("%s %d\n", __func__, a + b + x); +} + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), _add_and_print_set), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +mixin_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(MIXIN_SUB_ID_ADD_AND_SET, "i", "Add A + B + param and print it"), + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Class_Description class_desc = { + "Mixin", + EOBJ_CLASS_TYPE_MIXIN, + EOBJ_CLASS_DESCRIPTION_OPS(&MIXIN_BASE_ID, op_desc, MIXIN_SUB_ID_LAST), + NULL, + 0, + _constructor, + _destructor, + _class_constructor, + NULL + }; + + _my_class = eobj_class_new(&class_desc, EOBJ_CLASS_BASE, NULL); + + return _my_class; +} diff --git a/legacy/eobj/examples/mixin/mixin.h b/legacy/eobj/examples/mixin/mixin.h new file mode 100644 index 0000000000..d5efae20ca --- /dev/null +++ b/legacy/eobj/examples/mixin/mixin.h @@ -0,0 +1,20 @@ +#ifndef MIXIN_H +#define MIXIN_H + +#include "eobj.h" + +extern EAPI Eobj_Op MIXIN_BASE_ID; + +enum { + MIXIN_SUB_ID_ADD_AND_SET, + MIXIN_SUB_ID_LAST +}; + +#define MIXIN_ID(sub_id) (MIXIN_BASE_ID + sub_id) + +#define MIXIN_ADD_AND_PRINT(x) MIXIN_ID(MIXIN_SUB_ID_ADD_AND_SET), EOBJ_TYPECHECK(int, x) + +#define MIXIN_CLASS mixin_class_get() +const Eobj_Class *mixin_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/mixin/simple.c b/legacy/eobj/examples/mixin/simple.c new file mode 100644 index 0000000000..57e3eb10f1 --- /dev/null +++ b/legacy/eobj/examples/mixin/simple.c @@ -0,0 +1,92 @@ +#include "eobj.h" +#include "mixin.h" +#include "simple.h" + +EAPI Eobj_Op SIMPLE_BASE_ID = 0; + +typedef struct +{ + int a; + int b; +} Private_Data; + +static Eobj_Class *_my_class = NULL; + +#define _GET_SET_FUNC(name) \ +static void \ +_##name##_get(Eobj *obj, Eobj_Op op, va_list *list) \ +{ \ + Private_Data *pd = eobj_data_get(obj, _my_class); \ + (void) op; \ + int *name; \ + name = va_arg(*list, int *); \ + *name = pd->name; \ + printf("%s %d\n", __func__, pd->name); \ +} \ +static void \ +_##name##_set(Eobj *obj, Eobj_Op op, va_list *list) \ +{ \ + Private_Data *pd = eobj_data_get(obj, _my_class); \ + (void) op; \ + int name; \ + name = va_arg(*list, int); \ + pd->name = name; \ + printf("%s %d\n", __func__, pd->name); \ +} + +_GET_SET_FUNC(a) +_GET_SET_FUNC(b) + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set), + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_A_GET), _a_get), + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_B_SET), _b_set), + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_B_GET), _b_get), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +simple_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"), + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_GET, "i", "Get property A"), + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_SET, "i", "Set property B"), + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_B_GET, "i", "Get property B"), + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Class_Description class_desc = { + "Simple", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST), + NULL, + sizeof(Private_Data), + _constructor, + _destructor, + _class_constructor, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, EOBJ_CLASS_BASE, MIXIN_CLASS, NULL); +} diff --git a/legacy/eobj/examples/mixin/simple.h b/legacy/eobj/examples/mixin/simple.h new file mode 100644 index 0000000000..4baf2b0dd5 --- /dev/null +++ b/legacy/eobj/examples/mixin/simple.h @@ -0,0 +1,26 @@ +#ifndef SIMPLE_H +#define SIMPLE_H + +#include "eobj.h" + +extern EAPI Eobj_Op SIMPLE_BASE_ID; + +enum { + SIMPLE_SUB_ID_A_SET, + SIMPLE_SUB_ID_A_GET, + SIMPLE_SUB_ID_B_SET, + SIMPLE_SUB_ID_B_GET, + SIMPLE_SUB_ID_LAST +}; + +#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id) + +#define SIMPLE_A_SET(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EOBJ_TYPECHECK(int, a) +#define SIMPLE_A_GET(a) SIMPLE_ID(SIMPLE_SUB_ID_A_GET), EOBJ_TYPECHECK(int *, a) +#define SIMPLE_B_SET(b) SIMPLE_ID(SIMPLE_SUB_ID_B_SET), EOBJ_TYPECHECK(int, b) +#define SIMPLE_B_GET(b) SIMPLE_ID(SIMPLE_SUB_ID_B_GET), EOBJ_TYPECHECK(int *, b) + +#define SIMPLE_CLASS simple_class_get() +const Eobj_Class *simple_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/examples/signals/CMakeLists.txt b/legacy/eobj/examples/signals/CMakeLists.txt new file mode 100644 index 0000000000..151fa7a682 --- /dev/null +++ b/legacy/eobj/examples/signals/CMakeLists.txt @@ -0,0 +1,22 @@ +LIST(APPEND SIGNALS_CC_SOURCES + main.c + simple.c + ) + +include_directories( + ${EINA_INCLUDE_DIRS} + ${EVAS_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/lib + ) + +add_executable(signals ${SIGNALS_CC_SOURCES}) + +get_target_property(eobj_LIB_FILE eobj LOCATION) +target_link_libraries(signals + ${EINA_LIBRARIES} + ${eobj_LIB_FILE} + ) + +add_dependencies(signals eobj) + +add_test(Example_signals signals) diff --git a/legacy/eobj/examples/signals/main.c b/legacy/eobj/examples/signals/main.c new file mode 100644 index 0000000000..7ebb78ca1a --- /dev/null +++ b/legacy/eobj/examples/signals/main.c @@ -0,0 +1,42 @@ +#include "eobj.h" +#include "simple.h" + +static Eina_Bool +_a_changed_cb(void *data, Eobj *obj, const Eobj_Event_Description *desc, void *event_info) +{ + /* FIXME: Actually print it. */ + (void) desc; + (void) obj; + int new_a = *((int *) event_info); + printf("%s event_info:'%d' data:'%s'\n", __func__, new_a, (const char *) data); + + /* Fix data is NULL, stop. */ + return !!data; +} + +int +main(int argc, char *argv[]) +{ + (void) argc; + (void) argv; + eobj_init(); + + Eobj *obj = eobj_add(SIMPLE_CLASS, NULL); + + /* The order of these two is undetermined. */ + eobj_event_callback_priority_add(obj, SIG_A_CHANGED, EOBJ_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, "CALLED"); + eobj_event_callback_priority_add(obj, SIG_A_CHANGED, EOBJ_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, "CALLED2"); + /* This will be called afterwards. */ + eobj_event_callback_priority_add(obj, SIG_A_CHANGED, EOBJ_CALLBACK_PRIORITY_DEFAULT, _a_changed_cb, NULL); + /* This will never be called because the previous callback returns NULL. */ + eobj_event_callback_priority_add(obj, SIG_A_CHANGED, EOBJ_CALLBACK_PRIORITY_AFTER, _a_changed_cb, "NOT CALLED"); + + eobj_do(obj, SIMPLE_A_SET(1)); + + eobj_event_callback_del_full(obj, SIG_A_CHANGED, _a_changed_cb, NULL); + + eobj_unref(obj); + eobj_shutdown(); + return 0; +} + diff --git a/legacy/eobj/examples/signals/simple.c b/legacy/eobj/examples/signals/simple.c new file mode 100644 index 0000000000..ae5bbd3285 --- /dev/null +++ b/legacy/eobj/examples/signals/simple.c @@ -0,0 +1,119 @@ +#include "eobj.h" +#include "simple.h" + +EAPI Eobj_Op SIMPLE_BASE_ID = 0; + +typedef struct +{ + int a; +} Private_Data; + +EAPI const Eobj_Event_Description _SIG_A_CHANGED = + EOBJ_EVENT_DESCRIPTION("a,changed", "i", "Called when a has changed."); + +static Eobj_Class *_my_class = NULL; + +static void +_a_set(Eobj *obj, Eobj_Op op, va_list *list) +{ + Private_Data *pd = eobj_data_get(obj, _my_class); + (void) op; + int a; + a = va_arg(*list, int); + pd->a = a; + printf("%s %d\n", __func__, pd->a); + + eobj_event_callback_call(obj, SIG_A_CHANGED, &pd->a); +} + +Eina_Bool +_cb_added(void *data, Eobj *obj, const Eobj_Event_Description *desc, void *event_info) +{ + const Eobj_Event_Description *cb_desc = event_info; + (void) data; + (void) desc; + + if (cb_desc != SIG_A_CHANGED) + return EINA_TRUE; + + int count = (int) eobj_generic_data_get(obj, "cb_count") + 1; + eobj_generic_data_set(obj, "cb_count", (void *) count); + + printf("Added SIG_A_CHANGED callback to %p. Count: %d\n", obj, count); + return EINA_TRUE; +} + +Eina_Bool +_cb_deled(void *data, Eobj *obj, const Eobj_Event_Description *desc, void *event_info) +{ + const Eobj_Event_Description *cb_desc = event_info; + (void) data; + (void) desc; + + if (cb_desc != SIG_A_CHANGED) + return EINA_TRUE; + + int count = (int) eobj_generic_data_get(obj, "cb_count") - 1; + eobj_generic_data_set(obj, "cb_count", (void *) count); + + printf("Removed SIG_A_CHANGED callback from %p. Count: %d\n", obj, count); + return EINA_TRUE; +} + +static void +_constructor(Eobj *obj) +{ + eobj_constructor_super(obj); + + eobj_event_callback_add(obj, EOBJ_SIG_CALLBACK_ADD, _cb_added, NULL); + eobj_event_callback_add(obj, EOBJ_SIG_CALLBACK_DEL, _cb_deled, NULL); + + eobj_generic_data_set(obj, "cb_count", (intptr_t) 0); +} + +static void +_destructor(Eobj *obj) +{ + eobj_destructor_super(obj); +} + +static void +_class_constructor(Eobj_Class *klass) +{ + const Eobj_Op_Func_Description func_desc[] = { + EOBJ_OP_FUNC_DESCRIPTION(SIMPLE_ID(SIMPLE_SUB_ID_A_SET), _a_set), + EOBJ_OP_FUNC_DESCRIPTION_SENTINEL + }; + + eobj_class_funcs_set(klass, func_desc); +} + +const Eobj_Class * +simple_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Op_Description op_desc[] = { + EOBJ_OP_DESCRIPTION(SIMPLE_SUB_ID_A_SET, "i", "Set property A"), + EOBJ_OP_DESCRIPTION_SENTINEL + }; + + static const Eobj_Event_Description *event_desc[] = { + SIG_A_CHANGED, + NULL + }; + + static const Eobj_Class_Description class_desc = { + "Simple", + EOBJ_CLASS_TYPE_REGULAR, + EOBJ_CLASS_DESCRIPTION_OPS(&SIMPLE_BASE_ID, op_desc, SIMPLE_SUB_ID_LAST), + event_desc, + sizeof(Private_Data), + _constructor, + _destructor, + _class_constructor, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, EOBJ_CLASS_BASE, NULL); +} diff --git a/legacy/eobj/examples/signals/simple.h b/legacy/eobj/examples/signals/simple.h new file mode 100644 index 0000000000..10fe63929b --- /dev/null +++ b/legacy/eobj/examples/signals/simple.h @@ -0,0 +1,23 @@ +#ifndef SIMPLE_H +#define SIMPLE_H + +#include "eobj.h" + +extern EAPI Eobj_Op SIMPLE_BASE_ID; + +enum { + SIMPLE_SUB_ID_A_SET, + SIMPLE_SUB_ID_LAST +}; + +#define SIMPLE_ID(sub_id) (SIMPLE_BASE_ID + sub_id) + +#define SIMPLE_A_SET(a) SIMPLE_ID(SIMPLE_SUB_ID_A_SET), EOBJ_TYPECHECK(int, a) + +extern const Eobj_Event_Description _SIG_A_CHANGED; +#define SIG_A_CHANGED (&(_SIG_A_CHANGED)) + +#define SIMPLE_CLASS simple_class_get() +const Eobj_Class *simple_class_get(void) EINA_CONST; + +#endif diff --git a/legacy/eobj/lib/CMakeLists.txt b/legacy/eobj/lib/CMakeLists.txt new file mode 100644 index 0000000000..37ecd6d2c9 --- /dev/null +++ b/legacy/eobj/lib/CMakeLists.txt @@ -0,0 +1,19 @@ +LIST(APPEND EOBJ_CC_SOURCES + eobj.c + ) + +include_directories( + ${EINA_INCLUDE_DIRS} + ) + +add_library(eobj SHARED ${EOBJ_CC_SOURCES}) +target_link_libraries(eobj + ${EINA_LIBRARIES} + ${EFL_COVERAGE_LIBS} + ) + +set_target_properties(eobj PROPERTIES + COMPILE_FLAGS "${EFL_COVERAGE_CFLAGS}") +set_target_properties(eobj PROPERTIES + VERSION ${EOBJ_VERSION} SOVERSION ${EOBJ_VERSION_MAJOR}) +set_target_properties(eobj PROPERTIES OUTPUT_NAME "eobj") diff --git a/legacy/eobj/lib/eobj.c b/legacy/eobj/lib/eobj.c new file mode 100644 index 0000000000..c656750f31 --- /dev/null +++ b/legacy/eobj/lib/eobj.c @@ -0,0 +1,1125 @@ +#include +#include + +#include "eobj.h" + +static int _eobj_log_dom = -1; + +static Eobj_Class **classes; +static Eobj_Class_Id classes_last_id; +static Eina_Bool _eobj_init_count = 0; + +#define CONSTRUCT_ERROR_KEY "__construct_error" + +static void _eobj_callback_remove_all(Eobj *obj); +static void _eobj_generic_data_del_all(Eobj *obj); +static void eobj_class_constructor(Eobj *obj, const Eobj_Class *klass); +static void eobj_class_destructor(Eobj *obj, const Eobj_Class *klass); + +#ifdef CRITICAL +#undef CRITICAL +#endif +#define CRITICAL(...) EINA_LOG_DOM_CRIT(_eobj_log_dom, __VA_ARGS__) + +#ifdef ERR +#undef ERR +#endif +#define ERR(...) EINA_LOG_DOM_ERR(_eobj_log_dom, __VA_ARGS__) + +#ifdef WRN +#undef WRN +#endif +#define WRN(...) EINA_LOG_DOM_WARN(_eobj_log_dom, __VA_ARGS__) + +#ifdef INF +#undef INF +#endif +#define INF(...) EINA_LOG_DOM_INFO(_eobj_log_dom, __VA_ARGS__) + +#ifdef DBG +#undef DBG +#endif +#define DBG(...) EINA_LOG_DOM_DBG(_eobj_log_dom, __VA_ARGS__) + +typedef struct _Eobj_Callback_Description Eobj_Callback_Description; + +struct _Eobj { + Eobj *parent; + const Eobj_Class *klass; + void *data_blob; + void **datas; + int refcount; + Eina_List *composite_objects; + + Eina_Inlist *callbacks; + int walking_list; + + Eina_Inlist *generic_data; + + const Eobj_Class *kls_itr; + + Eina_Bool delete:1; + EINA_MAGIC +}; + +/* Start of Dich */ +/* Dich search, split to 0xff 0xff 0xffff */ + +#define DICH_CHAIN1_MASK (0xff) +#define DICH_CHAIN2_MASK (0xff) +#define DICH_CHAIN_LAST_MASK (0xffff) +#define DICH_CHAIN1_SIZE (DICH_CHAIN1_MASK + 1) +#define DICH_CHAIN2_SIZE (DICH_CHAIN2_MASK + 1) +#define DICH_CHAIN_LAST_SIZE (DICH_CHAIN_LAST_MASK + 1) +#define DICH_CHAIN1(x) (((x) >> 24) & DICH_CHAIN1_MASK) +#define DICH_CHAIN2(x) (((x) >> 16) & DICH_CHAIN2_MASK) +#define DICH_CHAIN_LAST(x) ((x) & DICH_CHAIN_LAST_MASK) + +#define OP_CLASS_OFFSET 16 +#define OP_CLASS_OFFSET_GET(x) (((x) >> OP_CLASS_OFFSET) & 0xffff) +#define OP_CLASS_GET(op) ({ \ + Eobj_Class_Id tmp = OP_CLASS_OFFSET_GET(op); \ + (Eobj_Class *) ((tmp <= classes_last_id) && (tmp > 0)) ? \ + (classes[tmp - 1]) : NULL; \ + }) + +/* Structure of Eobj_Op is: + * 16bit: class + * 16bit: op. + */ + +typedef struct _Dich_Chain1 Dich_Chain1; + +typedef struct +{ + eobj_op_func_type func; +} op_type_funcs; + +typedef struct +{ + op_type_funcs *funcs; +} Dich_Chain2; + +struct _Dich_Chain1 +{ + Dich_Chain2 *chain; +}; + +typedef struct { + EINA_INLIST; + const Eobj_Class *klass; + Eina_Bool exists : 1; /* < True if already exists in class (incl parents). */ +} Eobj_Extension_Node; + +struct _Eobj_Class +{ + Eobj_Class_Id class_id; + const Eobj_Class *parent; + const Eobj_Class_Description *desc; + Dich_Chain1 chain[DICH_CHAIN1_SIZE]; + Eina_Inlist *extensions; + Eina_Bool constructed : 1; +}; + +static inline eobj_op_func_type +dich_func_get(const Eobj_Class *klass, Eobj_Op op) +{ + const Dich_Chain1 *chain1 = &klass->chain[DICH_CHAIN1(op)]; + if (!chain1) return NULL; + if (!chain1->chain) return NULL; + Dich_Chain2 *chain2 = &chain1->chain[DICH_CHAIN2(op)]; + if (!chain2) return NULL; + if (!chain2->funcs) return NULL; + + /* num_ops is calculated from the class. */ + const Eobj_Class *op_klass = OP_CLASS_GET(op); + if (!op_klass || (DICH_CHAIN_LAST(op) >= op_klass->desc->ops.count)) + return NULL; + + return chain2->funcs[DICH_CHAIN_LAST(op)].func; +} + +static inline void +dich_func_set(Eobj_Class *klass, Eobj_Op op, eobj_op_func_type func) +{ + const Eobj_Class *op_klass = OP_CLASS_GET(op); + size_t num_ops; + + /* Verify op is valid. */ + if (op_klass) + { + /* num_ops is calculated from the class. */ + num_ops = op_klass->desc->ops.count; + if (DICH_CHAIN_LAST(op) >= num_ops) + { + ERR("OP %x is too big for the domain '%s', expected value < %x.", + op, op_klass->desc->name, op_klass->desc->ops.count); + } + } + else + { + ERR("OP %x is from an illegal class.", op); + return; + } + + Dich_Chain1 *chain1 = &klass->chain[DICH_CHAIN1(op)]; + if (!chain1->chain) + { + klass->chain[DICH_CHAIN1(op)].chain = + chain1->chain = + calloc(DICH_CHAIN2_SIZE, sizeof(*(chain1->chain))); + } + + Dich_Chain2 *chain2 = &chain1->chain[DICH_CHAIN2(op)]; + if (!chain2->funcs) + { + chain2->funcs = chain1->chain[DICH_CHAIN2(op)].funcs = + calloc(num_ops, sizeof(*(chain2->funcs))); + } + + chain2->funcs[DICH_CHAIN_LAST(op)].func = func; +} + +static inline void +dich_func_clean_all(Eobj_Class *klass) +{ + int i; + Dich_Chain1 *chain1 = klass->chain; + + for (i = 0 ; i < DICH_CHAIN1_SIZE ; i++, chain1++) + { + int j; + Dich_Chain2 *chain2 = chain1->chain; + + if (!chain2) + continue; + + for (j = 0 ; j < DICH_CHAIN2_SIZE ; j++, chain2++) + { + free(chain2->funcs); + } + free(chain1->chain); + chain1->chain = NULL; + } +} + +/* END OF DICH */ + +/* FIXME: Decide if it should be fast, and if so, add a mapping. + * Otherwise, this is very slow. But since it's only for debugging... */ +static const Eobj_Op_Description * +_eobj_op_id_desc_get(Eobj_Op op) +{ + int i; + Eobj_Class **cls_itr = classes; + + for (i = 0 ; i < classes_last_id ; i++, cls_itr++) + { + if (*cls_itr) + { + const Eobj_Op_Description *desc = (*cls_itr)->desc->ops.descs; + if (!desc) + continue; + + Eobj_Op base_op_id = *(*cls_itr)->desc->ops.base_op_id; + while (desc->sub_op) + { + if ((base_op_id + desc->sub_op) == op) + return desc; + desc++; + } + } + } + + return NULL; +} + +static Eina_Bool +_eobj_op_internal(Eobj *obj, const Eobj_Class *obj_klass, Eobj_Op op, va_list *p_list) +{ + const Eobj_Class *klass = obj_klass; + eobj_op_func_type func; + + if (!obj_klass) + return EINA_FALSE; + + while (klass) + { + func = dich_func_get(klass, op); + + if (func) + { + func(obj, op, p_list); + return EINA_TRUE; + } + else + { + klass = klass->parent; + } + } + + if (!klass) + { + klass = obj_klass; + /* FIXME: Should probably flatten everything. to be faster. */ + { + /* Try MIXINS */ + Eobj_Extension_Node *itr; + EINA_INLIST_FOREACH(klass->extensions, itr) + { + if (_eobj_op_internal(obj, itr->klass, op, p_list)) + { + return EINA_TRUE; + } + } + } + + /* Try composite objects */ + { + Eina_List *itr; + Eobj *emb_obj; + EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj) + { + if (_eobj_op_internal(emb_obj, eobj_class_get(emb_obj), op, p_list)) + { + return EINA_TRUE; + } + } + } + + /* If haven't found anything, return FALSE */ + return EINA_FALSE; + } + + return EINA_TRUE; +} + +static inline Eina_Bool +_eobj_ops_internal(Eobj *obj, const Eobj_Class *obj_klass, va_list *p_list) +{ + Eina_Bool ret = EINA_TRUE; + Eobj_Op op = 0; + + op = va_arg(*p_list, Eobj_Op); + while (op) + { + if (!_eobj_op_internal(obj, obj_klass, op, p_list)) + { + const Eobj_Op_Description *desc = _eobj_op_id_desc_get(op); + const char *_id_name = (desc) ? desc->name : NULL; + const Eobj_Class *op_klass = OP_CLASS_GET(op); + const char *_dom_name = (op_klass) ? op_klass->desc->name : NULL; + ERR("Can't find func for op %x ('%s' of domain '%s') for class '%s'. Aborting.", + op, _id_name, _dom_name, + obj_klass->desc->name); + ret = EINA_FALSE; + break; + } + op = va_arg(*p_list, Eobj_Op); + } + + va_end(*p_list); + + return ret; +} + +EAPI Eina_Bool +eobj_do_internal(Eobj *obj, ...) +{ + Eina_Bool ret; + va_list p_list; + va_start(p_list, obj); + ret = _eobj_ops_internal(obj, eobj_class_get(obj), &p_list); + va_end(p_list); + return ret; +} + +EAPI Eina_Bool +eobj_class_do_internal(Eobj *obj, const Eobj_Class *klass, ...) +{ + Eina_Bool ret; + va_list p_list; + va_start(p_list, klass); + ret = _eobj_ops_internal(obj, klass, &p_list); + va_end(p_list); + return ret; +} + +EAPI const Eobj_Class * +eobj_class_get(Eobj *obj) +{ + return obj->klass; +} + +EAPI const Eobj_Class * +eobj_class_parent_get(const Eobj_Class *klass) +{ + return klass->parent; +} + +EAPI const char * +eobj_class_name_get(const Eobj_Class *klass) +{ + return klass->desc->name; +} + +static void +_eobj_class_base_op_init(Eobj_Class *klass) +{ + const Eobj_Class_Description *desc = klass->desc; + if (!desc || !desc->ops.base_op_id) + return; + + /* FIXME: Depends on values defined above! */ + *(desc->ops.base_op_id) = klass->class_id << OP_CLASS_OFFSET; +} + +static void +_eobj_class_constructor(Eobj_Class *klass) +{ + if (klass->constructed) + return; + + klass->constructed = EINA_TRUE; + + if (!klass->desc->class_constructor) + return; + + klass->desc->class_constructor(klass); +} + +EAPI void +eobj_class_funcs_set(Eobj_Class *klass, const Eobj_Op_Func_Description *func_descs) +{ + const Eobj_Op_Func_Description *itr; + itr = func_descs; + if (itr) + { + for ( ; itr->op != 0 ; itr++) + { + dich_func_set(klass, itr->op, itr->func); + } + } +} + +static Eina_Bool +_eobj_class_extn_exists(const Eobj_Class *klass, const Eobj_Class *extn_cls) +{ + while (klass) + { + Eobj_Extension_Node *extn; + EINA_INLIST_FOREACH(klass->extensions, extn) + { + if (extn->klass == extn_cls) + return EINA_TRUE; + } + + klass = klass->parent; + } + + return EINA_FALSE; +} + +EAPI Eobj_Class * +eobj_class_new(const Eobj_Class_Description *desc, const Eobj_Class *parent, ...) +{ + Eobj_Class *klass; + va_list p_list; + + va_start(p_list, parent); + +#define _CLS_NEW_CHECK(x) \ + do \ + { \ + if (!x) \ + { \ + ERR("%s can't be NULL! Aborting.", #x); \ + return NULL; \ + } \ + } \ + while(0) + + _CLS_NEW_CHECK(desc); + _CLS_NEW_CHECK(desc->name); + _CLS_NEW_CHECK(desc->constructor); + _CLS_NEW_CHECK(desc->destructor); + + klass = calloc(1, sizeof(Eobj_Class)); + klass->parent = parent; + klass->class_id = ++classes_last_id; + { + /* FIXME: Handle errors. */ + Eobj_Class **tmp; + tmp = realloc(classes, classes_last_id * sizeof(*classes)); + classes = tmp; + classes[klass->class_id - 1] = klass; + } + + /* Handle class extensions */ + { + Eobj_Class *extn = NULL; + + extn = va_arg(p_list, Eobj_Class *); + while (extn) + { + switch (extn->desc->type) + { + case EOBJ_CLASS_TYPE_REGULAR: + case EOBJ_CLASS_TYPE_REGULAR_NO_INSTANT: + /* Use it like an interface. */ + case EOBJ_CLASS_TYPE_INTERFACE: + break; + case EOBJ_CLASS_TYPE_MIXIN: + { + Eobj_Extension_Node *node = calloc(1, sizeof(*node)); + node->klass = extn; + node->exists = _eobj_class_extn_exists(klass, extn); + klass->extensions = + eina_inlist_append(klass->extensions, + EINA_INLIST_GET(node)); + } + break; + } + + extn = va_arg(p_list, Eobj_Class *); + } + } + + klass->desc = desc; + _eobj_class_base_op_init(klass); + + /* FIXME: Shouldn't be called here - should be called from eobj_add. */ + _eobj_class_constructor(klass); + + va_end(p_list); + + return klass; +} +#undef _CLS_NEW_CHECK + +EAPI void +eobj_class_free(Eobj_Class *klass) +{ + if (klass->constructed) + { + if (klass->desc->class_destructor) + klass->desc->class_destructor(klass); + + dich_func_clean_all(klass); + } + + { + Eina_Inlist *itrn; + Eobj_Extension_Node *extn; + EINA_INLIST_FOREACH_SAFE(klass->extensions, itrn, extn) + { + free(extn); + } + } + + free(klass); +} + +static int +_eobj_class_count_parents(const Eobj_Class *klass) +{ + int count = 0; + + for (count = 0 ; klass->parent ; klass = klass->parent) + count++; + + return count; +} + +EAPI Eobj * +eobj_add(const Eobj_Class *klass, Eobj *parent) +{ + if (klass->desc->type != EOBJ_CLASS_TYPE_REGULAR) + { + ERR("Class '%s' is not instantiate-able. Aborting.", klass->desc->name); + return NULL; + } + + Eobj *obj = calloc(1, sizeof(*obj)); + obj->klass = klass; + obj->parent = parent; + + obj->refcount++; + { + size_t datas_count = 0; + intptr_t offset = 0; + size_t i; + const Eobj_Class *kls_itr; + void **pvt_itr; + datas_count = _eobj_class_count_parents(klass) + 1; + + obj->datas = calloc(datas_count, sizeof(*(obj->datas))); + + /* Calculate all the offsets and set in the datas array. */ + pvt_itr = obj->datas + datas_count - 1; + for (kls_itr = klass ; kls_itr->parent ; kls_itr = kls_itr->parent) + { + *pvt_itr = (void *) offset; + + /* FIXME: Make sure this alignment is enough. */ + offset += kls_itr->desc->private_size + + (sizeof(void *) - + (kls_itr->desc->private_size % sizeof(void *))); + pvt_itr--; + } + + /* Allocate the datas blob and update the offsets. */ + obj->data_blob = calloc(1, offset); + + pvt_itr = obj->datas; + for (i = 0 ; i < datas_count ; i++) + { + *pvt_itr = ((char *) obj->data_blob) + (intptr_t) *pvt_itr; + + pvt_itr++; + } + } + + eobj_class_constructor(obj, klass); + if (obj->kls_itr && obj->kls_itr->parent) + { + ERR("Type '%s' - Not all of the object constructors have been executed.", klass->desc->name); + goto fail; + } + + if (eobj_generic_data_get(obj, CONSTRUCT_ERROR_KEY)) + { + ERR("Type '%s' - One of the object constructors have failed.", klass->desc->name); + goto fail; + } + + return obj; + +fail: + eobj_unref(obj); + return NULL; +} + +Eobj * +eobj_ref(Eobj *obj) +{ + obj->refcount++; + return obj; +} + +EAPI void +eobj_unref(Eobj *obj) +{ + if (--(obj->refcount) == 0) + { + const Eobj_Class *klass = eobj_class_get(obj); + eobj_class_destructor(obj, klass); + /*FIXME: add eobj_class_unref(klass) ? - just to clear the caches. */ + + Eina_List *itr, *itr_n; + Eobj *emb_obj; + EINA_LIST_FOREACH_SAFE(obj->composite_objects, itr, itr_n, emb_obj) + { + eobj_del(emb_obj); + obj->composite_objects = + eina_list_remove_list(obj->composite_objects, itr); + } + + _eobj_callback_remove_all(obj); + + if (obj->data_blob) + free(obj->data_blob); + free(obj->datas); + + _eobj_generic_data_del_all(obj); + + free(obj); + } +} + +EAPI void +eobj_del(Eobj *obj) +{ + obj->delete = EINA_TRUE; + eobj_unref(obj); +} + +EAPI Eobj * +eobj_parent_get(Eobj *obj) +{ + return obj->parent; +} + +EAPI void +eobj_constructor_error_set(Eobj *obj) +{ + eobj_generic_data_set(obj, CONSTRUCT_ERROR_KEY, (void *) EINA_TRUE); +} + +EAPI Eina_Bool +eobj_constructor_error_get(const Eobj *obj) +{ + return (intptr_t) eobj_generic_data_get(obj, CONSTRUCT_ERROR_KEY); +} + +static void +eobj_class_constructor(Eobj *obj, const Eobj_Class *klass) +{ + const Eobj_Extension_Node *extn; + + obj->kls_itr = klass; + + if (!klass) + return; + + EINA_INLIST_FOREACH(klass->extensions, extn) + { + /* Only call if it's the first one in the class. */ + if (!extn->exists && extn->klass->desc->constructor) + extn->klass->desc->constructor(obj); + } + + klass->desc->constructor(obj); +} + +static void +eobj_class_destructor(Eobj *obj, const Eobj_Class *klass) +{ + const Eobj_Extension_Node *extn; + + obj->kls_itr = klass; + + if (!klass) + return; + + klass->desc->destructor(obj); + + EINA_INLIST_REVERSE_FOREACH(klass->extensions, extn) + { + /* Only call if it's the first one in the class. */ + if (!extn->exists && extn->klass->desc->destructor) + extn->klass->desc->destructor(obj); + } + +} + +EAPI void +eobj_constructor_super(Eobj *obj) +{ + if (obj->kls_itr->parent) + eobj_class_constructor(obj, obj->kls_itr->parent); +} + +EAPI void +eobj_destructor_super(Eobj *obj) +{ + if (obj->kls_itr->parent) + eobj_class_destructor(obj, obj->kls_itr->parent); +} + +EAPI void * +eobj_data_get(Eobj *obj, const Eobj_Class *klass) +{ + /* FIXME: Add a check that this is of the right klass and we don't seg. + * Probably just return NULL. */ + return obj->datas[_eobj_class_count_parents(klass)]; +} + +typedef struct +{ + EINA_INLIST; + Eina_Stringshare *key; + void *data; +} Eobj_Generic_Data_Node; + +static void +_eobj_generic_data_node_free(Eobj_Generic_Data_Node *node) +{ + eina_stringshare_del(node->key); + free(node); +} + +static void +_eobj_generic_data_del_all(Eobj *obj) +{ + Eina_Inlist *nnode; + Eobj_Generic_Data_Node *node; + + EINA_INLIST_FOREACH_SAFE(obj->generic_data, nnode, node) + { + obj->generic_data = eina_inlist_remove(obj->generic_data, + EINA_INLIST_GET(node)); + + _eobj_generic_data_node_free(node); + } +} + +EAPI void * +eobj_generic_data_set(Eobj *obj, const char *key, const void *data) +{ + void *prev_data; + Eobj_Generic_Data_Node *node; + + if (!key) return NULL; + if (!data) return NULL; + + prev_data = eobj_generic_data_del(obj, key); + + node = malloc(sizeof(Eobj_Generic_Data_Node)); + node->key = eina_stringshare_add(key); + node->data = (void *) data; + obj->generic_data = eina_inlist_prepend(obj->generic_data, + EINA_INLIST_GET(node)); + + return prev_data; +} + +EAPI void * +eobj_generic_data_get(const Eobj *obj, const char *key) +{ + Eobj_Generic_Data_Node *node; + + if (!key) return NULL; + + EINA_INLIST_FOREACH(obj->generic_data, node) + { + if (!strcmp(node->key, key)) + { + ((Eobj *) obj)->generic_data = + eina_inlist_promote(obj->generic_data, EINA_INLIST_GET(node)); + return node->data; + } + } + return NULL; +} + +EAPI void * +eobj_generic_data_del(Eobj *obj, const char *key) +{ + Eobj_Generic_Data_Node *node; + + if (!key) return NULL; + + EINA_INLIST_FOREACH(obj->generic_data, node) + { + if (!strcmp(node->key, key)) + { + void *data; + + data = node->data; + obj->generic_data = eina_inlist_remove(obj->generic_data, + EINA_INLIST_GET(node)); + _eobj_generic_data_node_free(node); + return data; + } + } + return NULL; +} + +EAPI Eina_Bool +eobj_init(void) +{ + if (_eobj_init_count++ > 0) + return EINA_TRUE; + + eina_init(); + + classes = NULL; + classes_last_id = 0; + _eobj_log_dom = eina_log_domain_register("eobj", EINA_COLOR_LIGHTBLUE); + if (_eobj_log_dom < 0) + { + EINA_LOG_ERR("Could not register log domain: eobj"); + return EINA_FALSE; + } + + return EINA_TRUE; +} + +EAPI Eina_Bool +eobj_shutdown(void) +{ + int i; + Eobj_Class **cls_itr = classes; + + if (--_eobj_init_count > 0) + return EINA_TRUE; + + for (i = 0 ; i < classes_last_id ; i++, cls_itr++) + { + if (*cls_itr) + eobj_class_free(*cls_itr); + } + + if (classes) + free(classes); + + eina_log_domain_unregister(_eobj_log_dom); + _eobj_log_dom = -1; + + eina_shutdown(); + return EINA_TRUE; +} + +EAPI void +eobj_composite_object_attach(Eobj *obj, Eobj *emb_obj) +{ + eobj_ref(emb_obj); + obj->composite_objects = eina_list_prepend(obj->composite_objects, emb_obj); +} + +EAPI void +eobj_composite_object_detach(Eobj *obj, Eobj *emb_obj) +{ + obj->composite_objects = eina_list_remove(obj->composite_objects, emb_obj); + eobj_unref(emb_obj); +} + +EAPI Eina_Bool +eobj_composite_is(Eobj *emb_obj) +{ + Eobj *obj = eobj_parent_get(emb_obj); + Eina_List *itr; + Eobj *tmp; + EINA_LIST_FOREACH(obj->composite_objects, itr, tmp) + { + if (tmp == emb_obj) + return EINA_TRUE; + } + + return EINA_FALSE; +} + +/* Callbacks */ +struct _Eobj_Callback_Description +{ + EINA_INLIST; + const Eobj_Event_Description *event; + Eobj_Event_Cb func; + void *func_data; + Eobj_Callback_Priority priority; + Eina_Bool delete_me : 1; +}; + +/* Actually remove, doesn't care about walking list, or delete_me */ +static void +_eobj_callback_remove(Eobj *obj, Eobj_Callback_Description *cb) +{ + obj->callbacks = eina_inlist_remove(obj->callbacks, + EINA_INLIST_GET(cb)); + free(cb); +} + +/* Actually remove, doesn't care about walking list, or delete_me */ +static void +_eobj_callback_remove_all(Eobj *obj) +{ + Eina_Inlist *initr; + Eobj_Callback_Description *cb; + EINA_INLIST_FOREACH_SAFE(obj->callbacks, initr, cb) + { + _eobj_callback_remove(obj, cb); + } +} + +static void +_eobj_callbacks_clear(Eobj *obj) +{ + Eina_Inlist *itn; + Eobj_Callback_Description *cb; + + /* Abort if we are currently walking the list. */ + if (obj->walking_list > 0) + return; + + EINA_INLIST_FOREACH_SAFE(obj->callbacks, itn, cb) + { + if (cb->delete_me) + { + _eobj_callback_remove(obj, cb); + } + } +} + +static int +_callback_priority_cmp(const void *_a, const void *_b) +{ + const Eobj_Callback_Description *a, *b; + a = (const Eobj_Callback_Description *) _a; + b = (const Eobj_Callback_Description *) _b; + if (a->priority < b->priority) + return -1; + else + return 1; +} + +EAPI Eina_Bool +eobj_event_callback_add(Eobj *obj, + const Eobj_Event_Description *desc, + Eobj_Event_Cb cb, + const void *data) +{ + return eobj_event_callback_priority_add(obj, desc, + EOBJ_CALLBACK_PRIORITY_DEFAULT, cb, data); +} + +EAPI Eina_Bool +eobj_event_callback_priority_add(Eobj *obj, + const Eobj_Event_Description *desc, + Eobj_Callback_Priority priority, + Eobj_Event_Cb func, + const void *data) +{ + Eobj_Callback_Description *cb = calloc(1, sizeof(*cb)); + cb->event = desc; + cb->func = func; + cb->func_data = (void *) data; + cb->priority = priority; + obj->callbacks = eina_inlist_sorted_insert(obj->callbacks, + EINA_INLIST_GET(cb), _callback_priority_cmp); + + eobj_event_callback_call(obj, EOBJ_SIG_CALLBACK_ADD, desc); + + return EINA_TRUE; +} + +EAPI void * +eobj_event_callback_del(Eobj *obj, const Eobj_Event_Description *desc, Eobj_Event_Cb func) +{ + void *ret = NULL; + Eobj_Callback_Description *cb; + EINA_INLIST_FOREACH(obj->callbacks, cb) + { + if ((cb->event == desc) && (cb->func == func)) + { + void *data; + + data = cb->func_data; + cb->delete_me = EINA_TRUE; + _eobj_callbacks_clear(obj); + ret = data; + goto end; + } + } + +end: + eobj_event_callback_call(obj, EOBJ_SIG_CALLBACK_DEL, desc); + return ret; +} + +EAPI void * +eobj_event_callback_del_full(Eobj *obj, const Eobj_Event_Description *desc, Eobj_Event_Cb func, const void *user_data) +{ + void *ret = NULL; + Eobj_Callback_Description *cb; + EINA_INLIST_FOREACH(obj->callbacks, cb) + { + if ((cb->event == desc) && (cb->func == func) && + (cb->func_data == user_data)) + { + void *data; + + data = cb->func_data; + cb->delete_me = EINA_TRUE; + _eobj_callbacks_clear(obj); + ret = data; + goto end; + } + } + +end: + eobj_event_callback_call(obj, EOBJ_SIG_CALLBACK_DEL, desc); + return ret; +} + +EAPI Eina_Bool +eobj_event_callback_call(Eobj *obj, const Eobj_Event_Description *desc, + const void *event_info) +{ + Eobj_Callback_Description *cb; + + obj->walking_list++; + + EINA_INLIST_FOREACH(obj->callbacks, cb) + { + if (!cb->delete_me && (cb->event == desc)) + { + /* Abort callback calling if the func says so. */ + if (!cb->func((void *) cb->func_data, obj, desc, + (void *) event_info)) + { + break; + } + } + if (obj->delete) + break; + } + obj->walking_list--; + _eobj_callbacks_clear(obj); + + return EINA_TRUE; +} + +static Eina_Bool +_eobj_event_forwarder_callback(void *data, Eobj *obj, const Eobj_Event_Description *desc, void *event_info) +{ + (void) obj; + Eobj *new_obj = (Eobj *) data; + return eobj_event_callback_call(new_obj, desc, event_info); +} + +/* FIXME: Change default priority? Maybe call later? */ +EAPI Eina_Bool +eobj_event_callback_forwarder_add(Eobj *obj, const Eobj_Event_Description *desc, Eobj *new_obj) +{ + return eobj_event_callback_add(obj, desc, _eobj_event_forwarder_callback, new_obj); +} + +EAPI Eina_Bool +eobj_event_callback_forwarder_del(Eobj *obj, const Eobj_Event_Description *desc, Eobj *new_obj) +{ + eobj_event_callback_del_full(obj, desc, _eobj_event_forwarder_callback, new_obj); + return EINA_TRUE; +} + +/* EOBJ_CLASS_BASE stuff */ +static Eobj_Class *_my_class = NULL; + +/* FIXME: Set proper type descriptions. */ +EAPI const Eobj_Event_Description _EOBJ_SIG_CALLBACK_ADD = + EOBJ_EVENT_DESCRIPTION("callback,add", "?", "Called when a callback was added."); +EAPI const Eobj_Event_Description _EOBJ_SIG_CALLBACK_DEL = + EOBJ_EVENT_DESCRIPTION("callback,del", "?", "Called when a callback was deleted."); + +static void +_constructor(Eobj *obj) +{ + DBG("%p - %s.", obj, _my_class->desc->name); +} + +static void +_destructor(Eobj *obj) +{ + DBG("%p - %s.", obj, _my_class->desc->name); +} + +EAPI const Eobj_Class * +eobj_base_class_get(void) +{ + if (_my_class) return _my_class; + + static const Eobj_Class_Description class_desc = { + "Eobj Base", + EOBJ_CLASS_TYPE_REGULAR_NO_INSTANT, + EOBJ_CLASS_DESCRIPTION_OPS(NULL, NULL, 0), + NULL, + 0, + _constructor, + _destructor, + NULL, + NULL + }; + + return _my_class = eobj_class_new(&class_desc, NULL, NULL); +} + diff --git a/legacy/eobj/lib/eobj.h b/legacy/eobj/lib/eobj.h new file mode 100644 index 0000000000..2b89c42a2d --- /dev/null +++ b/legacy/eobj/lib/eobj.h @@ -0,0 +1,163 @@ +#ifndef EOBJ_H +#define EOBJ_H + +#include +#include + +/* Check that the types are castable and cast them. */ +#define EOBJ_TYPECHECK(type, x) \ + ({ \ + type __x; \ + __x = x; \ + (void) __x; \ + (type) x; \ + }) + +#define EOBJ_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(*arr)) + +typedef struct _Eobj Eobj; +typedef uintptr_t Eobj_Op; + +typedef struct _Eobj_Class Eobj_Class; +typedef int Eobj_Class_Id; + +typedef enum +{ + EOBJ_CLASS_TYPE_REGULAR = 0, + EOBJ_CLASS_TYPE_REGULAR_NO_INSTANT, + EOBJ_CLASS_TYPE_INTERFACE, + EOBJ_CLASS_TYPE_MIXIN +} Eobj_Class_Type; + +typedef void (*eobj_op_func_type)(Eobj *, Eobj_Op, va_list *list); + +typedef struct +{ + Eobj_Op op; + eobj_op_func_type func; +} Eobj_Op_Func_Description; + +#define EOBJ_OP_FUNC_DESCRIPTION(op, func) { op, func } +#define EOBJ_OP_FUNC_DESCRIPTION_SENTINEL { 0, NULL } + +typedef struct +{ + const char *name; /**< name used for lookups */ + const char *type; /**< used for introspection purposes, documents what goes as callback event information (@c event_info) */ + const char *doc; /**< documentation for introspection purposes */ +} Eobj_Event_Description; + + +typedef struct +{ + Eobj_Op sub_op; + const char *name; + /* FIXME: properly define the type so it'll support get/set and etc. + * Do I even need/want type? If so, do I need/want it here? docs aren't + * enough? */ + const char *type; + const char *doc; +} Eobj_Op_Description; + +typedef struct +{ + const char *name; + Eobj_Class_Type type; + struct { + Eobj_Op *base_op_id; + const Eobj_Op_Description *descs; + size_t count; + } ops; + const Eobj_Event_Description **events; + size_t private_size; + void (*constructor)(Eobj *obj); + void (*destructor)(Eobj *obj); + void (*class_constructor)(Eobj_Class *klass); + void (*class_destructor)(Eobj_Class *klass); +} Eobj_Class_Description; + +#define EOBJ_CLASS_DESCRIPTION_OPS(base_op_id, op_descs, count) { base_op_id, op_descs, count } + +#define EOBJ_OP_DESCRIPTION(op, type, doc) { op, #op, type, doc } +#define EOBJ_OP_DESCRIPTION_SENTINEL { 0, NULL, NULL, NULL } + +#define EOBJ_EVENT_DESCRIPTION(name, type, doc) { name, type, doc } + +EAPI Eina_Bool eobj_init(void); +EAPI Eina_Bool eobj_shutdown(void); + +#define eobj_do(object, ...) eobj_do_internal(object, __VA_ARGS__, NULL) +#define eobj_class_do(object, klass, ...) eobj_class_do_internal(object, klass, __VA_ARGS__, NULL) +#define eobj_class_parent_do(object, klass, ...) eobj_class_do_internal(object, eobj_class_parent_get(klass), __VA_ARGS__, NULL) + +EAPI Eina_Bool eobj_do_internal(Eobj *obj, ...); + +EAPI Eina_Bool eobj_class_do_internal(Eobj *obj, const Eobj_Class *klass, ...); + +EAPI const Eobj_Class *eobj_class_get(Eobj *obj); +EAPI const Eobj_Class *eobj_class_parent_get(const Eobj_Class *klass); +EAPI const char *eobj_class_name_get(const Eobj_Class *klass); + +EAPI void eobj_constructor_super(Eobj *obj); +EAPI void eobj_destructor_super(Eobj *obj); +EAPI void eobj_constructor_error_set(Eobj *obj); +EAPI Eina_Bool eobj_constructor_error_get(const Eobj *obj); + +EAPI Eobj_Class *eobj_class_new(const Eobj_Class_Description *desc, const Eobj_Class *parent, ...); +EAPI void eobj_class_free(Eobj_Class *klass); +EAPI void eobj_class_funcs_set(Eobj_Class *klass, const Eobj_Op_Func_Description *func_descs); + +EAPI Eobj *eobj_add(const Eobj_Class *klass, Eobj *parent); +EAPI Eobj *eobj_parent_get(Eobj *obj); +EAPI void *eobj_data_get(Eobj *obj, const Eobj_Class *klass); +EAPI Eobj *eobj_ref(Eobj *obj); +EAPI void eobj_unref(Eobj *obj); +EAPI void eobj_del(Eobj *obj); +EAPI void *eobj_generic_data_set(Eobj *obj, const char *key, const void *data); +EAPI void *eobj_generic_data_get(const Eobj *obj, const char *key); +EAPI void *eobj_generic_data_del(Eobj *obj, const char *key); + +#define EOBJ_CLASS_BASE eobj_base_class_get() +EAPI const Eobj_Class *eobj_base_class_get(void) EINA_CONST; + +EAPI void eobj_composite_object_attach(Eobj *obj, Eobj *emb_obj); +EAPI void eobj_composite_object_detach(Eobj *obj, Eobj *emb_obj); +EAPI Eina_Bool eobj_composite_is(Eobj *emb_obj); + +/* Events */ +/** + * @def EOBJ_CALLBACK_PRIORITY_BEFORE + * Slightly more prioritized than default. + */ +#define EOBJ_CALLBACK_PRIORITY_BEFORE -100 +/** + * @def EOBJ_CALLBACK_PRIORITY_DEFAULT + * Default callback priority level + */ +#define EOBJ_CALLBACK_PRIORITY_DEFAULT 0 +/** + * @def EOBJ_CALLBACK_PRIORITY_AFTER + * Slightly less prioritized than default. + */ +#define EOBJ_CALLBACK_PRIORITY_AFTER 100 +typedef short Eobj_Callback_Priority; + +/* True meaning continue, False meaning stop callbacks. - Make it an enum? */ +typedef Eina_Bool (*Eobj_Event_Cb)(void *data, Eobj *obj, const Eobj_Event_Description *desc, void *event_info); + +EAPI Eina_Bool eobj_event_callback_forwarder_add(Eobj *obj, const Eobj_Event_Description *desc, Eobj *new_obj); +EAPI Eina_Bool eobj_event_callback_forwarder_del(Eobj *obj, const Eobj_Event_Description *desc, Eobj *new_obj); + +/* callbacks of the same priority are called in reverse order of creation. */ +EAPI Eina_Bool eobj_event_callback_add(Eobj *obj, const Eobj_Event_Description *desc, Eobj_Event_Cb cb, const void *data); +EAPI Eina_Bool eobj_event_callback_priority_add(Eobj *obj, const Eobj_Event_Description *desc, Eobj_Callback_Priority priority, Eobj_Event_Cb cb, const void *data); +EAPI void *eobj_event_callback_del(Eobj *obj, const Eobj_Event_Description *desc, Eobj_Event_Cb func); +EAPI void *eobj_event_callback_del_full(Eobj *obj, const Eobj_Event_Description *desc, Eobj_Event_Cb func, const void *user_data); +EAPI Eina_Bool eobj_event_callback_call(Eobj *obj, const Eobj_Event_Description *desc, const void *event_info); + +EAPI extern const Eobj_Event_Description _EOBJ_SIG_CALLBACK_ADD; +#define EOBJ_SIG_CALLBACK_ADD (&(_EOBJ_SIG_CALLBACK_ADD)) +EAPI extern const Eobj_Event_Description _EOBJ_SIG_CALLBACK_DEL; +#define EOBJ_SIG_CALLBACK_DEL (&(_EOBJ_SIG_CALLBACK_DEL)) + +#endif diff --git a/legacy/eobj/tests/CMakeLists.txt b/legacy/eobj/tests/CMakeLists.txt new file mode 100644 index 0000000000..6080f079ae --- /dev/null +++ b/legacy/eobj/tests/CMakeLists.txt @@ -0,0 +1,30 @@ +if (CHECK_ENABLED) + + LIST(APPEND EOBJ_SUITE_CC_SOURCES + eobj_suite.c + eobj_test_init.c + eobj_test_general.c + ) + + add_executable(eobj_suite ${EOBJ_SUITE_CC_SOURCES}) + + include_directories( + ${EINA_INCLUDE_DIRS} + ${EVAS_INCLUDE_DIRS} + ${ELEMENTARY_INCLUDE_DIRS} + ${CMAKE_SOURCE_DIR}/lib + ${CHECK_INCLUDE_DIRS} + ) + + get_target_property(eobj_LIB_FILE eobj LOCATION) + target_link_libraries(eobj_suite + ${EINA_LIBRARIES} + ${EVAS_LIBRARIES} + ${ELEMENTARY_LIBRARIES} + ${eobj_LIB_FILE} + ${CHECK_LIBRARIES} + ) + + add_test(eobj_suite eobj_suite) + add_dependencies(check eobj_suite) +endif (CHECK_ENABLED) diff --git a/legacy/eobj/tests/eobj_suite.c b/legacy/eobj/tests/eobj_suite.c new file mode 100644 index 0000000000..b6f1d46d0d --- /dev/null +++ b/legacy/eobj/tests/eobj_suite.c @@ -0,0 +1,102 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "eobj.h" + +#include "eobj_suite.h" + +typedef struct _Eobj_Test_Case Eobj_Test_Case; + +struct _Eobj_Test_Case +{ + const char *test_case; + void (*build)(TCase *tc); +}; + +static const Eobj_Test_Case etc[] = { + { "Eobj init", eobj_test_init }, + { "Eobj general", eobj_test_general }, + { NULL, NULL } +}; + +static void +_list_tests(void) +{ + const Eobj_Test_Case *itr; + + itr = etc; + fputs("Available Test Cases:\n", stderr); + for (; itr->test_case; itr++) + fprintf(stderr, "\t%s\n", itr->test_case); +} +static Eina_Bool +_use_test(int argc, const char **argv, const char *test_case) +{ + if (argc < 1) + return 1; + + for (; argc > 0; argc--, argv++) + if (strcmp(test_case, *argv) == 0) + return 1; + return 0; +} + +static Suite * +eobj_suite_build(int argc, const char **argv) +{ + TCase *tc; + Suite *s; + int i; + + s = suite_create("Eobj"); + + for (i = 0; etc[i].test_case; ++i) + { + if (!_use_test(argc, argv, etc[i].test_case)) continue; + tc = tcase_create(etc[i].test_case); + + etc[i].build(tc); + + suite_add_tcase(s, tc); + tcase_set_timeout(tc, 0); + } + + return s; +} + +int +main(int argc, char **argv) +{ + Suite *s; + SRunner *sr; + int i, failed_count; + + for (i = 1; i < argc; i++) + if ((strcmp(argv[i], "-h") == 0) || + (strcmp(argv[i], "--help") == 0)) + { + fprintf(stderr, "Usage:\n\t%s [test_case1 .. [test_caseN]]\n", + argv[0]); + _list_tests(); + return 0; + } + else if ((strcmp(argv[i], "-l") == 0) || + (strcmp(argv[i], "--list") == 0)) + { + _list_tests(); + return 0; + } + + s = eobj_suite_build(argc - 1, (const char **)argv + 1); + sr = srunner_create(s); + + srunner_run_all(sr, CK_ENV); + failed_count = srunner_ntests_failed(sr); + srunner_free(sr); + + return (failed_count == 0) ? 0 : 255; +} diff --git a/legacy/eobj/tests/eobj_suite.h b/legacy/eobj/tests/eobj_suite.h new file mode 100644 index 0000000000..b9f6e89fc4 --- /dev/null +++ b/legacy/eobj/tests/eobj_suite.h @@ -0,0 +1,10 @@ +#ifndef _EOBJ_SUITE_H +#define _EOBJ_SUITE_H + +#include + +void eobj_test_init(TCase *tc); +void eobj_test_general(TCase *tc); + + +#endif /* _EOBJ_SUITE_H */ diff --git a/legacy/eobj/tests/eobj_test_general.c b/legacy/eobj/tests/eobj_test_general.c new file mode 100644 index 0000000000..d44abcc4c7 --- /dev/null +++ b/legacy/eobj/tests/eobj_test_general.c @@ -0,0 +1,18 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "eobj_suite.h" +#include "eobj.h" + +START_TEST(eobj_simple) +{ +} +END_TEST + +void eobj_test_general(TCase *tc) +{ + tcase_add_test(tc, eobj_simple); +} diff --git a/legacy/eobj/tests/eobj_test_init.c b/legacy/eobj/tests/eobj_test_init.c new file mode 100644 index 0000000000..507ed7d851 --- /dev/null +++ b/legacy/eobj/tests/eobj_test_init.c @@ -0,0 +1,20 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "eobj_suite.h" +#include "eobj.h" + +START_TEST(eobj_simple) +{ + fail_if(!eobj_init()); /* one init by test suite */ + fail_if(!eobj_shutdown()); +} +END_TEST + +void eobj_test_init(TCase *tc) +{ + tcase_add_test(tc, eobj_simple); +}