Browse Source

New UI Work

Josh Engebretson 10 years ago
parent
commit
81eef74818

+ 37 - 2
Source/Atomic/UI/UI.cpp

@@ -66,6 +66,8 @@ UI::~UI()
     if (initialized_)
     {
         tb::TBWidgetsAnimationManager::Shutdown();
+
+        widgetWrap_.Clear();
         delete rootWidget_;
         // leak
         //delete TBUIRenderer::renderer_;
@@ -75,8 +77,6 @@ UI::~UI()
     uiContext_ = 0;
     TBFile::SetReaderFunction(0);
     TBID::tbidRegisterCallback = 0;
-
-
 }
 
 void UI::Shutdown()
@@ -390,6 +390,41 @@ bool UI::IsWidgetWrapped(tb::TBWidget* widget)
     return widgetWrap_.Contains(widget);
 }
 
+bool UI::UnwrapWidget(tb::TBWidget* widget)
+{
+    if (widgetWrap_.Contains(widget))
+    {
+        widgetWrap_.Erase(widget);
+        return true;
+    }
+
+    return false;
+
+}
+
+void UI::PruneUnreachableWidgets()
+{
+    HashMap<tb::TBWidget*, SharedPtr<UIWidget>>::Iterator itr;
+
+    for (itr = widgetWrap_.Begin(); itr != widgetWrap_.End(); )
+    {
+        if ((*itr).first_->GetParent() || (*itr).second_->JSGetHeapPtr())
+        {
+            itr++;
+            continue;
+        }
+
+        tb::TBWidget* toDelete = (*itr).first_;
+
+        itr.GotoNext();
+
+        delete toDelete;
+
+        // this will likely be flagged by valgrind as assessing invalid memory
+        assert(!widgetWrap_.Contains(toDelete));
+    }
+}
+
 UIWidget* UI::WrapWidget(tb::TBWidget* widget)
 {
     if (widgetWrap_.Contains(widget))

+ 4 - 1
Source/Atomic/UI/UI.h

@@ -47,6 +47,9 @@ public:
 
     bool IsWidgetWrapped(tb::TBWidget* widget);
     UIWidget* WrapWidget(tb::TBWidget* widget);
+    bool UnwrapWidget(tb::TBWidget* widget);
+
+    void PruneUnreachableWidgets();
 
     void GetTBIDString(unsigned id, String& value);
 
@@ -71,7 +74,7 @@ private:
 
     WeakPtr<Graphics> graphics_;
 
-    HashMap<tb::TBWidget*, UIWidget*> widgetWrap_;
+    HashMap<tb::TBWidget*, SharedPtr<UIWidget> > widgetWrap_;
     HashMap<unsigned, String> tbidToString_;
 
     bool inputDisabled_;

+ 0 - 1
Source/Atomic/UI/UIImageWidget.cpp

@@ -25,7 +25,6 @@ UIImageWidget::UIImageWidget(Context* context, bool createWidget) : UIWidget(con
 
 UIImageWidget::~UIImageWidget()
 {
-    LOGINFOF("Hey!");
 }
 
 bool UIImageWidget::OnEvent(const tb::TBWidgetEvent &ev)

+ 8 - 0
Source/Atomic/UI/UIWidget.cpp

@@ -82,6 +82,14 @@ void UIWidget::ConvertEvent(UIWidget *handler, UIWidget* target, const tb::TBWid
 
 void UIWidget::OnDelete()
 {
+    if (widget_)
+    {
+        // if we don't have a UI subsystem, we are exiting
+        UI* ui = GetSubsystem<UI>();
+        if (ui)
+            ui->UnwrapWidget(widget_);
+    }
+
     widget_ = 0;
     ReleaseRef();
 }

+ 0 - 2
Source/AtomicJS/Javascript/JSAtomic.cpp

@@ -146,8 +146,6 @@ static int js_atomic_destroy(duk_context* ctx)
     if (!obj)
         return 0;
 
-    JSVM* vm = JSVM::GetJSVM(ctx);
-
     if (obj->GetType() == Node::GetTypeStatic())
     {
 

+ 19 - 1
Source/AtomicJS/Javascript/JSUI.cpp

@@ -1,5 +1,6 @@
 #include <TurboBadger/tb_widgets.h>
 
+#include <Atomic/Core/CoreEvents.h>
 #include <Atomic/UI/UIEvents.h>
 #include <Atomic/UI/UIWidget.h>
 #include <Atomic/UI/UIButton.h>
@@ -12,9 +13,11 @@ using namespace tb;
 namespace Atomic
 {
 
-JSUI::JSUI(Context* context) : Object(context)
+JSUI::JSUI(Context* context) : Object(context),
+    updateTime_(0.0f)
 {
     ctx_ = JSVM::GetJSVM(nullptr)->GetJSContext();
+    SubscribeToEvent(E_UPDATE, HANDLER(JSUI, HandleUpdate));
     SubscribeToEvent(E_WIDGETEVENT, HANDLER(JSUI, HandleWidgetEvent));
     SubscribeToEvent(E_WIDGETLOADED, HANDLER(JSUI, HandleWidgetLoaded));
     SubscribeToEvent(E_POPUPMENUSELECT, HANDLER(JSUI, HandlePopupMenuSelect));
@@ -37,6 +40,21 @@ void JSUI::GatherWidgets(tb::TBWidget* widget, PODVector<tb::TBWidget*>& widgets
 
 }
 
+void JSUI::HandleUpdate(StringHash eventType, VariantMap& eventData)
+{
+    float timeStep = eventData[Update::P_TIMESTEP].GetFloat();
+
+    updateTime_ += timeStep;
+    if (updateTime_ > 1.0f)
+    {
+        UI* ui = GetSubsystem<UI>();
+        ui->PruneUnreachableWidgets();
+        updateTime_ = 0.0f;
+    }
+}
+
+
+
 void JSUI::HandleWidgetLoaded(StringHash eventType, VariantMap& eventData)
 {
     using namespace WidgetLoaded;

+ 2 - 0
Source/AtomicJS/Javascript/JSUI.h

@@ -24,9 +24,11 @@ public:
 private:
 
     duk_context* ctx_;
+    float updateTime_;
 
     void PushWidgetEventObject(VariantMap& eventData);
 
+    void HandleUpdate(StringHash eventType, VariantMap& eventData);
     void HandleWidgetEvent(StringHash eventType, VariantMap& eventData);
     void HandleWidgetLoaded(StringHash eventType, VariantMap& eventData);
     void HandlePopupMenuSelect(StringHash eventType, VariantMap& eventData);