Hi, Artem.
Here's a question:
Your code reads the object type.
//--- Read object type this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE);
But it is not checked as in SB
bool CList::Load(const int file_handle) { uint i,num; CObject *node; bool result=true; //--- check if(file_handle==INVALID_HANDLE) return(false); //--- reading and checking begin marker - 0xFFFFFFFFFFFFFFFFFFFFF if(FileReadLong(file_handle)!=-1) return(false); //--- reading and checking type if(FileReadInteger(file_handle,INT_VALUE)!=Type()) return(false); //--- read list size num=FileReadInteger(file_handle,INT_VALUE); //--- sequential creation of list items using the call of method Load() Clear(); for(i=0;i<num;i++) { node=CreateElement(); if(node==NULL) return(false); Add(node); result&=node.Load(file_handle); } //--- successful return(result); }
As we can see, the Type() method simply returns a value
virtual int Type(void) const { return(0x7779); }
What is the necessity of such a check in SB? Is it really enough to read the type and create an element of the corresponding type?
Well, if the type is not read, what next?
Here is the code:
//--- Sequentially recreate the list items by calling the Load() method of node objects this.Clear(); for(uint i=0; i<num; i++) { //--- Read and check the object data start marker - 0xFFFFFFFFFFFFFFFFFFFFFFF if(::FileReadLong(file_handle)!=MARKER_START_DATA) return false; //--- Read object type this.m_element_type=(ENUM_OBJECT_TYPE)::FileReadInteger(file_handle,INT_VALUE); node=this.CreateElement(); if(node==NULL) return false; this.Add(node); //--- Now the file pointer is offset relative to the beginning of the object marker by 12 bytes (8 - marker, 4 - type). //--- Let's put a pointer to the beginning of the object data and load the object properties from the file using the Load() method of the node element. if(!::FileSeek(file_handle,-12,SEEK_CUR)) return false; result &=node.Load(file_handle); } //--- Result return result; } //+------------------------------------------------------------------+ //| Method for creating a list item| //+------------------------------------------------------------------+ CObject *CListObj::CreateElement(void) { //--- Depending on the object type in m_element_type, create a new object switch(this.m_element_type) { case OBJECT_TYPE_TABLE_CELL : return new CTableCell(); case OBJECT_TYPE_TABLE_ROW : return new CTableRow(); case OBJECT_TYPE_TABLE_MODEL : return new CTableModel(); default : return NULL; } }
Read the type of the object into a variable. Then we try to create this object in CreateElement(), and there are cases. What will this method return if the type of the object being created is not read from the file?
Well, if the type is not read, then what next?
Here's the code:
We read the type of the object into a variable. Then we try to create this object in CreateElement(), and there are cases. What will this method return if the type of the object being created is not read from the file?
Artem, that's not what I'm talking about. I'm talking about the fact that there is a type check in SB. Exactly the check.
//--- reading and checking type if(FileReadInteger(file_handle,INT_VALUE)!= Type()) return(false);
Does the type read from the file match the type from the Type()Read and typecheck method. Is that how it translates?
And you just read the type without checking it.
So the question is: What is the deep meaning of this check?
Here's the question: What is the deep meaning of this check?
When a class of SomeObject is loaded from a file by calling the Load() method of this very SomeObject, it checks "did I really read myself from the file?" (that's what you're asking). If not, it means something went wrong, so there's no point in loading any further.
What I have here is a LIST (CListObj) reading an object type from a file. The list does not know what is there (what object) in the file. But it must know this object type to create it in its CreateElement() method. That's why it doesn't check the type of the loaded object from the file. After all, there will be a comparison with Type(), which in this method returns the type of a list, not an object.
When a class of SomeObject is loaded from a file by calling the Load() method of this very SomeObject, it checks "did I really read myself from the file?" (that's what you're asking). If not, it means that something went wrong, so there is no point in loading further.
What I have here is a LIST (CListObj) reading an object type from a file. The list does not know what is there (what object) in the file. But it must know this object type to create it in its CreateElement() method. That's why it doesn't check the type of the loaded object from the file. After all, there will be a comparison with Type(), which in this method returns the type of a list, not an object.
Thanks, I've figured it out, I understand.
I read it, and then I reread it again.
it's anything but a "model" in MVC. Some ListStorage for example
I wonder. Is it possible to get some analogue of python and R dataframes in this way? These are such tables where different columns can contain data of different types (from a limited set of types, but including string).
You can. If we are talking about different columns of one table, then in the described implementation each cell of the table can have a different data type.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Check out the new article: Implementation of a table model in MQL5: Applying the MVC concept.
In programming, application architecture plays a key role in ensuring reliability, scalability, and ease of support. One of the approaches that helps achieve such goals is to leverage architecture pattern called MVC (Model-View-Controller).
MVC concept allows you to divide an application into three interrelated components: model (data and logic management), view (data display), and controller (processing user actions). This separation simplifies code development, testing, and maintenance, making it more structured and flexible.
In this article, we consider how to apply MVC principles to implement a table model in the MQL5 language. Tables are an important tool for storing, processing, and displaying data, and properly organizing them can make working with information much easier. We will create classes for working with tables: table cells, rows, and a table model. To store cells within rows and rows within the table model, we will use the linked list classes from the MQL5 Standard Library that allow efficient storage and use of data.
Author: Artyom Trishkin