From c8c605fc7ec342c6c64bcd7368c9327d9c818209 Mon Sep 17 00:00:00 2001
From: am0ebe <am0ebe@gmx.de>
Date: Thu, 22 Feb 2024 16:16:29 +0100
Subject: [PATCH] add closeCam, add cam->id(), change info, fix state bug, fix
 idx bug, more bugs...

---
 src/cam.cpp            | 53 +++++++++++++++++++++++++++---------------
 src/cam.h              | 11 ++++++---
 src/cmd/console.cpp    |  5 ++++
 src/cmd/console.h      |  1 +
 src/cmd/main.cpp       |  1 +
 src/core.cpp           | 44 +++++++++++++++++++++--------------
 src/core.h             |  6 +++--
 src/frameprocessor.cpp |  2 +-
 src/utils.cpp          |  3 ++-
 9 files changed, 82 insertions(+), 44 deletions(-)

diff --git a/src/cam.cpp b/src/cam.cpp
index 0984587..ce49737 100644
--- a/src/cam.cpp
+++ b/src/cam.cpp
@@ -13,11 +13,13 @@
 
 using State = Cam::State;
 using namespace VmbCPP;
+using namespace std::chrono;
 
 Cam::Cam(CameraPtr pCamera) : IPrinter(),
 _cam(pCamera),
 _name(""),
-_state(disconnected),
+_id(""),
+_state(closed),
 _frames(FramePtrVector(threadsPerCam())),
 _payloadSize(0LL),
 _pixelFormat("")
@@ -30,6 +32,7 @@ Cam::Cam(const Cam& other) :
 IPrinter(),
 _cam(other._cam),
 _name(other._name),
+_id(other._id),
 _state(other._state),
 _frames(other._frames),
 _payloadSize(other._payloadSize),
@@ -38,7 +41,7 @@ _pixelFormat(other._pixelFormat)
 
 Cam::~Cam()
 {
-	qDebug() << __FUNCTION__ << "():" << __LINE__ << "name:" << _name;
+	qDebug() << __FUNCTION__ << "():" << __LINE__ << "id:" << _id;
 	if( _state == recording )
 		stopRecording();
 
@@ -58,22 +61,33 @@ QString Cam::name()
 	return _name;
 }
 
+QString Cam::id()
+{
+	if( _id.isEmpty() )
+	{
+		std::string str;
+		f(_cam->GetID( str ));
+		_id = QString::fromStdString(str);
+	}
+	return _id;
+}
+
 State Cam::state() const
 {
 	return _state;
 }
 
-bool Cam::open()
+void Cam::open()
 {
-	if( ! f(_cam->Open( VmbAccessModeFull ),"open cam #"+_name) )
-		_state = opened;
-
-	return _state == opened;
+	f(_cam->Open( VmbAccessModeFull ),"open cam #"+_name);
+	//state change will be handled by CamObserver::CameraStateChanged
 }
 
 void Cam::close()
 {
-	_state = closed;
+	f(_cam->Close(),"close cam #"+_name);
+
+
 }
 
 /* Does:
@@ -89,7 +103,7 @@ void Cam::close()
 	TODO if( !_curCam->isOpen() ) return; >> listener
 	2d get frameID
 */
