привожу полный пример тестового файла — собственно вывод квадратика и текста в нем и под ним на экран с помощью
Graphics
Если используется таймер для перерисовки данного класса, то возникает ситуация с увеличением памяти как в самой среде Sciter, так и в программе (если она использует sciter.dll).
Т.е. память по графике не освобождается.
Как сделать, чтобы память при перерисовке освобождалась — возможно что-то в примере некорректно?
<html>
<head>
<title>Sciter2 </title>
<style>
div.Speedometer {
prototype:SpeedTT;
width:*;
height:*;
border:1px solid black;
}
</style>
<script type="text/tiscript">
// 2 вспомогат функции прорисовки
// квадрат от центра
function w_drawRectCenter(gfx,ax,ay,aWidth,aHeight,aRx=0,aRy=0)
{
var LRx=aRx;
var LRy=aRx;
if ((LRx>0) && (aRy>0)) {LRy=aRy}
//
if (LRx==0) {gfx.rectangle(ax-aWidth*0.5,ay-aHeight*0.5,aWidth,aHeight);}
else {gfx.rectangle(ax-aWidth*0.5,ay-aHeight*0.5,aWidth,aHeight,LRx,LRy)}
}
//
// текст в центре
function w_drawTextCenter(gfx,Ltext,aLength,ax,ay,aSize,aLineWidth)
{
var L_deltaBaseLine=aSize/6; // текст по базовой линии - поэтому сдвигаем его относительно нее вверх
var L_L =Ltext;
L_L.font("Arial",aSize);
L_L.width(aSize*(aLength+1));
L_L.height(aSize);
var (at,at1)=L_L.width();
//gfx.rectangle(-at*0.5,-L_L.height()*0.5,at+aLineWidth*2,L_L.height());
gfx.save();
gfx.drawText(L_L,ax-at*0.5,ay-L_L.height()*0.5-L_deltaBaseLine,7);
gfx.restore();
return true;
}
// класс Behavior
class SpeedTT: Behavior
{
function attached() {
this.paintContent =this.drawSpeed;
}
function drawSpeed(gfx)
{
var (x,y,w,h) = this.box(#rectw);
var scale = w < h? w / 300.0: h / 300.0;
//
gfx.save();
gfx.translate(w*0.5,h*0.5);
var Lmin = w < h? w: h;
gfx.lineWidth(1);
gfx.lineColor(color("red"));
gfx.fillColor(color("yellow"));
w_drawRectCenter(gfx,0,0,200,120,5,5);
var TextStr1="Text+BB+text";
var TextStr2="gggggggggggggggggggggggggggggggggggggggg";
var LL1=new Graphics.Text(TextStr1);
var LL2=new Graphics.Text(TextStr2);
gfx.lineColor(color("navy"));
gfx.fillColor(color("lime"));
var LtextSize=16;
w_drawTextCenter(gfx,LL1,TextStr1.length, 0,0,LtextSize+8,1);
w_drawTextCenter(gfx,LL2,TextStr2.length, 0,150,LtextSize+8,1);
//
gfx.restore();
}
}
////// основное
function self.ready(){
var body = $(body);
$(#spTT).prototype=SpeedTT;
$(#spTT).attached();
body.timer(30,function(){$(#spTT).refresh(); return true;});
}
</script>
</head>
<body>
<h2>Sciter2 test_TT</h2>
<div #spTT class="Speedometer" ></div>
</body>
</html>
Здравствуйте, willi-spb, Вы писали:
Когда ты делаешь это или
var LL1 = new Graphics.Text(TextStr1);
var PP1 = new Graphics.Path();
то ты создаешь объекты в native/GPU memory space. В скриптовом пространстве они занимают всего ничего.
Поэтому GC в общем случае для них не срабатывает (вернее срабатывает, но в отдаленном будещем).
У тебя есть три опции:
1. создавать Graphics.Text один раз и его выводить не пересоздавая. Наиболее эффективный вариант.
2. создавать Graphics.Text и удалять его когда он не нужен: LL1.destroy();
3. время от временм принудительно вызывать garbage collector: gc();
Здравствуйте, c-smile, Вы писали:
CS>Здравствуйте, willi-spb, Вы писали:
CS>Когда ты делаешь это или
CS>CS>var LL1 = new Graphics.Text(TextStr1);
CS>var PP1 = new Graphics.Path();
CS>
CS>то ты создаешь объекты в native/GPU memory space. В скриптовом пространстве они занимают всего ничего.
CS>Поэтому GC в общем случае для них не срабатывает (вернее срабатывает, но в отдаленном будещем).
CS>У тебя есть три опции:
CS>1. создавать Graphics.Text один раз и его выводить не пересоздавая. Наиболее эффективный вариант.
CS>2. создавать Graphics.Text и удалять его когда он не нужен: LL1.destroy();
CS>3. время от временм принудительно вызывать garbage collector: gc();
Добрый день!
1. создавать объект один раз — используется для работы с Image — в данном примере подразумевается,
что текст будет меняться достаточно быстро (например показания прибора в динамике)
2.
добавил в данный пример: LL1.destroy();
LL2.destroy(); перед вызовом gfx.restore();и после — память растет
3.добавил в ready() таймер на очистку мусора body.timer(500,function(){gc(); return true;});
привожу чуть измененный пример — с учетом указанных Вами корректировок — память все равно увеличивается
Версия скайтера 3.0.2.5
<html>
<head>
<title>Sciter2 </title>
<style>
div.Speedometer {
prototype:SpeedTT;
width:*;
height:*;
border:1px solid black;
}
</style>
<script type="text/tiscript">
// 2 вспомогат функции прорисовки
// квадрат от центра
function w_drawRectCenter(gfx,ax,ay,aWidth,aHeight,aRx=0,aRy=0)
{
var LRx=aRx;
var LRy=aRx;
if ((LRx>0) && (aRy>0)) {LRy=aRy}
//
if (LRx==0) {gfx.rectangle(ax-aWidth*0.5,ay-aHeight*0.5,aWidth,aHeight);}
else {gfx.rectangle(ax-aWidth*0.5,ay-aHeight*0.5,aWidth,aHeight,LRx,LRy)}
}
//
// текст в центре
function w_drawTextCenter(gfx,Ltext,aLength,ax,ay,aSize,aLineWidth)
{
var L_deltaBaseLine=aSize/6; // текст по базовой линии - поэтому сдвигаем его относительно нее вверх
var L_L =Ltext;
L_L.font("Arial",aSize);
L_L.width(aSize*(aLength+1));
L_L.height(aSize);
var (at,at1)=L_L.width();
//gfx.rectangle(-at*0.5,-L_L.height()*0.5,at+aLineWidth*2,L_L.height());
gfx.save();
gfx.drawText(L_L,ax-at*0.5,ay-L_L.height()*0.5-L_deltaBaseLine,7);
gfx.restore();
return true;
}
// класс Behavior
class SpeedTT: Behavior
{
function attached() {
this.paintContent =this.drawSpeed;
}
function drawSpeed(gfx)
{
var (x,y,w,h) = this.box(#rectw);
var scale = w < h? w / 300.0: h / 300.0;
//
gfx.save();
gfx.translate(w*0.5,h*0.5);
var Lmin = w < h? w: h;
gfx.lineWidth(1);
gfx.lineColor(color("red"));
gfx.fillColor(color("yellow"));
w_drawRectCenter(gfx,0,0,200,120,5,5);
var ii=rand(50000);
var TextStr1=ii.toString();
var TextStr2="gggggggggggggggggggggggggggggggggggggggg";
var LL1=new Graphics.Text(TextStr1);
var LL2=new Graphics.Text(TextStr2);
gfx.lineColor(color("navy"));
gfx.fillColor(color("lime"));
var LtextSize=16;
w_drawTextCenter(gfx,LL1,TextStr1.length, 0,0,LtextSize+8,1);
w_drawTextCenter(gfx,LL2,TextStr2.length, 0,150,LtextSize+8,1);
//
gfx.restore();
LL1.destroy();
LL2.destroy();
}
}
////// основное
function self.ready(){
var body = $(body);
$(#spTT).prototype=SpeedTT;
$(#spTT).attached();
$(#spTT).timer(30,function(){$(#spTT).refresh(); return true;});
body.timer(200,function(){gc(); return true;});
}
</script>
</head>
<body>
<h2>Sciter2 test_TT</h2>
<div #spTT class="Speedometer" ></div>
</body>
</html>
конечно, таймер 30мсек — это немного утрированное значение, однако в реальной программе мне нужно показать "дребезг" стрелки прибора и отклонение значений в динамике и в этом случае 30мс — это близко к истине.
Может быть, у меня что-то еще некорректно сделано?
Здравствуйте, willi-spb, Вы писали:
WS>Здравствуйте, c-smile, Вы писали:
Это вот
body.timer(200,function(){gc(); return true;});
тогда не надо если явно destroy вызываешь.
А memleak небольшой действительно увидел в new Graphics.Text(), поправил уже. В след. билде будет.