using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace Deltares.RtcTools.Net
{
public class RtcToolsDll : IRtcToolsDll
{
// TODO: remove the directory change once the RtcTools computational core can handle file paths
private string _rtcToolsWorkingDirectory; // this is a relative or absolute path, coming from the omi file of the Sobek 3 RTC-Tools wrapper
private string _oldDirectory;
private static string CheckDirSeparator(string dirPath)
{
string dirSeparator = Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture);
return dirPath.EndsWith(dirSeparator) ? dirPath : dirPath + dirSeparator;
}
private void ChangeDir()
{
if (!String.IsNullOrEmpty(_rtcToolsWorkingDirectory))
{
if (!Environment.CurrentDirectory.Equals(_rtcToolsWorkingDirectory))
{
_oldDirectory = Environment.CurrentDirectory;
Environment.CurrentDirectory = _rtcToolsWorkingDirectory;
}
}
}
private void RestoreDir()
{
if (_oldDirectory != null)
{
Environment.CurrentDirectory = _oldDirectory;
_oldDirectory = null;
}
}
private IntPtr _pRtcToolsClass;
// initialization and time frame
///
/// Empty constructor, use to force loading the DLL
///
public RtcToolsDll()
{
RtcToolsDllNative.LoadRtcToolsDll();
}
public virtual void Initialize(string directoryPathForXmlFiles, string schemaLocation)
{
try
{
_rtcToolsWorkingDirectory = directoryPathForXmlFiles;
ChangeDir();
_pRtcToolsClass = RtcToolsDllNative.CreateOmiAccessableRtcToolsClass(
Marshal.StringToHGlobalAnsi(CheckDirSeparator(schemaLocation)),
Marshal.StringToHGlobalAnsi(CheckDirSeparator(directoryPathForXmlFiles)));
RestoreDir();
}
catch (Exception e)
{
StringBuilder errormessage = new StringBuilder();
errormessage.Append("RtcToolsDll.Initialize: Could not create OmiAccessableRtcToolsClass. " + e);
Console.WriteLine(errormessage);
Debug.WriteLine(errormessage);
throw new Exception(errormessage.ToString());
}
// executing the initialize function of the RtcTools c++ class, the pointer is used.
try {
ChangeDir();
RtcToolsDllNative.OmiInitialize(_pRtcToolsClass);
RestoreDir();
} catch (Exception) {
throw new Exception("RtcToolsDll.Initialize: Error in executing DllImport function OmiInitialize");
}
}
public string GetStartTimeString()
{
try
{
string datetime =
Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiGetStartTimeString(_pRtcToolsClass));
return datetime;
}
catch (Exception)
{
throw new Exception(GetType() + ".RtcToolsDll.GetStartTimeString: Error in executing DllImport function OmiGetStartTimeString");
}
}
public double GetStartTimeAsMJD()
{
var datetime = GetStartTimeString();
var dtStartTime = DateTime.Parse(datetime);
return Gregorian2ModifiedJulian(dtStartTime);
}
public string GetEndTimeString()
{
try
{
string datetime =
Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiGetEndTimeString(_pRtcToolsClass));
return datetime;
}
catch (Exception)
{
throw new Exception(GetType() + ".RtcToolsDll.GetEndTimeString: Error in executing DllImport function OmiGetEndTimeString");
}
}
public double GetEndTimeAsMJD()
{
var datetime = GetEndTimeString();
var dtEndTime = DateTime.Parse(datetime);
return Gregorian2ModifiedJulian(dtEndTime);
}
// exchange items ------------------------------------------------------------
public int GetInputExchangeItemCount()
{
try {
return RtcToolsDllNative.OmiGetInputExchangeItemCount(_pRtcToolsClass);
} catch (Exception) {
throw new Exception(
"RtcToolsDll.GetExchangeItemCount: Error in executing DllImport function OmiGetInputExchangeItemCount");
}
}
public string InputExchangeItemGetQuantityId(int index)
{
try {
string sQuantity =
Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiInputExchangeItemGetQuantityId(_pRtcToolsClass, index));
return sQuantity;
} catch (Exception) {
throw new Exception(
"RtcToolsDll.InputExchangeItemGetQuantityId: Error in executing DllImport function OmiInputExchangeItemGetQuantityId");
}
}
public string InputExchangeItemGetElementId(int index)
{
try {
string sExchangeItem =
Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiInputExchangeItemGetElementId(_pRtcToolsClass, index));
return sExchangeItem;
} catch (Exception) {
throw new Exception(GetType() +
".InputExchangeItemGetElementId: Error in executing DllImport function OmiInputExchangeItemGetLocation(index " +
index + ")");
}
}
public string InputExchangeItemGetUnit(int index) {
try {
string sUnit = Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiInputExchangeItemGetUnit(_pRtcToolsClass, index));
return sUnit;
} catch (Exception) {
throw new Exception(GetType() +
".InputExchangeItemGetUnit: Error in executing DllImport function OmiInputExchangeItemGetUnit(index " + index + ")");
}
}
public int GetOutputExchangeItemCount()
{
try {
return RtcToolsDllNative.OmiGetOutputExchangeItemCount(_pRtcToolsClass);
} catch (Exception) {
throw new Exception(
"RtcToolsDll.GetExchangeItemCount: Error in executing DllImport function OmiGetOutputExchangeItemCount");
}
}
public string OutputExchangeItemGetQuantityId(int index)
{
try {
string sQuantity =
Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiOutputExchangeItemGetQuantityId(_pRtcToolsClass, index));
return sQuantity;
} catch (Exception) {
throw new Exception(
"RtcToolsDll.OutputExchangeItemGetQuantityId: Error in executing DllImport function OmiOutputExchangeItemGetQuantityId");
}
}
public string OutputExchangeItemGetElementId(int index)
{
try {
string sExchangeItem =
Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiOutputExchangeItemGetElementId(_pRtcToolsClass, index));
return sExchangeItem;
} catch (Exception) {
throw new Exception(GetType() +
".OutputExchangeItemGetElementId: Error in executing DllImport function OmiOutputExchangeItemGetLocation(index " +
index + ")");
}
}
public string OutputExchangeItemGetUnit(int index) {
try {
string sUnit =
Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiOutputExchangeItemGetUnit(_pRtcToolsClass, index));
return sUnit;
} catch (Exception) {
throw new Exception(GetType() +
".OutputExchangeItemGetUnit: Error in executing DllImport function OmiOutputExchangeItemGetUnit(index " + index + ")");
}
}
// set values, run, get current time and get values
public void SetValue(int index, double value)
{
try {
RtcToolsDllNative.OmiSetInputValue(_pRtcToolsClass, index, value, 1);
} catch (Exception) {
throw new Exception(GetType() + ".SetValue: Error in executing DllImport function OmiSetInputValue with index " +
index);
}
}
///
///
///
///
///
///
public void SetValue(int index, double value, int timeStepCount)
{
try
{
RtcToolsDllNative.OmiSetInputValue(_pRtcToolsClass, index, value, timeStepCount);
}
catch (Exception)
{
throw new Exception(GetType() + ".SetValue2: Error in executing DllImport function OmiSetInputValue with index " +
index);
}
}
public void PerformTimeStep()
{
try {
RtcToolsDllNative.OmiPerformTimeStep(_pRtcToolsClass, 1);
} catch (Exception e) {
throw new Exception(GetType() + ".PerformTimeStep: Error in executing DllImport function OmiPerformTimeStep:\n" + e.Message);
}
}
public void PerformTimeStep(int timeStepCount)
{
try
{
RtcToolsDllNative.OmiPerformTimeStep(_pRtcToolsClass, timeStepCount);
}
catch (Exception e)
{
throw new Exception(GetType() + ".PerformTimeStep2: Error in executing DllImport function OmiPerformTimeStep:\n" + e.Message);
}
}
public string GetCurrentTimeString()
{
try
{
string datetime =
Marshal.PtrToStringAnsi(RtcToolsDllNative.OmiGetCurrentTimeString(_pRtcToolsClass));
return datetime;
}
catch (Exception)
{
throw new Exception(GetType() + ".RtcToolsDll.GetCurrentTimeString: Error in executing DllImport function OmiGetCurrentTimeString");
}
}
public double GetCurrentTimeAsMJD()
{
var datetime = GetCurrentTimeString();
var dtCurrentTime = DateTime.Parse(datetime);
return Gregorian2ModifiedJulian(dtCurrentTime);
}
public double GetValue(int index)
{
double result;
try {
result = RtcToolsDllNative.OmiGetOutputValue(_pRtcToolsClass, index);
} catch (Exception) {
throw new Exception(GetType() + ".GetValue: Error in executing DllImport function OmiGetOutputValue(index " + index +
")");
}
return result;
}
public void WriteState(string path, string filename)
{
ChangeDir();
RtcToolsDllNative.OmiWriteStateFile(_pRtcToolsClass,
Marshal.StringToHGlobalAnsi(path),
Marshal.StringToHGlobalAnsi(filename));
RestoreDir();
}
public void Finish()
{
ChangeDir();
RtcToolsDllNative.FinishOmiAccessableRtcToolsClass(_pRtcToolsClass);
RestoreDir();
}
public void Dispose()
{
ChangeDir();
RtcToolsDllNative.DisposeOmiAccessableRtcToolsClass(_pRtcToolsClass);
RestoreDir();
_rtcToolsWorkingDirectory = null;
}
///
/// Converts a DateTime object to modified julian date
///
/// DateTime object
/// Modified Julian Date (days since November 17, 1858)
public static double Gregorian2ModifiedJulian(DateTime gregorianDate)
{
long ticks = gregorianDate.Ticks - new DateTime(1858, 11, 17).Ticks;
return (double) ticks/((double) TimeSpan.TicksPerDay);
}
}
}