-void Cam::startRecording(std::chrono::seconds dur)
+void Cam::startRecording(seconds dur)
 {
 	try
 	{
@@ -128,14 +142,14 @@ void Cam::startRecording(std::chrono::seconds dur)
 	_state = recording;
 
 	// Convert to milliseconds
-	auto dur_ms = std::chrono::duration_cast<std::chrono::milliseconds>(dur).count();
+	auto dur_ms = duration_cast<milliseconds>(dur).count();
 	QTimer::singleShot(dur_ms, this, SLOT(stopRecording()));
 }
 
-void Cam::startRecording(std::chrono::minutes dur)
+void Cam::startRecording(minutes dur)
 {
 	// Convert to seconds
-	auto dur_s = std::chrono::duration_cast<std::chrono::seconds>(dur);
+	auto dur_s = duration_cast<seconds>(dur);
 	startRecording(dur_s);
 }
 
@@ -172,11 +186,12 @@ QString Cam::info()
 	{
 		std::string str;
 		g(_cam->GetID( str ));
-		camInfo += QString::fromStdString(str) + DELIM;
+		_id = QString::fromStdString(str);
+		camInfo += _id + DELIM;
 
-		g(_cam->GetName( str ));
-		_name = QString::fromStdString(str);
-		camInfo += _name + DELIM;
+		// g(_cam->GetName( str ));
+		// _name = QString::fromStdString(str);
+		// camInfo += _name + DELIM;
 
 		g(_cam->GetModel( str ));
 		camInfo += QString::fromStdString(str) + DELIM;
@@ -216,13 +231,13 @@ QString Cam::stateToString(const State& state)
 
 void Cam::toggleOpenClose()
 {
+	qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << stateToString(_state);
 	if( _state == opened )
-		close();
+		_state = closed;
 	else if ( _state == closed )
-		open();
+		_state = opened;
 	else
 		error("toggleOpenClose: cam state is not closed or opened");
-
 }
 
 void Cam::onCameraDisconnected()
diff --git a/src/cam.h b/src/cam.h
index cfb9e8d..42e162c 100644
--- a/src/cam.h
+++ b/src/cam.h
@@ -16,6 +16,9 @@ using VmbCPP::FramePtr;
 using VmbCPP::FeaturePtr;
 using VmbCPP::FramePtrVector;
 
+using std::chrono::minutes;
+using std::chrono::seconds;
+
 class Cam;
 using CamPtr = std::shared_ptr<Cam>;
 using CamPtrVector = std::vector<CamPtr>;
@@ -38,14 +41,15 @@ public:
 	~Cam();
 
 	QString name();
+	QString id();
 	State state() const;
 	static QString stateToString(const State&);
 	void toggleOpenClose();
 
-	bool open();
+	void open();
 	void close();
-	void startRecording(std::chrono::minutes dur);
-	void startRecording(std::chrono::seconds dur); //use as literals "1s, 1min"
+	void startRecording(minutes dur);
+	void startRecording(seconds dur); //use as literals "1s, 1min"
 	QString info();
 	inline CameraPtr getCameraPtr() const { return _cam; }
 
@@ -56,6 +60,7 @@ public slots:
 private:
 	CameraPtr _cam;
 	QString _name;
+	QString _id;
 	State _state;
 	FramePtrVector _frames;
 	VmbInt64_t _payloadSize;
diff --git a/src/cmd/console.cpp b/src/cmd/console.cpp
index 6ea2616..688d0bc 100644
--- a/src/cmd/console.cpp
+++ b/src/cmd/console.cpp
@@ -98,6 +98,7 @@ void Console::printHelp()
 	<< "h: print this help"
 	<< "1-9: select camera"
 	<< "d: change duration of recording"
+	<< "c: close current camera"
 	<< "o: open current camera"
 	<< "r: start recording"
 	<< "t: stop recording"
@@ -155,6 +156,10 @@ void Controller::keyPress(const QChar& key)
 				emit setDuration(dur);
 				break;
 
+			case 'c':
+				emit closeCam();
+				break;
+
 			case 'o':
 				emit openCam();
 				break;
diff --git a/src/cmd/console.h b/src/cmd/console.h
index 9946186..0d68bfd 100644
--- a/src/cmd/console.h
+++ b/src/cmd/console.h
@@ -60,6 +60,7 @@ class Controller : public QObject
 		// to core
 		void listCams();
 		void openCam();
+		void closeCam();
 		void cam(int);
 		void startRecording();
 		void stopRecording();
diff --git a/src/cmd/main.cpp b/src/cmd/main.cpp
index 8b9c5ea..d7ea8b5 100644
--- a/src/cmd/main.cpp
+++ b/src/cmd/main.cpp
@@ -20,6 +20,7 @@ int main(int argc, char *argv[])
 	//ui (controller) -> vmb (core)
 	QObject::connect(&controller, &Controller::listCams,			&core, &Core::listCams);
 	QObject::connect(&controller, &Controller::openCam, 			&core, &Core::openCam);
+	QObject::connect(&controller, &Controller::closeCam, 			&core, &Core::closeCam);
 	QObject::connect(&controller, &Controller::cam, 				&core, &Core::cam);
 	QObject::connect(&controller, &Controller::startRecording, 	&core, &Core::startRecording);
 	QObject::connect(&controller, &Controller::stopRecording,	&core, &Core::stopRecording);
diff --git a/src/core.cpp b/src/core.cpp
index 43ab6cd..3164c97 100644
--- a/src/core.cpp
+++ b/src/core.cpp
@@ -39,7 +39,7 @@ void Core::init()
 
 	auto camObserver = new CamObserver();
 	connect( camObserver, SIGNAL(cameraListChanged()), this, SLOT(listCams()) ); //listcams calls updateCams!
-	connect( camObserver, SIGNAL(cameraStateChanged(CameraPtr)), this, SLOT(updateCamState(CameraPtr)) ); //
+	connect( camObserver, SIGNAL(cameraStateChanged(CameraPtr)), this, SLOT(toggleCamState(CameraPtr)) ); //
 
 	f(_sys.RegisterCameraListObserver(ICameraListObserverPtr(camObserver)), "register cam observer");
 
@@ -92,37 +92,33 @@ void Core::updateCameras()
 	auto it = _cameras.begin();
 	while (it != _cameras.end())
 	{
+		qDebug() << "check " << (*it)->id();
+
 		bool found = false;
 		for (const auto& vcam : vmbCameras)
 		{
 			if ((*it)->getCameraPtr() == vcam)
 			{
 				found = true;
+				++it;
 				break;
 			}
 		}
+
 		if (!found)
 		{
+			qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << " !!! ";
 			print({"cam disconnected",(*it)->name()});
 			it = _cameras.erase(it);
 		}
-		else
-		{
-			++it;
-		}
 	}
 } // now ~Camera() should be called on removed cams. >> camObserver
 
-void Core::updateCamState(CameraPtr vcam)
+void Core::toggleCamState(CameraPtr vcam)
 {
 	for (const auto& cam : _cameras)
-	{
 		if (cam->getCameraPtr() == vcam)
-		{
-			cam->toggleOpenClose();
-			break;
-		}
-	}
+			return cam->toggleOpenClose();
 }
 
 // update + print camlist
@@ -137,7 +133,14 @@ void Core::listCams()
 	auto idx=0;
 	for ( auto camera : _cameras  )
 	{
-		QString camInfo = QString::number(++idx) + ". " + camera->info();
+		QString camInfo;
+		if( camera == cam() )
+			camInfo += " * ";
+		else
+			camInfo += "   ";
+		camInfo += "Cam" + QString::number(++idx) + ": ";
+		camInfo += camera->info();
+
 		allCamInfo << camInfo;
 	}
 
@@ -147,14 +150,19 @@ void Core::listCams()
 	print(allCamInfo);
 }
 
