/////////////////////////////////////////////////////// // // SaherElm IT Center MQL5 Class Library // ---------------------------------------------- // Name: XSCDataCollector // Description: provides all Data Collection requirements ... // // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property library #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://www.saherelm.ir" #property version "1.00" #property strict // // START Definitions ... // // // Supported Data Types ... enum ENUM_X_XDATACOLLECTOR_TYPES { X_DATA_COLLECTOR_SIGNAL, X_DATA_COLLECTOR_SUPRES, X_DATA_COLLECTOR_POSITION, X_DATA_COLLECTOR_DEAL, X_DATA_COLLECTOR_LOG, }; // // END Definitions ... // // // START Import and Inclused requirements ... // // // Includes ... #include "x-saherelm.xtrade.class.mq5" #include "../Libraries/x-saherelm.log.lib.mq5" #include "../Libraries/x-saherelm.models.lib.mq5" #include "../Libraries/x-saherelm.common.lib.mq5" // // END Import and Inclused requirements ... // // // START Overrides ... // // // END Overrides ... // // // a Class Definition ... class XSCDataCollector { // // Public ... public: // // Constructor ... void XSCDataCollector() { // XSCDataCollector("XDataCollector"); // DefineTokens(); } void XSCDataCollector( string path // Base Folder to Store Data ) { // // Set Properties ... // Path(path); // DefineTokens(); } // // Deconstructor ... void ~XSCDataCollector() { } // // START Getter(s)/Setter(s) ... // // // Path ... void Path(string value) { mPath = value; } string Path() { return mPath; } // // END Getter(s)/Setter(s) ... // // // START Provided Functions ... // // // Clean Exists Collected Data ... void CleanStore() { // ENUM_X_XDATACOLLECTOR_TYPES types[]; RetrieveAllAvailableTypes(types); int typesCount = ArraySize(types); if (typesCount <= 0) { return; } // ResetLastError(); // for (int i = 0; i < typesCount; i++) { // ENUM_X_XDATACOLLECTOR_TYPES iType = types[i]; string typeFilePath = GenerateTypeFilePath(iType); // bool isExist = FileIsExist(typeFilePath); if (isExist) { FileDelete(typeFilePath); } } } // // Add Specific Deal ... void CollectDeal(const XDeal &deal) { // string content = ToStringFormat(deal); if (StringLen(content) <= 0) { return; } // string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_DEAL); int mFileHandler = FileOpen( filePath, FILE_READ | FILE_WRITE | FILE_TXT); if (mFileHandler == INVALID_HANDLE) { return; } // FileSeek(mFileHandler, 0, SEEK_END); FileWrite(mFileHandler, content); FileFlush(mFileHandler); FileClose(mFileHandler); } // // Extract Collected Deals ... void ExtreactDeals(XDeal &result[]) { // Clean(result); // string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_DEAL); int mFileHandler = FileOpen( filePath, FILE_READ | FILE_TXT); if (mFileHandler == INVALID_HANDLE) { return; } // while (!FileIsEnding(mFileHandler)) { // string content = FileReadString(mFileHandler); // XDeal deal = ToDeal(content); // Add( deal, result); } // FileClose(mFileHandler); } // // Add Specific Signal ... void CollectSignal(const XSignal &signal) { // string content = ToStringFormat(signal); if (StringLen(content) <= 0) { return; } // string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_SIGNAL); int mFileHandler = FileOpen( filePath, FILE_READ | FILE_WRITE | FILE_TXT); if (mFileHandler == INVALID_HANDLE) { LogMessage("Error: " + (string)GetLastError()); return; } // FileSeek(mFileHandler, 0, SEEK_END); FileWrite(mFileHandler, content); FileFlush(mFileHandler); FileClose(mFileHandler); } // // Extract Collected Signals ... void ExtreactSignals(XSignal &result[]) { // Clean(result); // string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_SIGNAL); int mFileHandler = FileOpen( filePath, FILE_READ | FILE_TXT); if (mFileHandler == INVALID_HANDLE) { return; } // while (!FileIsEnding(mFileHandler)) { // string content = FileReadString(mFileHandler); // XSignal signal = ToSignal(content); // Add( signal, result); } // FileClose(mFileHandler); } // // Add Specific Position ... void CollectPosition(const XPosition &position) { // string content = ToStringFormat(position); if (StringLen(content) <= 0) { return; } // string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_POSITION); int mFileHandler = FileOpen( filePath, FILE_READ | FILE_WRITE | FILE_TXT); if (mFileHandler == INVALID_HANDLE) { return; } // FileSeek(mFileHandler, 0, SEEK_END); FileWrite(mFileHandler, content); FileFlush(mFileHandler); FileClose(mFileHandler); } // // Extract Collected Positions ... void ExtreacPositions(XPosition &result[]) { // Clean(result); // string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_POSITION); int mFileHandler = FileOpen( filePath, FILE_READ | FILE_TXT); if (mFileHandler == INVALID_HANDLE) { return; } // while (!FileIsEnding(mFileHandler)) { // string content = FileReadString(mFileHandler); // XPosition position = ToPosition(content); // Add( position, result); } // FileClose(mFileHandler); } // // SUPPORT and RESISTANCE ... void CollectSupRes(const XOHCLSupRes &item) { } // void ExtractSupReses(XOHCLSupRes &result[]) { } // // Add Specific Log ... void CollectLog(string log) { // if (StringLen(log) <= 0) { return; } // string content = ExtractTypePath(X_DATA_COLLECTOR_LOG) + "[" + log + "]"; // string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_LOG); int mFileHandler = FileOpen( filePath, FILE_READ | FILE_WRITE | FILE_TXT); if (mFileHandler == INVALID_HANDLE) { return; } // FileSeek(mFileHandler, 0, SEEK_END); FileWrite(mFileHandler, content); FileFlush(mFileHandler); FileClose(mFileHandler); } // // Extract Collected Logs ... void ExtractLogs(string &result[]) { // Clean(result); // string filePath = GenerateTypeFilePath(X_DATA_COLLECTOR_LOG); string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_LOG); int mFileHandler = FileOpen( filePath, FILE_READ | FILE_TXT); if (mFileHandler == INVALID_HANDLE) { return; } // while (!FileIsEnding(mFileHandler)) { // string content = FileReadString(mFileHandler); // string log = ExtractString( content, typeIdentifier + "[", "]"); // if (StringLen(log) > 0) { // Add( log, result); } } // FileClose(mFileHandler); } // // TYPE Specific Casting Functions ... // // Signal ... // // Convert to it's String Representation ... string ToStringFormat(const XSignal &signal) { // string result = ""; // DefineTokens(); // result += ExtractTypePath(X_DATA_COLLECTOR_SIGNAL) + "[" + mProvidersToken + "(" + ToString(signal.providers) + ")" + mSymbolToken + "(" + signal.symbol + ")" + mPeriodToken + "(" + ToString(signal.period) + ")" + mTypeToken + "(" + (string)((int)signal.type) + ")" + mModeToken + "(" + (string)((int)signal.mode) + ")" + mEntryToken + "(" + (string)signal.entry + ")" + mRiskAmountToken + "(" + (string)signal.riskAmount + ")" + mTPToken + "(" + (string)signal.tp + ")" + mSLToken + "(" + (string)signal.sl + ")" + mR2rToken + "(" + (string)signal.r2r + ")" + mVolumeToken + "(" + (string)signal.volume + ")" + mSupportResistanceToken + "(" + ToStringFormat(signal.supportAndResistance) + ")" + "]"; // return result; } // // Converts an string to XSignal ... XSignal ToSignal(string content) { // XSignal result; // DefineTokens(); // string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_SIGNAL); // if (StringLen(content) == 0 || StringFind(content, typeIdentifier) < 0) { return result; } // string signalContent = ExtractString( content, typeIdentifier + "[", "]"); if (StringLen(signalContent) == 0) { return result; } // // Providers ... string providersStr = ExtractString( signalContent, mProvidersToken + "(", ")"); if (StringLen(providersStr) > 0) { // string providers[]; StringSplit( providersStr, StringGetCharacter(",", 0), providers); // ArrayCopy( result.providers, providers); } // // Symbol ... string symbolStr = ExtractString( signalContent, mSymbolToken + "(", ")"); if (StringLen(symbolStr) > 0) { result.symbol = symbolStr; } // // Period ... string periodStr = ExtractString( signalContent, mPeriodToken + "(", ")"); if (StringLen(periodStr) > 0) { // ENUM_TIMEFRAMES period = ToPeriod(periodStr); // result.period = period; } // // Type ... string typeStr = ExtractString( signalContent, mTypeToken + "(", ")"); if (StringLen(typeStr) > 0) { // ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)((int)typeStr); // result.type = type; } // // Mode ... string modeStr = ExtractString( signalContent, mModeToken + "(", ")"); if (StringLen(modeStr) > 0) { // ENUM_X_ORDER_MODES mode = (ENUM_X_ORDER_MODES)((int)modeStr); // result.mode = mode; } // // Entry ... string entryStr = ExtractString( signalContent, mEntryToken + "(", ")"); if (StringLen(entryStr) > 0) { // double entry = (double)entryStr; // result.entry = entry; } // // RiskAmount ... string raStr = ExtractString( signalContent, mRiskAmountToken + "(", ")"); if (StringLen(raStr) > 0) { // double ra = (double)raStr; // result.riskAmount = ra; } // // TP ... string tpStr = ExtractString( signalContent, mTPToken + "(", ")"); if (StringLen(tpStr) > 0) { // double tp = (double)tpStr; // result.tp = tp; } // // SL ... string slStr = ExtractString( signalContent, mSLToken + "(", ")"); if (StringLen(slStr) > 0) { // double sl = (double)slStr; // result.sl = sl; } // // R2R ... string r2rStr = ExtractString( signalContent, mR2rToken + "(", ")"); if (StringLen(r2rStr) > 0) { // double r2r = (double)r2rStr; // result.r2r = r2r; } // // Volume ... string volumeStr = ExtractString( signalContent, mVolumeToken + "(", ")"); if (StringLen(volumeStr) > 0) { // double volume = (double)volumeStr; // result.volume = volume; } // // SupportResistance ... string supportResistanceStr = ExtractString( signalContent, mSupportResistanceToken + "(", ")"); if (StringLen(supportResistanceStr) > 0) { // XOHCLSupRes supRes = ToSupRes(supportResistanceStr); // result.supportAndResistance = supRes; } // return result; } // // Deal ... // // Convert to it's String Representation ... string ToStringFormat(const XDeal &deal) { // string result = ""; // DefineTokens(); // result += ExtractTypePath(X_DATA_COLLECTOR_DEAL) + "[" + mMagicToken + "(" + (string)deal.magic + ")" + mPositionIDToken + "(" + (string)deal.positionId + ")" + mTicketToken + "(" + (string)deal.ticket + ")" + mSymbolToken + "(" + (string)deal.symbol + ")" + mOrderToken + "(" + (string)deal.order + ")" + mTimeToken + "(" + (string)deal.time + ")" + mPriceToken + "(" + (string)deal.price + ")" + mProfitToken + "(" + (string)deal.profit + ")" + mSwapToken + "(" + (string)deal.swap + ")" + mCommissionToken + "(" + (string)deal.commission + ")" + mVolumeToken + "(" + (string)deal.volume + ")" + mCommentToken + "(" + (string)deal.comment + ")" + mTypeToken + "(" + (string)((int)deal.type) + ")" + mEntryToken + "(" + (string)((int)deal.entry) + ")" + mReasonToken + "(" + (string)((int)deal.reason) + ")" + "]"; // return result; } // // Converts an string to XDeal ... XDeal ToDeal(string content) { // XDeal result; // DefineTokens(); // string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_DEAL); // if (StringLen(content) == 0 || StringFind(content, typeIdentifier) < 0) { return result; } // string dealContent = ExtractString( content, typeIdentifier + "[", "]"); if (StringLen(dealContent) == 0) { return result; } // // Magic ... string magicStr = ExtractString( dealContent, mMagicToken + "(", ")"); if (StringLen(magicStr) > 0) { // ulong magic = (ulong)magicStr; // result.magic = magic; } // // PositionID ... string posIDStr = ExtractString( dealContent, mPositionIDToken + "(", ")"); if (StringLen(posIDStr) > 0) { // ulong posID = (ulong)posIDStr; // result.positionId = posID; } // // Ticket ... string ticketStr = ExtractString( dealContent, mTicketToken + "(", ")"); if (StringLen(ticketStr) > 0) { // ulong ticket = (ulong)ticketStr; // result.ticket = ticket; } // // Symbol ... string symbolStr = ExtractString( dealContent, mSymbolToken + "(", ")"); if (StringLen(symbolStr) > 0) { result.symbol = symbolStr; } // // Order ... string orderStr = ExtractString( dealContent, mOrderToken + "(", ")"); if (StringLen(orderStr) > 0) { // ulong order = (ulong)orderStr; // result.order = order; } // // Time ... string timeStr = ExtractString( dealContent, mTimeToken + "(", ")"); if (StringLen(timeStr) > 0) { // datetime time = StringToTime(timeStr); // result.time = time; } // // Price ... string priceStr = ExtractString( dealContent, mPriceToken + "(", ")"); if (StringLen(priceStr) > 0) { // double price = (double)priceStr; // result.price = price; } // // Profit ... string profitStr = ExtractString( dealContent, mProfitToken + "(", ")"); if (StringLen(profitStr) > 0) { // double profit = (double)profitStr; // result.profit = profit; } // // Swap ... string swapStr = ExtractString( dealContent, mSwapToken + "(", ")"); if (StringLen(swapStr) > 0) { // double swap = (double)swapStr; // result.swap = swap; } // // Commission ... string commissionStr = ExtractString( dealContent, mCommissionToken + "(", ")"); if (StringLen(commissionStr) > 0) { // double commission = (double)commissionStr; // result.commission = commission; } // // Volume ... string volumeStr = ExtractString( dealContent, mVolumeToken + "(", ")"); if (StringLen(volumeStr) > 0) { // double volume = (double)volumeStr; // result.volume = volume; } // // Comment ... string commentStr = ExtractString( dealContent, mCommentToken + "(", ")"); if (StringLen(commentStr) > 0) { result.comment = commentStr; } // // Type ... string typeStr = ExtractString( dealContent, mTypeToken + "(", ")"); if (StringLen(typeStr) > 0) { // ENUM_DEAL_TYPE type = (ENUM_DEAL_TYPE)((int)typeStr); // result.type = type; } // // Entry ... string entryStr = ExtractString( dealContent, mEntryToken + "(", ")"); if (StringLen(entryStr) > 0) { // ENUM_DEAL_ENTRY entry = (ENUM_DEAL_ENTRY)((int)entryStr); // result.entry = entry; } // // Reason ... string reasonStr = ExtractString( dealContent, mReasonToken + "(", ")"); if (StringLen(reasonStr) > 0) { // ENUM_DEAL_REASON reason = (ENUM_DEAL_REASON)((int)reasonStr); // result.reason = reason; } // return result; } // // SUPPORT and RESISTANCES ... string ToStringFormat(const XOHCLSupRes &item) { // string result = ""; // DefineTokens(); // result += ExtractTypePath(X_DATA_COLLECTOR_SUPRES) + "[" + mResToken + "(" + ToString(item.res) + ")" + mSupToken + "(" + ToString(item.sup) + ")" + "]"; // return result; } // XOHCLSupRes ToSupRes(string content) { // XOHCLSupRes result; // DefineTokens(); // string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_SUPRES); // if (StringLen(content) == 0 || StringFind(content, typeIdentifier) < 0) { return result; } // string mainContent = ExtractString( content, typeIdentifier + "[", "]"); if (StringLen(mainContent) == 0) { return result; } // // Res ... string resStr = ExtractString( mainContent, mResToken + "(", ")"); if (StringLen(resStr) > 0) { // double res[]; string parts[]; StringSplit( resStr, StringGetCharacter(",", 0), parts); // int partsCount = ArraySize(parts); if (partsCount > 0) { // for (int i = 0; i < partsCount; i++) { // string iPart = parts[i]; // Add( double(iPart), result.res); } } } // // Sup ... string supStr = ExtractString( mainContent, mSupToken + "(", ")"); if (StringLen(supStr) > 0) { // double sup[]; string parts[]; StringSplit( supStr, StringGetCharacter(",", 0), parts); // int partsCount = ArraySize(parts); if (partsCount > 0) { // for (int i = 0; i < partsCount; i++) { // string iPart = parts[i]; // Add( double(iPart), result.sup); } } } // return result; } // // Position ... // // Convert to it's String Representation ... string ToStringFormat(const XPosition &position) { // string result = ""; // DefineTokens(); // result += ExtractTypePath(X_DATA_COLLECTOR_POSITION) + "[" + mMagicToken + "(" + (string)position.magic + ")" + mTicketToken + "(" + (string)position.ticket + ")" + mSymbolToken + "(" + (string)position.symbol + ")" + mPeriodToken + "(" + (string)((int)position.period) + ")" + mTypeToken + "(" + (string)((int)position.type) + ")" + mTPToken + "(" + (string)position.tp + ")" + mSLToken + "(" + (string)position.sl + ")" + mProfitToken + "(" + (string)position.profit + ")" + mEntryToken + "(" + (string)position.entry + ")" + mPriceToken + "(" + (string)position.price + ")" + mSwapToken + "(" + (string)position.swap + ")" + mCommissionToken + "(" + (string)position.commission + ")" + mVolumeToken + "(" + (string)position.volume + ")" + mOpenAtToken + "(" + (string)position.openAt + ")" + mCommentToken + "(" + (string)position.comment + ")" + "]"; // return result; } // // Converts an string to XPosition ... XPosition ToPosition(string content) { // XPosition result; // DefineTokens(); // string typeIdentifier = ExtractTypePath(X_DATA_COLLECTOR_POSITION); // if (StringLen(content) == 0 || StringFind(content, typeIdentifier) < 0) { return result; } // string positionContent = ExtractString( content, typeIdentifier + "[", "]"); if (StringLen(positionContent) == 0) { return result; } // // Magic ... string magicStr = ExtractString( positionContent, mMagicToken + "(", ")"); if (StringLen(magicStr) > 0) { // ulong magic = (ulong)magicStr; // result.magic = magic; } // // Ticket ... string ticketStr = ExtractString( positionContent, mTicketToken + "(", ")"); if (StringLen(ticketStr) > 0) { // ulong ticket = (ulong)ticketStr; // result.ticket = ticket; } // // Symbol ... string symbolStr = ExtractString( positionContent, mSymbolToken + "(", ")"); if (StringLen(symbolStr) > 0) { result.symbol = symbolStr; } // // Period ... string periodStr = ExtractString( positionContent, mPeriodToken + "(", ")"); if (StringLen(periodStr) > 0) { // ENUM_TIMEFRAMES period = ToPeriod(periodStr); // result.period = period; } // // Type ... string typeStr = ExtractString( positionContent, mTypeToken + "(", ")"); if (StringLen(typeStr) > 0) { // ENUM_POSITION_TYPE type = (ENUM_POSITION_TYPE)((int)typeStr); // result.type = type; } // // TP ... string tpStr = ExtractString( positionContent, mTPToken + "(", ")"); if (StringLen(tpStr) > 0) { // double tp = (double)tpStr; // result.tp = tp; } // // SL ... string slStr = ExtractString( positionContent, mSLToken + "(", ")"); if (StringLen(slStr) > 0) { // double sl = (double)slStr; // result.sl = sl; } // // Profit ... string profitStr = ExtractString( positionContent, mProfitToken + "(", ")"); if (StringLen(profitStr) > 0) { // double profit = (double)profitStr; // result.profit = profit; } // // Entry ... string entryStr = ExtractString( positionContent, mEntryToken + "(", ")"); if (StringLen(entryStr) > 0) { // double entry = (double)entryStr; // result.entry = entry; } // // Price ... string priceStr = ExtractString( positionContent, mPriceToken + "(", ")"); if (StringLen(priceStr) > 0) { // double price = (double)priceStr; // result.price = price; } // // Swap ... string swapStr = ExtractString( positionContent, mSwapToken + "(", ")"); if (StringLen(swapStr) > 0) { // double swap = (double)swapStr; // result.swap = swap; } // // Commission ... string commissionStr = ExtractString( positionContent, mCommissionToken + "(", ")"); if (StringLen(commissionStr) > 0) { // double commission = (double)commissionStr; // result.commission = commission; } // // Volume ... string volumeStr = ExtractString( positionContent, mVolumeToken + "(", ")"); if (StringLen(volumeStr) > 0) { // double volume = (double)volumeStr; // result.volume = volume; } // // OpenAt ... string openAtStr = ExtractString( positionContent, mOpenAtToken + "(", ")"); if (StringLen(openAtStr) > 0) { // datetime openAt = StringToTime(openAtStr); // result.openAt = openAt; } // // Comment ... string commentStr = ExtractString( positionContent, mCommentToken + "(", ")"); if (StringLen(commentStr) > 0) { result.comment = commentStr; } // return result; } // // END Provided Functions ... // // // Protected ... protected: // // Destintion Folder Path ... string mPath; // void DefineTokens() { // // Define Required Variables ... // // Define Some Modifier Tokens for Type Castings ... mProvidersToken = "PVS"; mSymbolToken = "SBL"; mPeriodToken = "PR"; mTypeToken = "TYP"; mModeToken = "MD"; mEntryToken = "EN"; mRiskAmountToken = "RA"; mTPToken = "TP"; mSLToken = "SL"; mR2rToken = "RR"; mVolumeToken = "VL"; // mMagicToken = "MGK"; mTicketToken = "TK"; mProfitToken = "PFT"; mPriceToken = "CPR"; mSwapToken = "SWP"; mCommissionToken = "CMS"; mOpenAtToken = "ODT"; mCommentToken = "CMN"; // mPositionIDToken = "PID"; mOrderToken = "ORD"; mTimeToken = "TDT"; mReasonToken = "RSN"; // mResToken = "RES"; mSupToken = "SUP"; mSupportResistanceToken = "SUPRES"; } // // Private ... private: // // Generate Full File Path ... string GetFilePath(string fileName) { // string result = ""; // result = // Path() + "\\" + fileName // ; // return result; } // // Extract Each Type Specific File Name ... string ExtractTypePath(ENUM_X_XDATACOLLECTOR_TYPES type) { // string typeStr = EnumToString(type); // string typeParts[]; StringSplit( typeStr, StringGetCharacter("_", 0), typeParts); // string result = typeParts[ArraySize(typeParts) - 1]; // return result; } // string GenerateTypeFilePath(ENUM_X_XDATACOLLECTOR_TYPES type) { // string name = ExtractTypePath(type) + ".txt"; // string result = GetFilePath(name); // return result; } // // Retrieve all available data types ... void RetrieveAllAvailableTypes(ENUM_X_XDATACOLLECTOR_TYPES &result[]) { // ArrayFree(result); ArrayResize(result, 0); // Add( X_DATA_COLLECTOR_LOG, result); // Add( X_DATA_COLLECTOR_DEAL, result); // Add( X_DATA_COLLECTOR_SIGNAL, result); // Add( X_DATA_COLLECTOR_SUPRES, result); // Add( X_DATA_COLLECTOR_POSITION, result); } // // Define Some Modifier Tokens for Type Castings ... string mProvidersToken; string mSymbolToken; string mPeriodToken; string mTypeToken; string mModeToken; string mEntryToken; string mRiskAmountToken; string mTPToken; string mSLToken; string mR2rToken; string mVolumeToken; // string mMagicToken; string mTicketToken; string mProfitToken; string mPriceToken; string mSwapToken; string mCommissionToken; string mOpenAtToken; string mCommentToken; // string mPositionIDToken; string mOrderToken; string mTimeToken; string mReasonToken; // string mResToken; string mSupToken; string mSupportResistanceToken; }; // // START Usefull Functions ... // void Add(ENUM_X_XDATACOLLECTOR_TYPES type, ENUM_X_XDATACOLLECTOR_TYPES &types[]) { // ArrayResize( types, ArraySize(types) + 1); // types[ArraySize(types) - 1] = type; } // // END Usefull Functions ... //