utc-Dali-SignalDelegate.cpp
utc-Dali-SignalTemplatesFunctors.cpp
utc-Dali-SignalTemplates.cpp
+ utc-Dali-SingletonService.cpp
utc-Dali-Stage.cpp
utc-Dali-TapGesture.cpp
utc-Dali-TapGestureDetector.cpp
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <stdlib.h>
+#include <iostream>
+#include <dali/public-api/dali-core.h>
+#include <dali-test-suite-utils.h>
+#include <dali/devel-api/common/singleton-service.h>
+
+using namespace Dali;
+
+namespace
+{
+
+class TestHandle : public BaseHandle
+{
+public:
+ TestHandle() {}
+ TestHandle( BaseObject* object ) : BaseHandle( object ) {}
+};
+
+class TestObject : public BaseObject
+{
+};
+
+} // unnamed namespace
+
+void utc_dali_singleton_service_startup(void)
+{
+ test_return_value = TET_UNDEF;
+}
+
+void utc_dali_singleton_service_cleanup(void)
+{
+ test_return_value = TET_PASS;
+}
+
+int UtcDaliSingletonServiceGet(void)
+{
+ // Attempt to retrieve SingletonService before creating application
+ SingletonService singletonService;
+ singletonService = SingletonService::Get();
+ DALI_TEST_CHECK( !singletonService );
+
+ // Create Application class, should be able to retrieve SingletonService now
+ TestApplication application;
+ singletonService = SingletonService::Get();
+ DALI_TEST_CHECK( singletonService );
+
+ END_TEST;
+}
+
+int UtcDaliSingletonServiceRegisterAndGetSingleton(void)
+{
+ TestApplication application;
+ SingletonService singletonService( SingletonService::Get() );
+
+ // Attempt to register an empty handle
+ TestHandle handle;
+ singletonService.Register( typeid( handle ), handle );
+ DALI_TEST_CHECK( !singletonService.GetSingleton( typeid( handle ) ) );
+
+ // Create an actor instance and retrieve, should be valid this time
+ handle = TestHandle( new TestObject );
+ singletonService.Register( typeid( handle ), handle );
+ DALI_TEST_CHECK( singletonService.GetSingleton( typeid( handle ) ) );
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali/devel-api/common/singleton-service.h>
+
+// INTERNAL INCLUDES
+#include <dali/internal/event/common/thread-local-storage.h>
+
+namespace Dali
+{
+
+SingletonService::SingletonService()
+{
+}
+
+SingletonService SingletonService::Get()
+{
+ return Internal::ThreadLocalStorage::GetSingletonService();
+}
+
+SingletonService::~SingletonService()
+{
+}
+
+void SingletonService::Register( const std::type_info& info, BaseHandle singleton )
+{
+ GetImplementation( *this ).Register( info, singleton );
+}
+
+void SingletonService::UnregisterAll()
+{
+ GetImplementation( *this ).UnregisterAll();
+}
+
+BaseHandle SingletonService::GetSingleton( const std::type_info& info ) const
+{
+ return GetImplementation( *this ).GetSingleton( info );
+}
+
+SingletonService::SingletonService( Internal::ThreadLocalStorage* tls )
+: BaseHandle( tls )
+{
+}
+
+} // namespace Dali
--- /dev/null
+#ifndef DALI_SINGELTON_SERVICE_H
+#define DALI_SINGELTON_SERVICE_H
+
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <typeinfo>
+#include <dali/public-api/object/base-handle.h>
+
+namespace Dali
+{
+
+namespace Internal DALI_INTERNAL
+{
+class ThreadLocalStorage;
+}
+
+/**
+ * @brief Allows the registration of a class as a singleton
+ *
+ * @note This class is created by the Application class and is destroyed when the Application class is destroyed.
+ *
+ * @see Application
+ */
+class DALI_CORE_API SingletonService : public BaseHandle
+{
+public:
+
+ /**
+ * @brief Create an uninitialized handle.
+ *
+ * This can be initialized by calling SingletonService::Get().
+ */
+ SingletonService();
+
+ /**
+ * @brief Retrieves a handle to the SingletonService.
+ *
+ * @return A handle to the SingletonService if it is available. This will be an empty handle if
+ * the service is not available.
+ */
+ static SingletonService Get();
+
+ /**
+ * @brief Destructor
+ *
+ * This is non-virtual since derived Handle types must not contain data or virtual methods.
+ */
+ ~SingletonService();
+
+ /**
+ * @brief Registers the singleton of Dali handle with its type info.
+ *
+ * The singleton will be kept alive for the lifetime of the service.
+ *
+ * @note This is not intended for application developers.
+ * @param[in] info The type info of the Dali handle generated by the compiler.
+ * @param[in] singleton The Dali handle to be registered
+ */
+ void Register( const std::type_info& info, BaseHandle singleton );
+
+ /**
+ * @brief Unregisters all singletons.
+ *
+ * @note This is not intended for application developers.
+ */
+ void UnregisterAll();
+
+ /**
+ * @brief Gets the singleton for the given type.
+ *
+ * @note This is not intended for application developers.
+ * @param[in] info The type info of the given type.
+ * @return the Dali handle if it is registered as a singleton or an uninitialized handle.
+ */
+ BaseHandle GetSingleton( const std::type_info& info ) const;
+
+public: // Not intended for application developers
+
+ /**
+ * @brief This constructor is used by SingletonService::Get().
+ * @param[in] singletonService A pointer to the internal singleton-service object.
+ */
+ explicit DALI_INTERNAL SingletonService( Internal::ThreadLocalStorage* singletonService );
+};
+
+} // namespace Dali
+
+#endif // DALI_SINGELTON_SERVICE_H
${devel_api_src_dir}/animation/animation-devel.cpp
${devel_api_src_dir}/animation/path-constrainer.cpp
${devel_api_src_dir}/common/hash.cpp
+ ${devel_api_src_dir}/common/singleton-service.cpp
${devel_api_src_dir}/common/stage-devel.cpp
${devel_api_src_dir}/events/hit-test-algorithm.cpp
${devel_api_src_dir}/events/long-press-gesture-detector-devel.cpp
${devel_api_src_dir}/common/bitwise-enum.h
${devel_api_src_dir}/common/circular-queue.h
${devel_api_src_dir}/common/hash.h
+ ${devel_api_src_dir}/common/singleton-service.h
${devel_api_src_dir}/common/map-wrapper.h
${devel_api_src_dir}/common/owner-container.h
${devel_api_src_dir}/common/ref-counted-dali-vector.h
if( tls )
{
tls->Remove();
- delete tls;
+ tls->Unreference();
}
mObjectRegistry.Reset();
{
// a pointer to the ThreadLocalStorage object will be stored in TLS
// The ThreadLocalStorage object should be deleted by the Core destructor
- new ThreadLocalStorage(this);
+ ThreadLocalStorage* tls = new ThreadLocalStorage(this);
+ tls->Reference();
}
void Core::RegisterObject( Dali::BaseObject* object )
#include <dali/internal/common/core-impl.h>
#include <dali/public-api/common/dali-common.h>
#include <dali/internal/event/common/event-thread-services.h>
+#include <dali/integration-api/processor-interface.h>
+
+#if defined(DEBUG_ENABLED)
+#include <dali/integration-api/debug.h>
+Debug::Filter* gSingletonServiceLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_SINGLETON_SERVICE" );
+
+// Need to define own macro as the log function is not installed when this object is created so no logging is shown with DALI_LOG_INFO at construction and destruction
+#define DALI_LOG_SINGLETON_SERVICE_DIRECT(level, message) \
+ if(gSingletonServiceLogFilter && gSingletonServiceLogFilter->IsEnabledFor(level)) { std::string string(message); Dali::TizenPlatform::LogMessage( Debug::DebugInfo, string ); }
+
+#define DALI_LOG_SINGLETON_SERVICE(level, format, ...) DALI_LOG_INFO(gSingletonServiceLogFilter, level, format, ## __VA_ARGS__ )
+#else
+
+#define DALI_LOG_SINGLETON_SERVICE_DIRECT(level, message)
+#define DALI_LOG_SINGLETON_SERVICE(level, format, ...)
+
+#endif
namespace Dali
{
return *threadLocal;
}
+Dali::SingletonService ThreadLocalStorage::GetSingletonService()
+{
+ Dali::SingletonService singletonService;
+ if ( threadLocal )
+ {
+ singletonService = Dali::SingletonService( threadLocal );
+ }
+ return singletonService;
+}
+
bool ThreadLocalStorage::Created()
{
// see if the TLS has been set yet
mCore->RemoveScene( scene );
}
+void ThreadLocalStorage::Register( const std::type_info& info, BaseHandle singleton )
+{
+ if( singleton )
+ {
+ DALI_LOG_SINGLETON_SERVICE( Debug::General, "Singleton Added: %s\n", info.name() );
+ mSingletonContainer.push_back( SingletonPair( info.name(), singleton ) );
+
+ Integration::Processor* processor = dynamic_cast<Integration::Processor*>( &singleton.GetBaseObject() );
+ if( processor )
+ {
+ mCore->RegisterProcessor( *processor );
+ }
+ }
+}
+
+void ThreadLocalStorage::UnregisterAll( )
+{
+ mSingletonContainer.clear();
+}
+
+BaseHandle ThreadLocalStorage::GetSingleton( const std::type_info& info ) const
+{
+ BaseHandle object;
+
+ const SingletonContainer::const_iterator end = mSingletonContainer.end();
+ for( SingletonContainer::const_iterator iter = mSingletonContainer.begin(); iter != end; ++iter )
+ {
+ // comparing the addresses as these are allocated statically per library
+ if( ( *iter ).first == info.name() )
+ {
+ object = ( *iter ).second;
+ }
+ }
+
+ return object;
+}
+
} // namespace Internal
} // namespace Dali
*
*/
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
+
// INTERNAL INCLUDES
+#include <dali/devel-api/common/singleton-service.h>
#include <dali/internal/event/common/stage-def.h>
#include <dali/internal/event/common/scene-impl.h>
* Class to store a pointer to core in thread local storage.
*
*/
-class ThreadLocalStorage
+class ThreadLocalStorage : public Dali::BaseObject
{
public:
*/
ThreadLocalStorage(Core* core);
- /**
- * Destructor.
- */
- ~ThreadLocalStorage();
-
/**
* Remove core pointer.
* Prevents the core pointer being automatically deleted when the thread exits.
*/
static ThreadLocalStorage& Get();
+ /**
+ * @copydoc Dali::SingletonService::Get()
+ */
+ static Dali::SingletonService GetSingletonService();
+
/**
* Checks if the TLS has been created
* @return if the TLS has been created
*/
void RemoveScene( Scene* scene );
+ /**
+ * @copydoc Dali::SingletonService::Register()
+ */
+ void Register( const std::type_info& info, BaseHandle singleton );
+
+ /**
+ * @copydoc Dali::SingletonService::UnregisterAll()
+ */
+ void UnregisterAll();
+
+ /**
+ * @copydoc Dali::SingletonService::GetSingleton()
+ */
+ BaseHandle GetSingleton( const std::type_info& info ) const;
+
+private:
+
+ /**
+ * Virtual Destructor
+ */
+ virtual ~ThreadLocalStorage();
+
+ // Undefined
+ ThreadLocalStorage( const ThreadLocalStorage& );
+ ThreadLocalStorage& operator=( ThreadLocalStorage& );
+
private:
Core* mCore; ///< reference to core
+ // using the address of the type name string as compiler will allocate these once per library
+ // and we don't support un/re-loading of dali libraries while singleton service is alive
+ typedef std::pair< const char*, BaseHandle> SingletonPair;
+ typedef std::vector< SingletonPair > SingletonContainer;
+ typedef SingletonContainer::const_iterator SingletonConstIter;
+
+ SingletonContainer mSingletonContainer; ///< The container to look up singleton by its type name
+
};
} // namespace Internal
+// Helpers for public-api forwarding methods
+
+inline Internal::ThreadLocalStorage& GetImplementation(Dali::SingletonService& service)
+{
+ DALI_ASSERT_ALWAYS( service && "SingletonService handle is empty" );
+
+ BaseObject& handle = service.GetBaseObject();
+
+ return static_cast<Internal::ThreadLocalStorage&>(handle);
+}
+
+inline const Internal::ThreadLocalStorage& GetImplementation(const Dali::SingletonService& service)
+{
+ DALI_ASSERT_ALWAYS( service && "SingletonService handle is empty" );
+
+ const BaseObject& handle = service.GetBaseObject();
+
+ return static_cast<const Internal::ThreadLocalStorage&>(handle);
+}
+
} // namespace Dali
#endif // DALI_INTERNAL_THREAD_LOCAL_STORAGE_H