-bool Core::openCam()
+void Core::openCam()
 {
 	if( cam() )
-		return cam()->open();
+		cam()->open();
+}
 
-	return false;
+void Core::closeCam()
+{
+	if( cam() )
+		cam()->close();
 }
 
+
 /*
 current camera getter + setter
 -1 is dflt and means "return current camera"
@@ -162,13 +170,13 @@ other idx's update idx and return new curCam
 */
 CamPtr Core::cam(const unsigned long &idx)
 {
-	static unsigned long curIdx = 123;
+	static unsigned long curIdx = 0;
 	if( idx != -1UL )
 		curIdx = idx;
 
 	try
 	{
-		print("set cam",idx+1);
+		// print("set cam",idx+1);
 		return _cameras.at(curIdx);
 	}
 	catch (const std::out_of_range& oor)
diff --git a/src/core.h b/src/core.h
index bd1f9a2..77c1f56 100644
--- a/src/core.h
+++ b/src/core.h
@@ -23,8 +23,10 @@ public:
 
 public slots:
 	void listCams();
-	void updateCamState(CameraPtr);
-	bool openCam();
+	void toggleCamState(CameraPtr);
+	void openCam();
+	void closeCam();
+	// XXX add new func
 
 	CamPtr cam(const unsigned long &idx=-1);
 
diff --git a/src/frameprocessor.cpp b/src/frameprocessor.cpp
index c07f2fa..d098fcf 100644
--- a/src/frameprocessor.cpp
+++ b/src/frameprocessor.cpp
@@ -54,7 +54,7 @@ void FrameProcessor::processFrame()
 	cv::imwrite(filename.toStdString(), frameMat, params);
 	qDebug() << "Frame saved as JPEG: " << filename;
 
-	QThread::msleep(500); //simulate processing time
+	QThread::msleep(2000); //simulate processing time // testing
 
 	emit frameProcessed(m_pframe);
 }
diff --git a/src/utils.cpp b/src/utils.cpp
index 50085f8..7b59e38 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -26,7 +26,8 @@ int ncam()
 
 int threadsPerCam()
 {
-	return std::ceil(static_cast<double>(QThread::idealThreadCount()) / ncam() ); //round up!
+	// return std::ceil(static_cast<double>(QThread::idealThreadCount()) / ncam() ); //round up!
+	return 2; // for testing
 }
 
 const QString getVersion()
-- 
GitLab