(31.03.2019 21:07)wessonsm Wrote: Разбирал воговские скрипты и наткнулся на пару моментов, требующих уточнения.
1. Видимо функцию !?FU8165 просто при создании скрипта забыли удалить. Ничего страшного, но всё же лучше закоментировать этот вызов.
3. Да это ошибка.
П.1 и 3 я исправил в сборке и они будут доступны в след.релизе.
Теперь что касается п.2:
Да, предложенный алгоритм тобой будет быстрее. Но по настоящему быстрее будет исполозование SN:G вместо DO и т.п.
Всё из за особенностей запуска функций типа !?FU. Если коротко, то цикл SN:G в десятки, если даже не в сотни раз быстрее цикла DO, потому что в нем не происходит каждый раз вызов функции !?FU.
Для справки: один вызов функций FU вызывает уеву тучу циклов на С++ для сохранения и обнуления, а потом восстановления локальных переменных (см. исходник Вог)
Code:
int ERM_Function(char Cmd,int Num,_ToDo_*sp,Mes *Mp)
{
int i,j,v;
int _lYVarInsideFunction;
int OldX[16];
int OldY[100];
float OldF[100];
char OldString[10][512];
if(WoG==0) RETURN(0) // поддерживается только в WoG
// VarNum *vnp=(VarNum *)&sp->Pointer;
switch(Cmd){
case 'P': // вызвать функцию
for(i=0;i<16;i++) { OldX[i]=ERMVarX[i]; }
for(i=0;i<100;i++){ OldY[i]=ERMVarY[i]; }
for(i=0;i<100;i++){ OldF[i]=ERMVarF[i]; }
for(i=0;i<10;i++) for(j=0;j<512;j++) { OldString[i][j]=ERMLString[i][j]; }
for(i=0;i<Num;i++){ ERMVarX[i]=Mp->n[i]; }
for(i=0;i<100;i++){ ERMVarY[i]=0; }
for(i=0;i<100;i++){ ERMVarF[i]=0; }
v=GetVarVal(&sp->Par[0]);
_lYVarInsideFunction=YVarInsideFunction;
YVarInsideFunction=1;
FUCall(v);
YVarInsideFunction=_lYVarInsideFunction;
// 3.58 return values
// first restore y vars (and others)
for(i=0;i<100;i++){ ERMVarY[i]=OldY[i]; }
for(i=0;i<100;i++){ ERMVarF[i]=OldF[i]; }
for(i=0;i<10;i++) for(j=0;j<512;j++) { ERMLString[i][j]=OldString[i][j]; }
// now if used ?y, it will be stored correctly
for(i=0;i<Num;i++){
if(Mp->VarI[i].Check!=1) continue; // не ?
Apply(&ERMVarX[i],4,Mp,(char)i);
}
for(i=0;i<16;i++) { ERMVarX[i]=OldX[i]; }
break;