void Adaptor::RemoveIdle(CallbackBase* callback)
{
- mCallbacks.Erase(std::find_if(mCallbacks.Begin(), mCallbacks.End(), [&callback](CallbackBase* current) { return callback == current; }));
- mReturnCallbacks.Erase(std::find_if(mReturnCallbacks.Begin(), mReturnCallbacks.End(), [&callback](CallbackBase* current) { return callback == current; }));
+ mCallbacks.Erase(std::remove_if(mCallbacks.Begin(), mCallbacks.End(), [&callback](CallbackBase* current) { return callback == current; }), mCallbacks.End());
+ mReturnCallbacks.Erase(std::remove_if(mReturnCallbacks.Begin(), mReturnCallbacks.End(), [&callback](CallbackBase* current) { return callback == current; }), mReturnCallbacks.End());
}
void Adaptor::RunIdles()
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
END_TEST;
}
-int UtcDaliSetPropertyP(void)
+int UtcDaliSliderSetPropertyP(void)
{
ToolkitTestApplication application;
- tet_infoline("UtcDaliSetPropertyP");
+ tet_infoline("UtcDaliSliderSetPropertyP");
Slider slider = Slider::New();
slider.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT);
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
return GetImplementation(*this).GetPreMultiplyOnLoad();
}
+void VisualFactory::DiscardVisual(Visual::Base visual)
+{
+ GetImplementation(*this).DiscardVisual(visual);
+}
+
} // namespace Toolkit
} // namespace Dali
#define DALI_TOOLKIT_VISUAL_FACTORY_H
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 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.
*/
bool GetPreMultiplyOnLoad() const;
+ /**
+ * @brief Discard visual base. It will keep reference of visual until idle callback called.
+ *
+ * @param[in] visual Discarded visual base.
+ */
+ void DiscardVisual(Visual::Base visual);
+
private:
explicit DALI_INTERNAL VisualFactory(Internal::VisualFactory* impl);
};
}
/**
+ * Discard visual from source to visual factory.
+ */
+void DiscardVisual(RegisteredVisualContainer::Iterator sourceIter, RegisteredVisualContainer& source)
+{
+ Toolkit::Visual::Base visual = (*sourceIter)->visual;
+ if(visual)
+ {
+ if(Stage::IsInstalled())
+ {
+ Toolkit::VisualFactory::Get().DiscardVisual(visual);
+ }
+ }
+
+ source.Erase(sourceIter);
+}
+
+/**
* Performs actions as requested using the action name.
* @param[in] object The object on which to perform the action.
* @param[in] actionName The action to perform.
Actor self(mControlImpl.Self());
Toolkit::GetImplementation((*iter)->visual).SetOffScene(self);
(*iter)->pending = false;
- (*iter)->visual.Reset();
- mRemoveVisuals.Erase(iter);
+
+ // Discard removed visual. It will be destroyed at next Idle time.
+ DiscardVisual(iter, mRemoveVisuals);
}
}
{
Toolkit::GetImplementation((*visualToRemoveIter)->visual).SetOffScene(self);
}
- mRemoveVisuals.Erase(visualToRemoveIter);
+
+ // Discard removed visual. It will be destroyed at next Idle time.
+ DiscardVisual(visualToRemoveIter, mRemoveVisuals);
}
// A visual is ready so control may need relayouting if staged
// Visuals pending replacement can now be taken out of the removal list and set off scene
// Iterate through all replacement visuals and add to a move queue then set off scene
- for(auto removalIter = mRemoveVisuals.Begin(), end = mRemoveVisuals.End(); removalIter != end; removalIter++)
+
+ if(!mRemoveVisuals.Empty())
{
- Toolkit::GetImplementation((*removalIter)->visual).SetOffScene(self);
+ std::reverse(mRemoveVisuals.Begin(), mRemoveVisuals.End());
+
+ while(!mRemoveVisuals.Empty())
+ {
+ auto removalIter = mRemoveVisuals.End() - 1u;
+ Toolkit::GetImplementation((*removalIter)->visual).SetOffScene(self);
+
+ // Discard removed visual. It will be destroyed at next Idle time.
+ DiscardVisual(removalIter, mRemoveVisuals);
+ }
}
for(auto replacedIter = mVisuals.Begin(), end = mVisuals.End(); replacedIter != end; replacedIter++)
{
(*replacedIter)->pending = false;
}
-
- mRemoveVisuals.Clear();
}
void Control::Impl::SetMargin(Extents margin)
// EXTERNAL INCLUDES
#include <dali/devel-api/scripting/scripting.h>
+#include <dali/integration-api/adaptor-framework/adaptor.h>
#include <dali/integration-api/debug.h>
#include <dali/public-api/object/property-array.h>
#include <dali/public-api/object/type-registry-helper.h>
mImageVisualShaderFactory(),
mTextVisualShaderFactory(),
mSlotDelegate(this),
+ mIdleCallback(nullptr),
mDebugEnabled(debugEnabled),
mPreMultiplyOnLoad(true)
{
VisualFactory::~VisualFactory()
{
+ if(mIdleCallback && Adaptor::IsAvailable())
+ {
+ // Removes the callback from the callback manager in case the control is destroyed before the callback is executed.
+ Adaptor::Get().RemoveIdle(mIdleCallback);
+ mIdleCallback = nullptr;
+ }
}
void VisualFactory::OnStyleChangedSignal(Toolkit::StyleManager styleManager, StyleChange::Type type)
return mPreMultiplyOnLoad;
}
+void VisualFactory::DiscardVisual(Toolkit::Visual::Base visual)
+{
+ mDiscardedVisuals.emplace_back(visual);
+
+ RegisterDiscardCallback();
+}
+
Internal::TextureManager& VisualFactory::GetTextureManager()
{
return GetFactoryCache().GetTextureManager();
return *mTextVisualShaderFactory;
}
+void VisualFactory::OnDiscardCallback()
+{
+ mIdleCallback = nullptr;
+
+ // Discard visual now.
+ mDiscardedVisuals.clear();
+}
+
+void VisualFactory::RegisterDiscardCallback()
+{
+ if(!mIdleCallback && Adaptor::IsAvailable())
+ {
+ // The callback manager takes the ownership of the callback object.
+ mIdleCallback = MakeCallback(this, &VisualFactory::OnDiscardCallback);
+
+ Adaptor& adaptor = Adaptor::Get();
+
+ if(!adaptor.AddIdle(mIdleCallback, false))
+ {
+ // Fail to add idle. (Maybe adaptor is paused.)
+ mIdleCallback = nullptr;
+ }
+ }
+}
+
} // namespace Internal
} // namespace Toolkit
*/
// EXTERNAL INCLUDES
+#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/object/base-object.h>
// INTERNAL INCLUDES
bool GetPreMultiplyOnLoad() const;
/**
+ * @copydoc Toolkit::VisualFactory::DiscardVisual()
+ */
+ void DiscardVisual(Toolkit::Visual::Base visual);
+
+ /**
* @return the reference to texture manager
*/
Internal::TextureManager& GetTextureManager();
*/
TextVisualShaderFactory& GetTextVisualShaderFactory();
+ /**
+ * @brief Callbacks called for clear discarded visuals.
+ */
+ void OnDiscardCallback();
+
+ /**
+ * @brief Register idle callback for discard visuals if need.
+ */
+ void RegisterDiscardCallback();
+
VisualFactory(const VisualFactory&) = delete;
VisualFactory& operator=(const VisualFactory& rhs) = delete;
std::unique_ptr<ImageVisualShaderFactory> mImageVisualShaderFactory;
std::unique_ptr<TextVisualShaderFactory> mTextVisualShaderFactory;
SlotDelegate<VisualFactory> mSlotDelegate;
- bool mDebugEnabled : 1;
- bool mPreMultiplyOnLoad : 1; ///< Local store for this flag
+ CallbackBase* mIdleCallback;
+
+ using DiscardedVisualContainer = std::vector<Toolkit::Visual::Base>;
+ DiscardedVisualContainer mDiscardedVisuals{};
+
+ bool mDebugEnabled : 1;
+ bool mPreMultiplyOnLoad : 1; ///< Local store for this flag
};
/**