Commit 3e8647f9 authored by 刘乐's avatar 刘乐

1, 水力模型的新接口

parent ba785fcc
#include "CivHydrTest.h"
#include "CivHydrFuncInter.h"
#include <iostream>
// 水力测试
void CivConHydrTest::test(char* uri)
{
int succ = hdyrSimulation(uri);
std::cout << "测试结果:" << succ << std::endl;
}
// 水质测试
void CivConQuaTest::test(char* uri)
{
int succ = qualitySimulation(uri);
std::cout << "测试结果:" << succ << std::endl;
}
// 追踪分析
void CivConTrackTest::test(char* uri)
{
char result[1024 * 32];
char sn[32];
strcpy_s(sn, "JD00000680");
int succ = trackingSimulation(uri, sn, 13, result);
std::cout << result << std::endl;
std::cout << "测试结果:" << succ << std::endl;
}
/**
获取时段数据
*/
void CivConGetDataTest::test(char* uri)
{
const char* date = "2020-07-13";
char* dates = const_cast<char*>(date);
const char* interval = "4";
char* intervals = const_cast<char*>(interval);
bool isSucces = getDataByInterval(uri, dates, intervals);
std::cout << "测试结果:" << isSucces << std::endl;
};
#pragma once
class CivHydrTest
{
public:
virtual void test(char* uri) = 0;
};
// 水力测试
class CivConHydrTest :public CivHydrTest
{
public:
virtual void test(char* uri);
};
// 水质测试
class CivConQuaTest :public CivHydrTest
{
public:
virtual void test(char* uri);
};
// 追踪分析
class CivConTrackTest :public CivHydrTest
{
public:
virtual void test(char* uri);
};
/**
获取时段数据
*/
class CivConGetDataTest :public CivHydrTest
{
public:
virtual void test(char* uri);
};
#include "CivTestContext.h"
#include "CivHydrTest.h"
CivTestContext::CivTestContext(CivHydrTest* test)
:mTest(test)
{
}
CivTestContext::~CivTestContext()
{
delete mTest;
}
void CivTestContext::contextTest(char* uri)
{
if (mTest == nullptr)
return;
mTest->test(uri);
}
\ No newline at end of file
#pragma once
class CivHydrTest;
class CivTestContext
{
public:
explicit CivTestContext(CivHydrTest* test);
~CivTestContext();
void contextTest(char* uri);
private:
CivHydrTest* mTest;
};
...@@ -143,8 +143,14 @@ ...@@ -143,8 +143,14 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="CivHydrTest.cpp" />
<ClCompile Include="CivTestContext.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ClInclude Include="CivHydrTest.h" />
<ClInclude Include="CivTestContext.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
......
...@@ -18,5 +18,19 @@ ...@@ -18,5 +18,19 @@
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">
<Filter>源文件</Filter> <Filter>源文件</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="CivHydrTest.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="CivTestContext.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="CivHydrTest.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="CivTestContext.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>
\ No newline at end of file
#include <iostream> #include <iostream>
#include <libpq-fe.h> #include <libpq-fe.h>
#include "CivHydrFuncInter.h" #include "CivHydrFuncInter.h"
#include "iostream" #include "iostream"
#include "time.h" #include "time.h"
#include "string.h" #include "string.h"
#include "CivTestContext.h"
#include "CivHydrTest.h"
using namespace std; using namespace std;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
const char* uri = "host=192.168.19.100 port=5432 dbname=JinXian user=postgres password=admin"; const char* uri = "host=192.168.19.100 port=5432 dbname=JinXian user=postgres password=admin";
char* findUri = const_cast<char*>(uri); char* findUri = const_cast<char*>(uri);
char* result = (char*)malloc(2048);
char sn[32]; // 测试水力
strcpy_s(sn, "JD00000680"); /*CivTestContext context(new CivConHydrTest());
int succ = trackingSimulation(findUri, sn,2, result); context.contextTest(findUri);*/
std::cout << succ << std::endl;
free(result);
/*const char* date = "2020-07-02"; // 测试水质
char* dates = const_cast<char*>(date); /*CivTestContext context(new CivConQuaTest());
context.contextTest(findUri);*/
const char* interval = "4"; // 测试追踪分析
char* intervals = const_cast<char*>(interval); /*CivTestContext context(new CivConTrackTest());
bool isSucces = getDataByInterval(findUri, dates, intervals); context.contextTest(findUri);*/
std::cout << isSucces << std::endl;*/
getchar(); // 测试根据时段获取值
CivTestContext context(new CivConGetDataTest());
context.contextTest(findUri);
getchar();
return 0; return 0;
} }
\ No newline at end of file
...@@ -204,6 +204,7 @@ void CivInpBuilder::buildQuality() ...@@ -204,6 +204,7 @@ void CivInpBuilder::buildQuality()
{ {
ASSERT(mDbConn, mNewInp) ASSERT(mDbConn, mNewInp)
CivQuality quality; CivQuality quality;
if (!mDbConn->getQuality(quality)) if (!mDbConn->getQuality(quality))
return; return;
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
#include "CivHydrCalc.h" #include "CivHydrCalc.h"
#include "CivSysLog.h" #include "CivSysLog.h"
#include "CivPgConn.h"
#include "CivHydrSimulation.h"
bool DLLEXPORT simulation(char* uri, char* netName, char* flag) bool DLLEXPORT simulation(char* uri, char* netName, char* flag)
{ {
...@@ -39,32 +42,30 @@ bool DLLEXPORT hdySimulation(char* uri, char* netName) ...@@ -39,32 +42,30 @@ bool DLLEXPORT hdySimulation(char* uri, char* netName)
return true; return true;
} }
//bool DLLEXPORT qualitySimulation(char* uri, char* netName, char* type) bool DLLEXPORT getDataByInterval(char* uri, char* date, char* interval)
//{
// return true;
//}
bool DLLEXPORT qualityTrackingSimulation(char* uri, char* netName, char* nodeSn, char* time)
{ {
CivDbConn* dbConn = new CivPgConn(uri);
if (!dbConn->open())
{
delete dbConn;
return false;
}
if (!dbConn->updateNodeByInterval(date, interval))
{
delete dbConn;
return false;
}
if (!dbConn->updateLinkByInterval(date, interval))
{
delete dbConn;
return false;
}
return true; return true;
} }
bool DLLEXPORT getDataByInterval(char* uri, char* date, char* interval)
{
CivHydrCalc* calc = new CivHydrCalc(uri, "");
char inp[128];
strcpy(inp, "test.inp");
bool flag = calc->exportInp(inp);
std::cout << flag << std::endl;
//flag = calc->getDataByInterval(date, interval);
delete calc;
return flag;
}
#include "CivPgConn.h"
#include "CivHydrSimulation.h"
bool DLLEXPORT hdyrSimulation(char* uri) bool DLLEXPORT hdyrSimulation(char* uri)
{ {
...@@ -101,7 +102,7 @@ bool DLLEXPORT qualitySimulation(char* uri) ...@@ -101,7 +102,7 @@ bool DLLEXPORT qualitySimulation(char* uri)
return flag; return flag;
} }
bool DLLEXPORT trackingSimulation(char* uri, char* sN, int hours, char* result) bool DLLEXPORT trackingSimulation(char* uri, char* sN, int hours, char* result)
{ {
// 创建数据库连接 // 创建数据库连接
...@@ -113,15 +114,16 @@ bool DLLEXPORT trackingSimulation(char* uri, char* sN, int hours, char* result) ...@@ -113,15 +114,16 @@ bool DLLEXPORT trackingSimulation(char* uri, char* sN, int hours, char* result)
//开始模拟 //开始模拟
bool flag = mHyDr->trackingSimulation(sN, hours); bool flag = mHyDr->trackingSimulation(sN, hours);
std::string strResult;
if (flag) if (flag)
{ {
std::string strResult; mHyDr->getTrackingResult(hours, strResult);
mHyDr->getTrackingResult(hours, strResult); strcpy(result, strResult.c_str());
result = const_cast<char*>(strResult.c_str());
} }
std::cout << result << std::endl;
delete pgConn; delete pgConn;
delete mHyDr; delete mHyDr;
return flag; return flag;
} }
\ No newline at end of file
...@@ -28,7 +28,7 @@ extern "C" { ...@@ -28,7 +28,7 @@ extern "C" {
*@param result:输出结果:json字符串 *@param result:输出结果:json字符串
*@return 1:成功,其他值失败 *@return 1:成功,其他值失败
*/ */
bool DLLEXPORT trackingSimulation(char* uri, char* sN, int hours, char* result); bool DLLEXPORT trackingSimulation(char* uri, char* sN, int hours,char* result);
/** /**
*@brief 模拟计算 *@brief 模拟计算
...@@ -53,14 +53,7 @@ extern "C" { ...@@ -53,14 +53,7 @@ extern "C" {
*/ */
//bool DLLEXPORT qualitySimulation(char* uri, char* netName, char* type); //bool DLLEXPORT qualitySimulation(char* uri, char* netName, char* type);
/**
*@brief 水质追踪模拟计算
*@param uri: 管网数据库连接
*@param netName: 管网名
*@param nodeSn: 追踪节点编号
*@param time: 追踪时段
*/
bool DLLEXPORT qualityTrackingSimulation(char* uri, char* netName, char* nodeSn, char* time);
/** /**
*@brief 获取管网计算特定时段的结果 *@brief 获取管网计算特定时段的结果
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "CivSysLog.h" #include "CivSysLog.h"
#include "epanet2.h" #include "epanet2.h"
#include "../pandaDbManager/CivCommonUtils.h" #include "../pandaDbManager/CivCommonUtils.h"
#include "CivTrackingResultCache.h"
CivHydrSimulation::CivHydrSimulation() CivHydrSimulation::CivHydrSimulation()
...@@ -182,7 +183,6 @@ bool CivHydrSimulation::brushingResult() ...@@ -182,7 +183,6 @@ bool CivHydrSimulation::brushingResult()
{ {
clearSamePeriodValue(mDbConn, CurrentDate); clearSamePeriodValue(mDbConn, CurrentDate);
// 更新数据 // 更新数据
if (!mResultCache.updateToDb(mDbConn)) if (!mResultCache.updateToDb(mDbConn))
{ {
...@@ -262,12 +262,14 @@ bool CivHydrSimulation::trackingSimulation(char* snNode, int hour) ...@@ -262,12 +262,14 @@ bool CivHydrSimulation::trackingSimulation(char* snNode, int hour)
return false; return false;
} }
//模拟数据刷新 // 扩散分析不存储数据
if (!brushingResult()) ////模拟数据刷新
{ //if (!brushingResult())
CivSysLog::getInstance()->error("追踪分析计算失败", "CivHydrCalc", __FUNCTION__); //{
return false; // CivSysLog::getInstance()->error("追踪分析计算失败", "CivHydrCalc", __FUNCTION__);
} // return false;
//}
return true; return true;
} }
...@@ -370,28 +372,19 @@ bool CivHydrSimulation::qualityCompute() ...@@ -370,28 +372,19 @@ bool CivHydrSimulation::qualityCompute()
ENcloseQ(); ENcloseQ();
ENclose(); ENclose();
// 清除当前之前的模拟的数据
clearSamePeriodValue(mDbConn, CurrentDate);
// 更新数据
if (!mResultCache.updateToDb(mDbConn))
{
CivSysLog::getInstance()->error("水质分析结果存储失败", "CivHydrCalc", __FUNCTION__);
return false;
}
CivSysLog::getInstance()->info("水质分析结果存储成功", "CivHydrCalc", __FUNCTION__);
// 更新管网数据库数据
updateLastestDataToGisNet(mDbConn, "0");
CivSysLog::getInstance()->info("结束水质分析计算", "CivHydrCalc", __FUNCTION__); CivSysLog::getInstance()->info("结束水质分析计算", "CivHydrCalc", __FUNCTION__);
return true; return true;
} }
void CivHydrSimulation::getTrackingResult(int hours, std::string& result) void CivHydrSimulation::getTrackingResult(int hours, std::string& newresult)
{ {
std::string result;
result.append("["); result.append("[");
CivTrackingResultCache trackingCache;
trackingCache.cacheInfoFromDb(mDbConn);
for (int i = 0; i < hours; i++) for (int i = 0; i < hours; i++)
{ {
NodeResultItems nodeItemsMap; NodeResultItems nodeItemsMap;
...@@ -406,15 +399,26 @@ void CivHydrSimulation::getTrackingResult(int hours, std::string& result) ...@@ -406,15 +399,26 @@ void CivHydrSimulation::getTrackingResult(int hours, std::string& result)
size_t nodeTotal = nodeItemsMap.size(); size_t nodeTotal = nodeItemsMap.size();
while (nodeIter != nodeItemsMap.end()) while (nodeIter != nodeItemsMap.end())
{ {
if (nodeIter->second.dQuality < 0.8)
if (nodeIter->second.dQuality>0)
{ {
nodeTempText.append(nodeIter->first.c_str()); nodeTempText.append("[");
std::string sn = nodeIter->first;
nodeTempText.append(sn.c_str());
Junctions junction;
trackingCache.getNodeInfoBySn(sn, junction);
nodeTempText.append(",");
nodeTempText.append(junction.xCoord);
nodeTempText.append(","); nodeTempText.append(",");
nodeTempText.append(junction.yCoord);
nodeTempText.append("],");
} }
nodeIter++; nodeIter++;
} }
nodeTempText.append("]"); std::string newNodeTempText = nodeTempText.substr(0, nodeTempText.length() - 1);
newNodeTempText.append("]");
// 追踪管段编号 // 追踪管段编号
...@@ -427,24 +431,35 @@ void CivHydrSimulation::getTrackingResult(int hours, std::string& result) ...@@ -427,24 +431,35 @@ void CivHydrSimulation::getTrackingResult(int hours, std::string& result)
{ {
if (linkIter->second.dQuality > 0) if (linkIter->second.dQuality > 0)
{ {
linkTempText.append(linkIter->first.c_str()); std::string sn = linkIter->first;
if (index != total) linkTempText.append("[");
{ linkTempText.append(sn.c_str());
linkTempText.append(",");
} Pipes pipe;
trackingCache.getPipeInfoBySn(sn, pipe);
linkTempText.append(",");
linkTempText.append(pipe.startX);
linkTempText.append(",");
linkTempText.append(pipe.startX);
linkTempText.append(",");
linkTempText.append(pipe.endX);
linkTempText.append(",");
linkTempText.append(pipe.endY);
linkTempText.append("],");
} }
linkIter++; linkIter++;
index++;
} }
linkTempText.append("]"); std::string newLinkTempText = linkTempText.substr(0, linkTempText.length() - 1);
/* result.append(tempText); newLinkTempText.append("]");
if (i <(hours-1))
{ result.append("[");
result.append("|"); result.append(newNodeTempText);
}*/ result.append("|");
result.append(newLinkTempText);
result.append("],");
} }
result.append("]"); newresult = result.substr(0, result.length() -1 );
newresult.append("]");
} }
void CivHydrSimulation::getNodeResult(short time) void CivHydrSimulation::getNodeResult(short time)
......
...@@ -315,7 +315,15 @@ void CivNewInp::setQuality(const CivQuality& quality) ...@@ -315,7 +315,15 @@ void CivNewInp::setQuality(const CivQuality& quality)
{ {
CivQuality::Table table = *iter; CivQuality::Table table = *iter;
writeStringFormat(table.ID); writeStringFormat(table.ID);
writeString(table.InitQuality); if (mQualityType == ANALYSIS_TRACE)
{
writeString("0");
}
else
{
writeString(table.InitQuality);
}
} }
writeString(""); writeString("");
} }
......
...@@ -743,35 +743,19 @@ bool CivPgConn::getPatterns(CivPatterns& patterns) ...@@ -743,35 +743,19 @@ bool CivPgConn::getPatterns(CivPatterns& patterns)
int rows = PQntuples(mResult); int rows = PQntuples(mResult);
int columns = PQnfields(mResult); int columns = PQnfields(mResult);
std::map<std::string, std::vector<std::string>> typeMap;
for (int i = 0; i < rows; i++) for (int i = 0; i < rows; i++)
{ {
char* name = PQgetvalue(mResult, i, 0); char* name = PQgetvalue(mResult, i, 0);
char* val = PQgetvalue(mResult, i, 1); char* val = PQgetvalue(mResult, i, 1);
char* type = PQgetvalue(mResult, i, 2);
CivPatterns::PatternTable pTable;
pTable.name = name;
pTable.val = val;
typeMap[type].push_back(name); patterns.addItem(pTable);
typeMap[type].push_back(val);
} }
for (auto iter = typeMap.begin(); iter != typeMap.end(); iter++)
{
CivPatterns::PatternTable pTable;
pTable.name = iter->first;
std::vector<std::string> valVec = iter->second;
int total = valVec.size();
// 拼接字符串
char value[512] = "";
for (int i = 0; i < total; i++)
{
strcat_s(value, valVec[i].c_str());
strcat_s(value, " ");
}
pTable.val = value;
patterns.addItem(pTable);
}
PQclear(mResult); PQclear(mResult);
return true; return true;
...@@ -898,7 +882,7 @@ bool CivPgConn::getFieldValueFromTable(const std::string& table, ...@@ -898,7 +882,7 @@ bool CivPgConn::getFieldValueFromTable(const std::string& table,
for (int i = 0; i < rows; i++) for (int i = 0; i < rows; i++)
{ {
std::vector<std::string> vecRes; std::vector<std::string> vecRes;
for (int j = 0; j < columns; i++) for (int j = 0; j < columns; j++)
{ {
std::string res = PQgetvalue(mResult, i, j); std::string res = PQgetvalue(mResult, i, j);
vecRes.push_back(res); vecRes.push_back(res);
...@@ -911,36 +895,3 @@ bool CivPgConn::getFieldValueFromTable(const std::string& table, ...@@ -911,36 +895,3 @@ bool CivPgConn::getFieldValueFromTable(const std::string& table,
return true; return true;
} }
bool CivPgConn::getFieldValueFromPipes(const std::vector<std::string>& fileds, std::vector < std::vector<std::string>> & result)
{
std::string sql = "select pipe1.\"编号\",ST_X(ST_StartPoint(ST_GeometryN(pipe1.\"geom\", 1))) as startX,\
ST_Y(ST_StartPoint(ST_GeometryN(pipe1.\"geom\", 1))) as startY,\
ST_X(ST_EndPoint(ST_GeometryN(pipe1.\"geom\", 1))) as endX,\
ST_Y(ST_EndPoint(ST_GeometryN(pipe1.\"geom\", 1))) as endY\
from public.\"管段\" as pipe1";
std::string utf8Sql = TransUTFCoding(sql);
if (!execSql(utf8Sql))
{
CivSysLog::getInstance()->error(mLastError, "CivPgConn", __FUNCTION__);
return false;
}
int rows = PQntuples(mResult);
int columns = PQnfields(mResult);
for (int i = 0; i < rows; i++)
{
std::vector<std::string> vecRes;
for (int j = 0; j < columns; i++)
{
std::string res = PQgetvalue(mResult, i, j);
vecRes.push_back(res);
}
result.push_back(vecRes);
}
PQclear(mResult);
return true;
}
\ No newline at end of file
...@@ -10,6 +10,25 @@ void CivTrackingResultCache::cacheInfoFromDb(CivDbConn* dbConn) ...@@ -10,6 +10,25 @@ void CivTrackingResultCache::cacheInfoFromDb(CivDbConn* dbConn)
cachePipeInfoFromDb(dbConn); cachePipeInfoFromDb(dbConn);
} }
void CivTrackingResultCache::getNodeInfoBySn(const std::string& sn, Junctions& junctions)
{
auto iterm = mNodeCache.find(sn);
if (iterm == mNodeCache.end())
return;
junctions = iterm->second;
}
void CivTrackingResultCache::getPipeInfoBySn(const std::string& sn, Pipes& pipes)
{
auto iterm = mPipesCache.find(sn);
if (iterm == mPipesCache.end())
return;
pipes = iterm->second;
}
void CivTrackingResultCache::transformToJsonStr(std::string jsonStr) void CivTrackingResultCache::transformToJsonStr(std::string jsonStr)
{ {
jsonStr.append("{node:["); jsonStr.append("{node:[");
...@@ -21,8 +40,6 @@ void CivTrackingResultCache::transformToJsonStr(std::string jsonStr) ...@@ -21,8 +40,6 @@ void CivTrackingResultCache::transformToJsonStr(std::string jsonStr)
std::string sNo = iter->first; std::string sNo = iter->first;
Junctions junctions = iter->second; Junctions junctions = iter->second;
} }
jsonStr.append("}"); jsonStr.append("}");
jsonStr.append("],link:["); jsonStr.append("],link:[");
...@@ -112,22 +129,3 @@ void CivTrackingResultCache::cachePipeInfoFromDb(CivDbConn* dbConn) ...@@ -112,22 +129,3 @@ void CivTrackingResultCache::cachePipeInfoFromDb(CivDbConn* dbConn)
} }
} }
void CivTrackingResultCache::addNodeQuality(const std::string& sn, double quality)
{
auto iter = mNodeCache.find(sn);
if (iter == mNodeCache.end())
return;
Junctions junctions = iter->second;
junctions.mQualitys.push_back(quality);
}
void CivTrackingResultCache::addPipeQuality(const std::string& sn, double quality)
{
auto iter = mPipesCache.find(sn);
if (iter == mPipesCache.end())
return;
Pipes pipes = iter->second;
pipes.mQualitys.push_back(quality);
}
\ No newline at end of file
...@@ -4,14 +4,13 @@ ...@@ -4,14 +4,13 @@
#include <vector> #include <vector>
class CivDbConn; class CivDbConn;
#define CACHEEXPORT __declspec(dllexport)
// 节点 // 节点
typedef struct typedef struct
{ {
std::string sNo; // 本点号 std::string sNo; // 本点号
std::string xCoord; // x坐标 std::string xCoord; // x坐标
std::string yCoord; // y坐标 std::string yCoord; // y坐标
std::vector<double> mQualitys; // 时段需水量集合
} Junctions; } Junctions;
// 管段 // 管段
...@@ -22,13 +21,12 @@ typedef struct ...@@ -22,13 +21,12 @@ typedef struct
std::string startY; // 起始节点Y std::string startY; // 起始节点Y
std::string endX;// 终止节点X std::string endX;// 终止节点X
std::string endY;// 终止节点Y std::string endY;// 终止节点Y
std::vector<double> mQualitys; // 时段需水量集合
}Pipes; }Pipes;
/** /**
*追踪节点,管段信息缓存类 *追踪节点,管段信息缓存类
*/ */
class CivTrackingResultCache class CACHEEXPORT CivTrackingResultCache
{ {
public: public:
/** /**
...@@ -44,16 +42,18 @@ public: ...@@ -44,16 +42,18 @@ public:
void transformToJsonStr(std::string jsonStr); void transformToJsonStr(std::string jsonStr);
/** /**
*@brief 向节点添加时段水质值 *@brief 根据本点号获取节点坐标信息
*@param quality 水质值 *@param sn 本点号
*@param junctions, 输出参数,获取的节点信息
*/ */
void addNodeQuality(const std::string& sn, double quality); void getNodeInfoBySn(const std::string& sn, Junctions& junctions);
/** /**
*@brief 向管段添加时段水质值 *@brief 根据本点号获取管段坐标信息
*@param quality 水质值 *@param sn 本点号
*@param junctions, 输出参数,获取的管段信息
*/ */
void addPipeQuality(const std::string& sn, double quality); void getPipeInfoBySn(const std::string& sn, Pipes& pipes);
private: private:
/** /**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment