Making a crowdsourced project on Canvas - page 17

 
o_O:

Create_resource(string Resource_name

Resource_name - how often does it change? how many resources are in memory?

Literally a few. Depends on how many windows are open. Currently I'm working with 1 or 2 windows at a time. Each window has 3-4 bitmap objects. It turns out about 8 resources. (I think it's not enough to slow down...)

Windows update on interface events (now only on clicks, other events disabled). At the same time, it slows down immediately, not after some time. On first click. Additionally I can clearly see a connection between "braking power" and window size. The bigger the window, the slower the response of the image.

And also note that ResourceCreate() arrives not immediately, but after "filling" the local array with an image, i.e. after all the colour calculations and initialization of the image array. I think this is the problem.

 

In order to make a final conclusion, I'll store the image in a static or global array. On interface events, I'll update window immediately by sending to ResourceCreate()- without initializing local array and calling ColorToARGB().

If after this the slowdown effect disappears - then the problem is what I've described. If not - then the problem is in something else.

Tomorrow I will try to check it. After experience I will write about results.

 
run with a profiler.
 
o_O:
run it with a profiler.
I'll do it tomorrow. Ok. )
 

@Peter Konow, why so many English words in the code?

Switch to pure Russian:

#define целочисленное int
#define пока while
#define Печатать Print

void OnStart()
{
        целочисленное номер = 0;
        пока ( номер < 10 )
        {
                Печатать( "номер = ", номер, "!" );
                номер ++;
        }
}
 
Andrey Khatimlianskii:

@Peter Konow, why so many English words in the code?

Switch to pure Russian:

#define целочисленное int
#define пустой void
#define пока while
#define Печатать Print
#define Начнем OnStart


пустой Начнем()
{
        целочисленное номер = 0;
        пока ( номер < 10 )
        {
                Печатать( "номер = ", номер, "!" );
                номер ++;
        }
}

That's even better.

 
Igor Volodin:

#define целочисленное int
#define пустой void
#define пока while
#define Печатать Print
#define Начнем OnStart


пустой Начнем()
{
        целочисленное номер = 0;
        пока ( номер < 10 )
        {
                Печатать( "номер = ", номер, "!" );
                номер ++;
        }
}

That's even better.

next - change #define to '#define'

added: change 'loss' to 'profit'
etc...
 
#define цл    int     // целое
#define цлк   short   // целое короткое
#define цлд   long    // целое длинное
#define плк   float   // плавающее короткое
#define пл    double  // плавающее
#define пст   void    // пустота
#define исток main
#define вывод Print
#define пока  while

пст исток()
{
   цл нмр = 0;             // сокращение от номер.
   пока( нмр < 10 )
   {
      вывод( "номер = ", нмр, "!" );
      нмр ++;

   }

}
Light it properly and it won't be any worse then, in my opinion.
 
Andrey Khatimlianskii:

@Peter Konow, why so many English words in the code?

Switch to pure Russian:

#define целочисленное int
#define пока while
#define Печатать Print

void OnStart()
{
        целочисленное номер = 0;
        пока ( номер < 10 )
        {
                Печатать( "номер = ", номер, "!" );
                номер ++;
        }
}

The suggestion is interesting, I have thought about it. However, there are advantages to combining two languages.

If a program is written in only one language (even if it's the native language), the view is gradually "glossed over" by the monotony of the text.

The alternation of Russian function and variable names, and English identifiers for events, properties, constants and operators, creates the necessary contrast for better reading.

Therefore, I do not switch completely to Russian. However, Russian still dominates, and it helps a lot to navigate in large code.

 

so with the start of the first version of styling work.

The implementation of the schema looks like this

**************

enAttrName - list (extensible) of attributes of the element to be rendered

//------------------------------------------------------------------    enum enAttrName
enum enAttrName // возможные аттрибутов контрола
{
        // шрифт
        anFontName, // имя
        anFontColor, // цвет
        anFontSize, // размер
        anFontWeight, // толщина
        anFontStyle, // стиль
        // фон
        anBackgroundColor, // цвет
        anBackgroundFill, // заливка
        // граница
        anBorderColor, // цвет
        anBorderWidth, // толщина
        // выравнивание
        anAlign,
        anVAlign

по мере необходимости добавлять нужные аттрибуты
};


this attribute is stored in a GAttr class

class GAttr // класс для установки значения в конкретный аттрибут
{
        enAttrName m_attr; // имя аттрибута
        // его значение
        long lval;
        double dval;
        string sval;
};

it somewhat resembles MqlParam, but in contrast to it, it is typestepindependent.

------

then the attributes are grouped into a GAttrReflect list. This list will refer to a certain state of a certain class.

class GAttrReflect
{
        GAttr* m_list[]; // список аттрибутов класса для одного некоторого состояния
};

An important feature of this class is that an attribute cannot be repeated twice in m_list. When you update an attribute, it will be overwritten, or an attribute will be created if it didn't exist.

-------

Each control has several such lists. Each of them refers to a reflection of a control's state. This list of reflections is expandable.

enum enAttrReflect // виды состояний - реакция контрола на своё состояние
{
        arDefault, // состояние по-умолчанию
        arDisable, // недоступен для ввода/неактивный
        arTransp, // должен стать прозрачным
        arSelect, // выбран
        arCheck, // отмечен
        arOver, // мышка над объектом
        arFocus, // получен фокус ввода

по мере необходимости добавлять новые рефлекты
};

Accordingly, one can define attributes for each control (class) for each of its reflexes.

A class - GAttrClass - stores the reflection list of a particular class.

class GAttrClass
{
        string m_class; // для какого класса составлен список
        GAttrReflect reflect[arLast]; // список рефлектов класса
};

-------

And finally, the final class, GThema, handles the entire set of classes that exist and are created by you.

class GThema
{
        GAttrClass* m_list[]; // список классов
};

This class uses the same principle as the attribute list - no two classes with the same name can exist in the list.

Thanks to operator[] overloading we can conveniently specify parameter names.

// задаём в классе GButton - цвет текста при наведении указателя мышки
g_thema["GButton"][arOver][anFontColor]=XRGB(255, 255, 255);

// или можно так
GAttrClass* at = g_thema["GButton"];
GAttrReflect* vl = at[arDefault];
vl[anFontColor] = XRGB(255, 255, 255);

---------

And finally, here is how we get the parameter of interest from the class subject

1. find the required m_class in the list
2. If it is found, look for a reflex in it,
3. if it is found, then we look for the attribute
4. if no attribute is found, then we look for a default reflex and an attribute in it
5. If the attribute is not found in the default reflector, repeat steps 1-4 for the default class name (m_class=NULL), which is common to all elements.

---------
advantage of the approach:
- there is always a default class that you can get along with and not create new ones.
- you can use only the default arDefault instead of creating reflexes
- you don't have to specify any properties in each control. You just need to add the class to GThema and copy
- all of the attributes that were not specified in the class in the reflector are hierarchically obtained from the default reflector or the default class.


Reason: