Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* AvmExerciseContext
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Fröbel, NLSE, 2018-07-30
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace LtsSession
|
||||
{
|
||||
class LtsSessionDataDds;
|
||||
}
|
||||
|
||||
namespace OperatorManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ExerciseManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace InfrastructureManagement
|
||||
{
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
}
|
||||
}
|
||||
|
||||
namespace AudioVideoManagement
|
||||
{
|
||||
|
||||
namespace Interface
|
||||
{
|
||||
class Dtc;
|
||||
class Ftc;
|
||||
}
|
||||
|
||||
class StreamNameMapping;
|
||||
|
||||
/**
|
||||
* For each Exercise -- as defined by its Id -- AvmExerciseContextManager manages
|
||||
* an associated ExerciseContext. The ExerciseContext just holds all necessary entities.
|
||||
* The idea is that any number of PluginInterface-instances with the same exerciseId
|
||||
* share the same ExerciseContext.
|
||||
* For example, all PluginInterface-instances for Exercise 42 can share the *same* Dtc or Ftc.
|
||||
* Thus Dtc and Ftc are part of the ExerciseContext.
|
||||
*
|
||||
* The lifetime of an ExerciseContext can be longer than the lifetime of a PluginInterface-instance.
|
||||
* AvsSessionContext uses (references) entities from the ExerciseContext.
|
||||
* This is ok as it is guaranteed that the lifetime of the ExerciseContext is at least as long
|
||||
* as the lifetime of AvsSessionContext.
|
||||
* Actually they have the same lifetime -- if an AvsSessionContext exists.
|
||||
*
|
||||
* The difference is that there can be at most one AvsSessionContext at the same time.
|
||||
* But there can be at most one ExerciseContext *for each* exerciseId at the same time.
|
||||
* For the global exercise (exerciseId 0) there is never an AvsSessionContext.
|
||||
*
|
||||
* The following picuture illustrates the lifetimes:
|
||||
*
|
||||
* App1 (42) --------- ---------
|
||||
* App2 (42) --------- ---------
|
||||
* App3 (35) =========
|
||||
*
|
||||
* ExerciseContext (42) --------- --------------- ---------
|
||||
* ExerciseContext (35) =========
|
||||
*
|
||||
* AvsSessionContext (42) --------- ---------------
|
||||
* AvsSessionContext (35) =========
|
||||
*
|
||||
* PluginInterface-instance 1 (42) ---------
|
||||
* PluginInterface-instance 2 (42) ---------
|
||||
* PluginInterface-instance 3 (42) ---------
|
||||
* PluginInterface-instance 4 (35) =========
|
||||
* PluginInterface-instance 5 (42) ---------
|
||||
*
|
||||
* @see AvsSessionContext
|
||||
* @author Christian Fröbel
|
||||
*/
|
||||
class AvmExerciseContextManager
|
||||
{
|
||||
public:
|
||||
struct ExerciseContext;
|
||||
|
||||
~AvmExerciseContextManager();
|
||||
|
||||
/**
|
||||
* Don't use directly; use AvmExerciseContextHandle instead.
|
||||
*/
|
||||
///@{
|
||||
ExerciseContext *acquire(int exerciseId, LtsSession::LtsSessionDataDds *session);
|
||||
void release(int exerciseId, ExerciseContext *composite);
|
||||
///@}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Small internal helper class in order to keep track of the refCount.
|
||||
* Here, the refCount denotes the number of PluginInterface-Instances for the same Exercise.
|
||||
*/
|
||||
struct RefCountedContext
|
||||
{
|
||||
explicit RefCountedContext(std::unique_ptr<ExerciseContext> &&context);
|
||||
RefCountedContext(RefCountedContext &&) noexcept;
|
||||
~RefCountedContext();
|
||||
|
||||
int refCount{1};
|
||||
std::unique_ptr<ExerciseContext> context;
|
||||
};
|
||||
|
||||
using ExerciseId = int;
|
||||
std::map<ExerciseId, RefCountedContext> m_activeContexts;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper class to automatically call AvmExerciseContextManager::acquire()
|
||||
* and AvmExerciseContextManager::release() in the ctor and dtor respectively.
|
||||
* Instances can be moved but not copied.
|
||||
*
|
||||
* @author Christian Fröbel
|
||||
*/
|
||||
class AvmExerciseContextHandle
|
||||
{
|
||||
public:
|
||||
AvmExerciseContextHandle();
|
||||
AvmExerciseContextHandle(AvmExerciseContextManager *context, int exerciseId, LtsSession::LtsSessionDataDds *session);
|
||||
|
||||
operator bool() const { return m_context.get(); }
|
||||
|
||||
/** Only available when not in global Exercise */
|
||||
StreamNameMapping *streamNameMapping() const;
|
||||
|
||||
const std::shared_ptr<Interface::Dtc> &dtc() const;
|
||||
const std::shared_ptr<Interface::Ftc> &ftc() const;
|
||||
|
||||
OperatorManagement::Interface::Dtc *opmDtc() const;
|
||||
ExerciseManagement::Interface::Dtc *exmDtc() const;
|
||||
InfrastructureManagement::Interface::Dtc *ismDtc() const;
|
||||
|
||||
|
||||
private:
|
||||
using Releaser = std::function<void (AvmExerciseContextManager::ExerciseContext *)>;
|
||||
std::unique_ptr<AvmExerciseContextManager::ExerciseContext, Releaser> m_context;
|
||||
};
|
||||
|
||||
} // namespace AudioVideoManagement
|
||||
Reference in new issue
Block a user