separate pytwrpper from predictorWrappery
[trackerpp.git] / src / Engine.cpp
index c044ab7..fbdf337 100644 (file)
@@ -1,47 +1,54 @@
 #include <mutex>
 #include <thread>
+#include <condition_variable>
 #include "Engine.h"
 #include "Logger.h"
+#include "PredictorWrapper.h"
 
 using namespace suanzi;
+using namespace std;
 
-const static std::string TAG = "Engine";
-
+static const std::string TAG = "Engine";
 static std::mutex g_mutex;
-static Engine* g_instance = nullptr;
+static EngineWPtr g_instance;
 
-Engine::Engine()
-{
-    detector = new Detector();
-    tracker = new Tracker();
-}
+typedef std::shared_ptr<std::vector<Person>> PersonsInfoPtr;
 
-Engine* Engine::create()
+EnginePtr Engine::create()
 {
     LOG_DEBUG(TAG, "create");
     std::lock_guard<std::mutex> lock(g_mutex);
-    if (g_instance)
-        return g_instance;
-    
-    Engine* instance (new Engine());
+    if (g_instance.lock()){
+        LOG_ERROR(TAG, "already exists");
+        return EnginePtr();
+    }
+    EnginePtr instance (new Engine());
     g_instance = instance;
-    return g_instance;
+    return instance;
 }
 
-void Engine::destroy()
+Engine::Engine()
 {
-    delete g_instance;
+    //detector = std::make_shared<Detector>();
+    detector = DetectorPtr(new Detector());
 }
 
 Engine::~Engine()
 {    
-    delete detector;
-    delete tracker;
+    destroy();
+}
+
+void Engine::destroy()
+{
+    LOG_DEBUG(TAG, "destroy");
+    detector.reset();
+    multiTracker.reset();
+    reader.reset();
+    observer_list.clear();
 }
 
 void Engine::setVideoSrc(VideoSrcType type, const std::string& url)
 {
-    videoSrc = url;
     reader = VideoReaderFactory::createVideoReader(type, url);
 }
 
@@ -49,14 +56,18 @@ void Engine::run()
 {
     LOG_DEBUG(TAG, "run");
     cv::Mat frame;
+    Detection detections[128];
     while (reader->read(frame)){
-        detector->detect(frame);
+        LOG_DEBUG(TAG, "Size: " << frame.cols  <<  "x" << frame.rows);
+        int total = detector->detect(frame, detections);
+        multiTracker->update(total, detections, frame);
     }
 }
 
 void Engine::start()
 {
     LOG_DEBUG(TAG, "start");
+    multiTracker = std::make_shared<MultiTracker>(g_instance);
     if (!reader){
         LOG_ERROR(TAG, "reader is null. exit");
         return;
@@ -67,5 +78,54 @@ void Engine::start()
 
 void Engine::addObserver(EngineObserver *observer)
 {
+    LOG_DEBUG(TAG, "addObserver");
     observer_list.insert(observer);
 }
+
+
+// WorkItem class for event thread
+class PersonInEventWorkItem : public WorkItem
+{
+public:
+    PersonInEventWorkItem(std::set<EngineObserver*> obs, PersonsInfoPtr info) : obs(obs), info(info){
+    }
+    ~PersonInEventWorkItem(){}
+    void run (){
+        for (auto o : obs){
+            o->onPersonsIn(*(info.get()));
+        }
+    }
+private:
+    std::set<EngineObserver*> obs;
+    PersonsInfoPtr info;
+};
+
+class PersonOutEventWorkItem : public WorkItem
+{
+public:
+    PersonOutEventWorkItem(std::set<EngineObserver*> obs, PersonsInfoPtr info) : obs(obs), info(info){
+    }
+    ~PersonOutEventWorkItem(){}
+    void run (){
+        for (auto o : obs){
+            o->onPersonsIn(*(info.get()));
+        }
+    }
+private:
+    std::set<EngineObserver*> obs;
+    PersonsInfoPtr info;
+};
+
+void Engine::onPersonsOut(const std::vector<Person>& p)
+{
+    LOG_DEBUG(TAG, "onPersonOut");
+    PersonsInfoPtr pp = std::make_shared<std::vector<Person>>(p);
+    eventThread.enqueue(new PersonOutEventWorkItem(this->observer_list, pp));
+}
+
+void Engine::onPersonsIn(const std::vector<Person>& p)
+{
+    LOG_DEBUG(TAG, "onPersonIn");
+    PersonsInfoPtr pp = std::make_shared<std::vector<Person>>(p);
+    eventThread.enqueue(new PersonInEventWorkItem(this->observer_list, pp));
+}