правки в Help
This commit is contained in:
Mikhalkovich Stanislav 2019-01-26 11:43:27 +03:00
parent 8887bfaa8e
commit 71bf09add9
20 changed files with 377 additions and 292 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "4";
public const string Build = "2";
public const string Revision = "1941";
public const string Revision = "1950";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=2
%REVISION%=1941
%MINOR%=4
%REVISION%=1950
%COREVERSION%=2
%MAJOR%=3

View file

@ -194,6 +194,7 @@ namespace PascalABCCompiler.NETGenerator {
public class GenericFldInfo : FldInfo
{
private Type _field_type;
public FieldInfo prev_fi; // передаю чтобы на третьем этапе в NegGenerator.cs (примерно 1586) можно было сконструировать правильный тип. Костыль для #1632
public override Type field_type
{
@ -203,10 +204,11 @@ namespace PascalABCCompiler.NETGenerator {
}
}
public GenericFldInfo(FieldInfo fi, Type field_type)
public GenericFldInfo(FieldInfo fi, Type field_type, FieldInfo prev_fi)
: base(fi)
{
_field_type = field_type;
this.prev_fi = prev_fi;
}
}
@ -698,14 +700,14 @@ namespace PascalABCCompiler.NETGenerator {
return fi;
}
public FldInfo AddGenericField(ICommonClassFieldNode f, FieldInfo fb, Type field_type)
public FldInfo AddGenericField(ICommonClassFieldNode f, FieldInfo fb, Type field_type, FieldInfo prev_fi)
{
FldInfo fi = new GenericFldInfo(fb, field_type);
FldInfo fi = new GenericFldInfo(fb, field_type, prev_fi); // prev_fi - чтобы сконструировать на последнем этапе fi
#if DEBUG
/*if (f.name == "XYZW")
{
var y = f.GetHashCode();
}*/
} */
#endif
defs[f] = fi;
return fi;
@ -719,15 +721,15 @@ namespace PascalABCCompiler.NETGenerator {
/*if (f.name == "XYZW")
{
var y = f.GetHashCode();
}*/
/*if (r == null && f.name == "XYZW")
}
if (r == null && f.name == "XYZW")
{
foreach (var k in defs.Keys)
{
if ((k is ICommonClassFieldNode) && (k as ICommonClassFieldNode).name == "XYZW")
return (FldInfo)defs[k];
}
}*/
} */
#endif
return r;
}
@ -919,7 +921,8 @@ namespace PascalABCCompiler.NETGenerator {
{
if (type.type_special_kind == type_special_kind.text_file)
ti.is_text_file = true;
if (!ti.is_set && !ti.is_typed_file && !ti.is_text_file) return ti;
if (!ti.is_set && !ti.is_typed_file && !ti.is_text_file)
return ti;
if (ti.clone_meth == null && !ti.is_typed_file && !ti.is_text_file)
{
if (type is ICommonTypeNode)

View file

@ -1498,7 +1498,7 @@ namespace PascalABCCompiler.NETGenerator
Type ftype = GetTypeOfGenericInstanceField(t, icfn.compiled_field);
FieldInfo fi = TypeBuilder.GetField(t, icfn.compiled_field);
helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype);
helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype, null);
continue;
}
}
@ -1562,14 +1562,44 @@ namespace PascalABCCompiler.NETGenerator
{
FieldInfo finfo = fldinfo.fi;
Type ftype = GetTypeOfGenericInstanceField(t, finfo);
FieldInfo fi = TypeBuilder.GetField(t, finfo);
helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype);
FieldInfo fi = TypeBuilder.GetField(t, finfo); // возвращает fi: FieldOnTypeBuilderInstantiation
helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype, finfo); // передаю также старое finfo чтобы на следующей итерации вызовом TypeBuilder.GetField(t, finfo) сконструировать правильное fi
}
else
{
FieldInfo finfo = fldinfo.fi;
FieldInfo fi = finfo;
helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, (fldinfo as GenericFldInfo).field_type);
/* Вот этот код не выполняется ни в одном тесте и в примере
type
Base<T> = class
XYZW: T;
end;
Derived<T1> = class(Base<T1>)
end;
begin
var a := new Derived<integer>;
a.XYZW := 2;
end.
срабатывает неправильно !!!
Исправил, введя доп. поле в GenericFldInfo, которое хранит FieldBuilder и позволяет конструировать fi на следующей итерации
*/
FieldInfo finfo = (fldinfo as GenericFldInfo).prev_fi;
FieldInfo fi = TypeBuilder.GetField(t, finfo);
helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, (fldinfo as GenericFldInfo).field_type, finfo);
//FieldInfo finfo = fldinfo.fi;
//FieldInfo fi = finfo;
//helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, (fldinfo as GenericFldInfo).field_type, finfo);
//#if DEBUG
/*{
var f = File.AppendText("d:\\aa.txt");
f.WriteLine(DateTime.Now);
f.WriteLine($"{value.used_members[dn] as ICommonClassFieldNode} {fi} {(fldinfo as GenericFldInfo).field_type}");
f.Close();
}*/
//#endif
}
continue;
}

View file

@ -64,6 +64,7 @@
<DebugType>Full</DebugType>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<DefineConstants>DEBUG</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>..\bin\</OutputPath>

Binary file not shown.

View file

@ -32,7 +32,7 @@
именем, имеющим точечную нотацию. В этом случае в качестве имен полей берутся
последние имена в точечной нотации. Например:</p>
<blockquote><code><strong>var</strong> d := new DateTime(2015,5,15);<br><strong>
var</strong> p := new class(d.Day, d.Month, d.Year);<br>Println(p.Day,
var</strong> p := new <strong>class</strong>(d.Day, d.Month, d.Year);<br>Println(p.Day,
p.Month, p.Year);<br>Println(p);</code></blockquote>
</body>

View file

@ -27,7 +27,7 @@
<blockquote><code><b>type</b> Person = <strong>auto class</strong><br>&nbsp;
name: string;<br>&nbsp; age: integer;<br><strong>end</strong>;<br><strong>
var</strong> p := new Person('Èâàíîâ',20); // êîíñòðóêòîð àâòîêëàññà
генерируется автоматически<br>writeln(p); // вызывается сгенерированный
генерируется автоматически<br>Writeln(p); // вызывается сгенерированный
àâòîìàòè÷åñêè ìåòîä ToString</code></blockquote>
<p>Çäåñü â îòëè÷èå îò äåéñòâèÿ writeln ïî óìîë÷àíèþ âûâîäÿòñÿ çíà÷åíèÿ íå òîëüêî
ïóáëè÷íûõ, à âñåõ ïîëåé.</p>

View file

@ -45,7 +45,7 @@ property</span></b><span lang="en-us"> Coun: integer <b>read</b> cnt;</span><br>
<p><code><span lang="en-us"><b>begin</b><br>
&nbsp; <b>var</b> p: Person := new Person('</span>Èâàíîâ<span lang="en-us">',20);<br>
&nbsp; <b>var</b> p1: Person := new Person('</span>Ïåòðîâ<span lang="en-us">',18);<br>
&nbsp; writeln(Person.Count); // </span>îáðàùåíèå ê êëàññîâîìó ìåòîäó
&nbsp; Writeln(Person.Count); // </span>îáðàùåíèå ê êëàññîâîìó ìåòîäó
<span lang="en-us">Count<br>
<b>end</b>.</span></code></p>
<p> îòëè÷èå îò ñòàòè÷åñêèõ ïîëåé è ìåòîäîâ, îáû÷íûå ïîëÿ è ìåòîäû íàçûâàþòñÿ

View file

@ -39,9 +39,9 @@ HashSet&lt;T&gt;
Self <strong>do</strong><br>&nbsp;&nbsp;&nbsp; action(x);<br><strong>end</strong>;</code></blockquote>
<p>Ñ ïîìîùüþ ìåòîäîâ ðàñøèðåíèÿ ìîæíî <a href="operoverloading.html">ïåðåãðóæàòü
îïåðàöèè</a>:</p>
<blockquote><code><strong>function operator</strong>+=&lt;T&gt;(a: List&lt;T&gt;; x: T):
<blockquote><code><strong>procedure operator</strong>+=&lt;T&gt;(a: List&lt;T&gt;; x: T):
List&lt;T&gt;; <strong>extensionmethod</strong>;<br><strong>begin</strong><br>&nbsp;
a.Add(x);<br>&nbsp; Result := a;<br><strong>end</strong>;</code></blockquote>
a.Add(x);<br><strong>end</strong>;</code></blockquote>
<p> ýòîì ñëó÷àå ïåðâûé ïàðàìåòð íå îáÿçàí èìåòü èìÿ Self.</p>
<p>Äëÿ ìåòîäîâ ðàñøèðåíèÿ èìååòñÿ ðÿä îãðàíè÷åíèé:</p>
<ul>

View file

@ -3,6 +3,7 @@
<head>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="class">
<param name="Keyword" value="sealed">
</object>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Классы и объекты: обзор</title>
@ -57,7 +58,7 @@
Print;<br><b>&nbsp;&nbsp;&nbsp; property</b> Name: string read fName;<br><b>&nbsp;&nbsp;&nbsp;
property</b> Age: integer read fAge;<b><br>&nbsp; end</b>;<br><strong><br>
procedure</strong> Person.Print;<br><strong>begin</strong><br>&nbsp;
writelnFormat('Имя: {0} Возраст: {1}', Name, Age);<br><strong>end</strong>;</code></p>
Writeln($'Имя: {Name} Возраст: {Age}');<br><strong>end</strong>;</code></p>
</blockquote>
<p>После слова <code><b>class</b></code>
в скобках может быть указано имя класса-предка (см. <A href="inheritance.html">
@ -90,10 +91,10 @@
<p><code>Print(p.Name,p.Age);<br>p.Print;</code></p>
</blockquote>
<h2>Вывод переменной типа класс</h2>
<p>По умолчанию процедура <code>write</code> для переменной типа класс выводит
<p>По умолчанию процедура <code>Write</code> для переменной типа класс выводит
содержимое её публичных полей и свойств в круглых скобках через запятую:</p>
<blockquote>
<p><code>write(p); // Иванов 20</code></p>
<p><code>Write(p); // Иванов 20</code></p>
</blockquote>
<p>Чтобы изменить это поведение, в классе следует
<A href="../Classes/virtual.html">переопределить</A> виртуальный метод
@ -109,13 +110,12 @@
string; <b>override</b>;<br>
<b>&nbsp;&nbsp;&nbsp; begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result :=
string.Format('Имя: {0}&nbsp; Возраст: {1}',
Name, Age); <br>
$'Имя: {Name} Возраст: {Age}'; <br>
<b>&nbsp;&nbsp;&nbsp; end</b>;<br>
<b>&nbsp; end</b>;<br>
&nbsp; ...<br>
<b>var</b> p: Person := new Person('Иванов',20);<br>
writeln(p); // Имя: Иванов&nbsp; Возраст: 20</code></p>
Writeln(p); // Имя: Иванов&nbsp; Возраст: 20</code></p>
</blockquote>
<h2>Присваивание и передача в качестве параметров подпрограмм</h2>
<p>Переменная типа класс является ссылкой и хранит ссылку на объект, создаваемый

View file

@ -28,7 +28,7 @@
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp;&nbsp;&nbsp; <b>procedure</b> Print;<br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln('<27><><EFBFBD>: ',name,'&nbsp; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ',age);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writeln('<27><><EFBFBD>: ',name,'&nbsp; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ',age);<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;<br>
&nbsp; <br>&nbsp; Student =<b> class</b>(Person)<br>
@ -45,7 +45,7 @@ integer);<br>
&nbsp;&nbsp;&nbsp; <b>procedure</b> Print;<br>
&nbsp;&nbsp;&nbsp; <b>begin</b><br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b>inherited</b> Print;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; writeln('<27><><EFBFBD><EFBFBD>: ',course,'&nbsp; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ',group);<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Writeln('<27><><EFBFBD><EFBFBD>: ',course,'&nbsp; <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: ',group);<br>
&nbsp;&nbsp;&nbsp; <b>end</b>;<br>
&nbsp; <b>end</b>;</code></p>
<p>Çäåñü ìåòîä <code>Print</code> ïðîèçâîäíîãî êëàññà <code>Student</code>

View file

@ -22,15 +22,15 @@
ñïåöèàëüíûì èìåíåì <b><code>operator</code></b> <i>
ÇíàêÎïåðàöèè</i>. Ïåðåãðóçêà ñïåöèàëüíûõ îïåðàöèé <code>+=</code>, <code>
-=</code>, <code>*=</code>, <code>/=</code>
îñóùåñòâëÿåòñÿ ñ ïîìîùüþ ñòàòè÷åñêîé (êëàññîâîé) ïðîöåäóðû-ìåòîäà, ïåðâûé ïàðàìåòð
îñóùåñòâëÿåòñÿ ñ ïîìîùüþ ñòàòè÷åñêîé ïðîöåäóðû-ìåòîäà, ïåðâûé ïàðàìåòð
êîòîðîé ïåðåäàåòñÿ ïî ññûëêå.</p>
<p>Íàïðèìåð:</p>
<blockquote>
<p><code><b>type</b> <br>&nbsp; Complex = <b>record</b><br>&nbsp;&nbsp;&nbsp; re,im: real;<br>&nbsp;&nbsp;&nbsp;
<b><span lang="en-us">class </span>function</b> <b>operator</b>+(a,b: Complex): Complex; <br>&nbsp;&nbsp;&nbsp;
<strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator</b>+(a,b: Complex): Complex; <br>&nbsp;&nbsp;&nbsp;
<b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result.re := a.re + b.re;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result.im := a.im + b.im;
<br>&nbsp;&nbsp;&nbsp; <b>end</b>; <br>&nbsp;&nbsp;&nbsp;
<b><span lang="en-us">class </span>function</b> <b>operator</b>=(a,b: Complex): boolean; <br>&nbsp;&nbsp;&nbsp; <b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result := (a.re = b.re)
<strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator</b>=(a,b: Complex): boolean; <br>&nbsp;&nbsp;&nbsp; <b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result := (a.re = b.re)
<b>and</b> (a.im = b.im);<br>&nbsp;&nbsp;&nbsp; <b>end</b>; <br>&nbsp; <b>end</b>;</code></p>
</blockquote>
<p>Äëÿ ïåðåãðóçêè îïåðàöèé äåéñòâóþò ñëåäóþùèå ïðàâèëà:</p>
@ -55,8 +55,6 @@
îïåðàöèÿ, âòîðîé - ïåðåäàåòñÿ ïî çíà÷åíèþ è ñîâìåñòèì ïî ïðèñâàèâàíèþ ñ
ïåðâûì. Ïåðåãðóçêà îñòàëüíûõ îïåðàöèé îñóùåñòâëÿåòñÿ ñ ïîìîùüþ ñòàòè÷åñêèõ
ôóíêöèé-ìåòîäîâ. </li>
<li>Òèïû èíòåðôåéñîâ íå ìîãóò áûòü òèïàìè ïàðàìåòðîâ.
Ïðè÷èíà: òèïû ïàðàìåòðîâ äîëæíû âû÷èñëÿòüñÿ íà ýòàïå êîìïèëÿöèè.</li>
<li>Îïåðàöèè ïðèâåäåíèÿ òèïà <span lang="ru">çàäàþòñÿ ñòàòè÷åñêèìè
ôóíêöèÿìè, ó êîòîðûõ </span>âìåñòî èìåíè <span lang="ru">èñïîëüçóåòñÿ </span>
<code><b>operator</b></code> <code><b>implicit</b></code> <span lang="ru">
@ -68,19 +66,18 @@
<blockquote>
<p><code><b>type</b> <br>&nbsp; Complex = <b>record</b><br>&nbsp;&nbsp;&nbsp;
...<br>&nbsp;&nbsp;&nbsp;
<b><span lang="en-us">class </span>function</b> <b>operator implicit</b>(d: real): Complex;<br>&nbsp;&nbsp;&nbsp;
<strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator implicit</b>(d: real): Complex;<br>&nbsp;&nbsp;&nbsp;
<b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result.re := d;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result.im := 0;<br>&nbsp;&nbsp;&nbsp;
<b>end</b>; <br>&nbsp; &nbsp;
<b><span lang="en-us">class </span>function</b> <b>operator explicit</b>(c: Complex): string;<br>&nbsp;&nbsp;&nbsp;
<strong>static</strong><b><span lang="en-us"> </span>function</b> <b>operator explicit</b>(c: Complex): string;<br>&nbsp;&nbsp;&nbsp;
<b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Result := Format('({0},{1})',c.re,c.im);<br>&nbsp;&nbsp;&nbsp;
<b>end</b>;<br>&nbsp;&nbsp;&nbsp;
<b><span lang="en-us">class </span>procedure</b> <b>operator</b>+=(<b>var</b> c: Complex;
<strong>static</strong><b><span lang="en-us"> </span>procedure</b> <b>operator</b>+=(<b>var</b> c: Complex;
value: Complex);<br>&nbsp;&nbsp;&nbsp; <b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
c.re += value.re;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c.im += value.im;<br>&nbsp;&nbsp;&nbsp;
<b>end</b>;<br>&nbsp;&nbsp;&nbsp;
<span lang="en-us">
<b>class </b> </span><b>function</b> <b>operator</b>+(c,c1: Complex):
<strong>static</strong><span lang="en-us"><b> </b> </span><b>function</b> <b>operator</b>+(c,c1: Complex):
Complex;<br>&nbsp;&nbsp;&nbsp; <b>begin&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </b><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
Result.re := c.re + c1.re;
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@ -88,12 +85,12 @@ value: Complex);<br>&nbsp;&nbsp;&nbsp; <b>begin</b><br>&nbsp;&nbsp;&nbsp;&nbsp;&
<br>&nbsp;&nbsp;&nbsp;
<b>end</b>;<br>&nbsp; <b>end</b>;</code></p>
</blockquote>
<p>Ìîæíî ïåðåãðóæàòü îïåðàöèè ñ ïîìîùüþ ìåòîäîâ ðàñøèðåíèÿ - â ýòîì ñëó÷àå ïðè
<p>Ìîæíî ïåðåãðóæàòü îïåðàöèè ñ ïîìîùüþ <a href="extensionmethods.html">ìåòîäîâ ðàñøèðåíèÿ</a> - â ýòîì ñëó÷àå ïðè
îïèñàíèè ïîäïðîãðàììû íå ñëåäóåò ïèñàòü ñëîâî class. Íàïðèìåð, òàê â ñèñòåìíîì ìîäóëå
ðåàëèçîâàíî äîáàâëåíèå ÷èñëà ê ñòðîêå:</p>
<blockquote>
<p><code><strong>function</strong> string.operator+(str: string; n:
integer): string;<br><strong>begin</strong><br>&nbsp; result := str +
<p><code><strong>function</strong> operator+(str: string; n:
integer): string; <strong>extensionmethod</strong>;<br><strong>begin</strong><br>&nbsp; result := str +
n.ToString;<br><strong>end</strong>;</code></p>
</blockquote>
</body>

View file

@ -1,20 +1,26 @@
<HTML><HEAD><object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="Keyword" value="Событие"></object>
<param name="Keyword" value="OnKeyDown">
<param name="Keyword" value="OnKeyPress">
<param name="Keyword" value="OnKeyUp">
<param name="Keyword" value="OnMouseDown">
<param name="Keyword" value="OnMouseMove">
<param name="Keyword" value="OnMouseUp">
<param name="Keyword" value="OnResize"></object>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251"><link rel="StyleSheet" href="../../../default.css">
</HEAD><body><H1>Ñîáûòèÿ ìîäóëÿ GraphWPF</H1>
<table border=0 cellpadding=5><tr><td><code>/// Событие нажатия на кнопку мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</td></tr>
<tr><td><code>/// Событие отжатия кнопки мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если отжата левая кнопка мыши, и 2, если отжата правая кнопка мыши;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ouseDown: procedure(x, y: real; mousebutton: integer);</td></tr>
<tr><td><code>/// Событие перемещения мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 0, если кнопка мыши не нажата, 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ouseUp: procedure(x, y: real; mousebutton: integer);</td></tr>
<tr><td><code>/// Событие нажатия клавиши;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ouseMove: procedure(x, y: real; mousebutton: integer);</td></tr>
<tr><td><code>/// Событие отжатия клавиши;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eyDown: procedure(k: Key);</td></tr>
<tr><td><code>/// Событие нажатия символьной клавиши;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eyUp: procedure(k: Key);</td></tr>
<tr><td><code>/// Событие изменения размера графического окна;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;eyPress: procedure(ch: char);</td></tr>
<table border=0 cellpadding=5><tr><td><code>OnMouseDown: <b>procedure</b>(x, y: real; mousebutton: integer);</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ñîáûòèå íàæàòèÿ íà êíîïêó ìûøè. (x,y) - êîîðäèíàòû êóðñîðà ìûøè â ìîìåíò íàñòóïëåíèÿ ñîáûòèÿ, mousebutton = 1, åñëè íàæàòà ëåâàÿ êíîïêà ìûøè, è 2, åñëè íàæàòà ïðàâàÿ êíîïêà ìûøè</td></tr>
<tr><td><code>OnMouseUp: <b>procedure</b>(x, y: real; mousebutton: integer);</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ñîáûòèå îòæàòèÿ êíîïêè ìûøè. (x,y) - êîîðäèíàòû êóðñîðà ìûøè â ìîìåíò íàñòóïëåíèÿ ñîáûòèÿ, mousebutton = 1, åñëè îòæàòà ëåâàÿ êíîïêà ìûøè, è 2, åñëè îòæàòà ïðàâàÿ êíîïêà ìûøè</td></tr>
<tr><td><code>OnMouseMove: <b>procedure</b>(x, y: real; mousebutton: integer);</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ñîáûòèå ïåðåìåùåíèÿ ìûøè. (x,y) - êîîðäèíàòû êóðñîðà ìûøè â ìîìåíò íàñòóïëåíèÿ ñîáûòèÿ, mousebutton = 0, åñëè êíîïêà ìûøè íå íàæàòà, 1, åñëè íàæàòà ëåâàÿ êíîïêà ìûøè, è 2, åñëè íàæàòà ïðàâàÿ êíîïêà ìûøè</td></tr>
<tr><td><code>OnKeyDown: <b>procedure</b>(k: Key);</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ñîáûòèå íàæàòèÿ êëàâèøè</td></tr>
<tr><td><code>OnKeyUp: <b>procedure</b>(k: Key);</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ñîáûòèå îòæàòèÿ êëàâèøè</td></tr>
<tr><td><code>OnKeyPress: <b>procedure</b>(ch: char);</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ñîáûòèå íàæàòèÿ ñèìâîëüíîé êëàâèøè</td></tr>
<tr><td><code>OnResize: <b>procedure</b>;</code>
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ñîáûòèå èçìåíåíèÿ ðàçìåðà ãðàôè÷åñêîãî îêíà</td></tr>
</table>
</body></HTML>

View file

@ -1 +1 @@
!define VERSION '3.4.2.1941'
!define VERSION '3.4.2.1950'

View file

@ -10,9 +10,9 @@
// https://github.com/SunSerega/PascalABC.Net-BlockFileOfT/blob/master/LICENSE.md
(************************************************************************************)
///Модуль содержащий тип BlockFileOf<T>
///Этот тип - альтернатива стандартному file of T
///Основное преимущество - скорость работы
///Модуль, содержащий тип BlockFileOf<T>
///Тип-альтернатива стандартному file of T
///Главное преимущество - скорость работы
unit BlockFileOfT;
interface
@ -24,42 +24,36 @@ type
///--
BlockFileBase = abstract class
protected fi:FileInfo;
protected _offset:int64;
protected str:FileStream;
protected bw:BinaryWriter;
protected br:BinaryReader;
protected fi: FileInfo;
protected _offset: int64;
protected str: FileStream;
protected bw: BinaryWriter;
protected br: BinaryReader;
protected linked := new List<BlockFileBase>;
protected procedure Link(f:BlockFileBase);
protected procedure Link(f: BlockFileBase);
protected procedure UnLink;
private class function MessageBox(wnd: System.IntPtr; message, caption: string; flags: cardinal):integer;
external 'User32.dll';
private static function MessageBox(wnd: System.IntPtr; message, caption: string; flags: cardinal): integer; external 'User32.dll';
end;
///Тип, записывающий данные в файл по принципу схожему с "file of <T>"
///Но в отличии от "file of <T>" - данный тип сохраняет всю запись одним блоком,
///так, как она записа в памяти.
///Это даёт значительное преимущество по скорости, но ограничевает,
///типы, которые могут быть использованы в виде полей <T>
///Тип, записывающий данные в файл по схожему с "file of <T>" принципу
///Но, в отличии от типизированных файлов, данный тип сохраняет всю запись одним блоком так, как она записа в памяти.
///Это даёт значительное преимущество по скорости, но ограничивает типы, которые могут быть использованы в качестве полей типа <T>
///
///Ожидается, что в видет шаблонного параметра <T> будет передана запись,
///не содержащая динамичных полей.
///Иначе целостность данных будет терятся
///Это значит, что поля записи T и всех вложенных записей - НЕ могут быть:
/// -Указатели
/// -Ссылочных типов (то есть классами)
/// -Особых типов, которые .Net считает "опасными". Как char или System.DateTime
///Но эти ограничения можно обойти, про это в справке
BlockFileOf<T>=class(BlockFileBase)
///Это значит, что поля записи T и всех вложенных записей не могут быть:
/// - Указателями
/// - Ссылочными типами (классами / динамическими массивами)
/// - Особоопасными в .NET типами. Например, char и System.DateTime
///Однако, эти ограничения можно обойти, об этом в справке
BlockFileOf<T> = class(BlockFileBase)
private class sz: integer;
private static sz: integer;
private class procedure TestForRefT(tt: System.Type);
private static procedure TestForRefT(tt: System.Type);
begin
if tt.IsClass then
begin
@ -82,7 +76,7 @@ type
TestForRefT(fi.FieldType);
end;
private class constructor :=
private static constructor :=
try
TestForRefT(typeof(T));
@ -116,193 +110,227 @@ type
end;
end;
private function GetName:string;
private function GetFullName:string;
private function GetName: string;
private function GetFullName: string;
private function GetExists:boolean;
private function GetExists: boolean;
private function GetFileSize:int64 := (GetByteFileSize - _offset) div sz;
private procedure SetFileSize(size:int64) := SetByteFileSize(_offset + size*sz);
private function GetFileSize: int64 := (GetByteFileSize - _offset) div sz;
private procedure SetFileSize(size: int64) := SetByteFileSize(_offset + size*sz);
private function GetByteFileSize:int64;
private procedure SetByteFileSize(size:int64);
private function GetByteFileSize: int64;
private procedure SetByteFileSize(size: int64);
private function GetPos:int64 := (GetPosByte-_offset) div sz;
private procedure SetPos(pos:int64) := SetPosByte(_offset + pos*sz);
private function GetPosByte:int64;
private procedure SetPosByte(pos:int64);
private function GetPos: int64 := (GetPosByte-_offset) div sz;
private procedure SetPos(pos: int64) := SetPosByte(_offset + pos*sz);
private function GetPosByte: int64;
private procedure SetPosByte(pos: int64);
private function InternalReadLazy(c:integer; start_pos:int64):sequence of T;
private function InternalReadLazy(c: integer; start_pos: int64):sequence of T;
///Инициализирует переменную файла, не привязывая её к файлу на диске
public constructor := exit;
///Инициализирует переменную файла, привязывая её к файлу fname
public constructor(fname:string) :=
///Инициализирует переменную файла, привязывая её к файлу с именем fname
public constructor(fname: string) :=
Assign(fname);
///Инициализирует переменную файла, привязывая её к файлу fname
///А так же устанавливая значение смещени от начала в байтах на offset
public constructor(fname:string; offset:int64) :=
///Инициализирует переменную файла, привязывая её к файлу с именем fname
///Устанавливает значение смещения от начала в байтах на offset
public constructor(fname: string; offset: int64) :=
Assign(fname, offset);
///- constructor BlockFileOf<>(f:BlockFileOf<>);
///Инициализирует новую переменную, создавая связку данной переменной
///После вызова этого конструктора - переданная и созданная переменная будут
///использовать общий файловый поток, но записывать разные типы данных (у них может быть разный T)
///Это значит, что переменная которую передали в конструктор должно уже иметь открытый файловый поток
///Инициализирует новую переменную, создавая связку с заданной переменной
///После вызова этого конструктора переданная и созданная переменные будут использовать общий файловый поток, но записывать разные типы данных (у них может быть разный T)
///Это значит, что переменная, которую передали в конструктор, уже должна иметь открытый файловый поток
///Метод Close разрывает эту связь.
public constructor(f: BlockFileBase) :=
Link(f);
///Возвращает или задаёт размер блока из одного элемента в байтах
///Задавать это свойство не рекомендуется
public property TSize: integer read integer(sz) write sz := value;
///Размер блока из одного элемента типа T, в байтах
///Хоть это свойство и можно перезаписывать, но это не рекомендуется
///Если перезаписать на число, большее чем было - в файл будет сохранять лишние нули
///А если на меньшее - получите неопределённое поведение (скорее всего вылет, но далеко не сразу)
public property TSize:integer read integer(sz) write sz := value;
///Возвращает или задаёт смещение от начала файла до начала элементов в байтах
public property Offset: int64 read _offset write _offset;
///Смещение от начала файла до начала элементов (в байтах)
public property Offset:int64 read _offset write _offset;
///Количество сохранённых в файл элементов типа T
///Чтоб установить длину файла - надо открыть файл. Но прочитать длину можно не открывая
public property Size:int64 read GetFileSize write SetFileSize;
///Полный размер файла, в байтах
///Чтоб установить длину файла - надо открыть файл. Но прочитать длину можно не открывая
public property ByteSize:int64 read GetByteFileSize write SetByteFileSize;
///Имя файла (только имя самого файла, без имени папки)
public property Name:string read GetName;
///Полное имя файла (вместе с именами всех под-папок, вплодь до корня диска)
public property FullName:string read GetFullName;
///Существует ли файл
public property Exists:boolean read GetExists;
///Возвращает или задаёт количество сохранённых в файл элементов
///Задавать можно только после открытия файла
public property Size: int64 read GetFileSize write SetFileSize;
///Номер текущего элемета типа T в файле (нумеруя с 0)
public property Pos:int64 read GetPos write SetPos;
///Номер текущего байта от начала файла (нумеруя с 0)
public property PosByte:int64 read GetPosByte write SetPosByte;
///Привязана ли переменная к файлу
public property Assigned:boolean read fi <> nil;
///Открыт ли файл
public property Opened:boolean read str <> nil;
///Достигнут ли конец файла
public property EOF:boolean read ByteSize-PosByte < sz;
///Основной поток открытого файла (или nil если файл не открыт)
///Внимание! Любое действие которое изменит этот поток - приведёт к неожиданным последствиям, используйте его только если знаете что делаете
public property BaseStream:FileStream read str;
///Переменная, которая записывает данные в основной поток (или nil если файл не открыт)
///Внимание! Любое действие которое изменит основной поток файла - приведёт к неожиданным последствиям, используйте его только если знаете что делаете
public property BinWriter:BinaryWriter read bw;
///Переменная, которая читает данные из основного потока (или nil если файл не открыт)
///Внимание! Любое действие которое изменит основной поток файла - приведёт к неожиданным последствиям, используйте его только если знаете что делаете
public property BinReader:BinaryReader read br;
///Переменная, показывающая данные о файле (или nil, если переменная не привязана к файлу)
public property FileInfo:System.IO.FileInfo read fi;
///Возвращает или задаёт размер файла в байтах
///Задавать можно только после открытия файла
public property ByteSize: int64 read GetByteFileSize write SetByteFileSize;
///Возвращает неполное имя файла
public property Name: string read GetName;
///Возвращает полное имя файла
public property FullName: string read GetFullName;
///Привязывает данную переменную к файлу {fname}
///Привязывать можно и к не существующим файлам, при откритии определёнными способами (как Rewrite) новый файл будет создан
public procedure Assign(fname:string);
///Привязывает данную переменную к файлу {fname}
///А так же устанавливая значение смещени от начала в байтах на offset
///Привязывать можно и к не существующим файлам, при откритии определёнными способами (как Rewrite) новый файл будет создан
public procedure Assign(fname:string; offset:int64);
///Убирает свять переменной и файла, если связь есть
///Определяет, существует ли файл
public property Exists: boolean read GetExists;
///Возвращает номер текущего элемета в файле (нумеруя с 0)
public property Pos: int64 read GetPos write SetPos;
///Возвращает номер текущего байта от начала файла (нумеруя с 0)
public property PosByte: int64 read GetPosByte write SetPosByte;
///Определяет, привязана ли переменная к файлу
public property Assigned: boolean read fi <> nil;
///Определяет, открыт ли файл
public property Opened: boolean read str <> nil;
///Определяет, достигнут ли конец файла
public property EOF: boolean read ByteSize-PosByte < sz;
///Возвращает поток текущего файла (или nil если файл не открыт)
///Внимание! Любое действие, связанное с изменением данного потока файла приведёт к неожиданным последствиям, используйте его только если знаете, что вы делаете
public property BaseStream: FileStream read str;
///Возвращает BinaryWriter текущего файла (или nil если файл не открыт)
///Внимание! Любое действие, связанное с изменением основного потока файла приведёт к неожиданным последствиям, используйте его только если знаете, что вы делаете
public property BinWriter: BinaryWriter read bw;
///Возвращает BinaryReader текущего файла (или nil если файл не открыт)
///Внимание! Любое действие, связанное с изменением основного потока файла приведёт к неожиданным последствиям, используйте его только если знаете, что вы делаете
public property BinReader: BinaryReader read br;
///Возвращает FileInfo текущего файла (или nil, если переменная не привязана к файлу)
public property FileInfo: System.IO.FileInfo read fi;
///Привязывает текущий экземпляр BlockFileOf<T> к файлу с именем fname
///Привязывать можно и к несуществующим файлам, при открытии на запись будет создан новый файл
public procedure Assign(fname: string);
///Привязывает данную переменную к файлу с именем fname
///Устанавливает смещение от начала файла до начала элементов в байтах на offset
///Привязывать можно и к несуществующим файлам, при открытии чем то вроде Rewrite будет создан новый файл
public procedure Assign(fname: string; offset: int64);
///Удаляет связь переменной с файлом, если связь есть
public procedure UnAssign;
///Открывает файл, способом описанным в переменной mode
///Чтоб получить переменную этого типа - пишите System.IO.FileMode.<способ_открытия_файла>
public procedure Open(mode:FileMode);
///Открывает файл способом mode
public procedure Open(mode: FileMode);
///Удаляет связаный файл, если он существует
public procedure Delete;
///Переименовывает файл
///Если указать другое расположение - файл будет перемещён
public procedure Rename(NewName:string);
///При указании иного расположения файл будет перемещён
public procedure Rename(NewName: string);
///Создает (или обнуляет) привязаный файл
///Создает файл
public procedure Rewrite;
///Привязывает данную переменную к файлу {fname} и создает (или обнуляет) этот файл
public procedure Rewrite(fname:string);
///Привязывает данную переменную к файлу {fname} и создает (или обнуляет) этот файл
///А так же устанавливая значение смещени от начала в байтах на offset
public procedure Rewrite(fname:string; offset:int64);
///Открывает файл (ожидается, что он уже существует) и устанавливает позицию на начало файла
///Привязывает данную переменную к файлу с именем fname и создает (или обнуляет) его
public procedure Rewrite(fname: string);
///Привязывает данную переменную к файлу с именем fname и создает (или обнуляет) его
///Устанавливает смещение от начала файла до начала элементов в байтах на offset
public procedure Rewrite(fname: string; offset: int64);
///Открывает файл на чтение
public procedure Reset;
///Привязывает данную переменную к файлу {fname}, открывает этот файл (ожидается, что файл уже существует) и устанавливает позицию на начало файла
public procedure Reset(fname:string);
///Привязывает данную переменную к файлу {fname}, открывает этот файл (ожидается, что файл уже существует) и устанавливает позицию на начало файла
///А так же устанавливая значение смещени от начала в байтах на offset
public procedure Reset(fname:string; offset:int64);
///Открывает файл (ожидается, что он уже существует) и устанавливает позицию в конце файла
///Привязывает данную переменную к файлу с именем fname и открывает его на чтение
public procedure Reset(fname: string);
///Привязывает данную переменную к файлу с именем fname и открывает его на чтение
///Устанавливает смещение от начала файла до начала элементов в байтах на offset
public procedure Reset(fname: string; offset: int64);
///Открывает файл и устанавливает позицию на конец файла
public procedure Append;
///Привязывает данную переменную к файлу {fname}, открывает этот файл (ожидается, что файл уже существует) и устанавливает позицию в конце файла
public procedure Append(fname:string);
///Привязывает данную переменную к файлу {fname}, открывает этот файл (ожидается, что файл уже существует) и устанавливает позицию в конце файла
///А так же устанавливая значение смещени от начала в байтах на offset
public procedure Append(fname:string; offset:int64);
///Переставляет позицию в файле на элемент #pos (нумеруя с 0)
public procedure Seek(pos:int64) := self.Pos := pos;
///Переставляет файловый курсор на байт #pos (нумеруя с 0) от начала файла
public procedure SeekByte(pos:int64) := self.PosByte := pos;
///Привязывает данную переменную к файлу с именем fname и открывает его, устанавливая позицию на конец файла
public procedure Append(fname: string);
///Привязывает данную переменную к файлу с именем fname и открывает его, устанавливая позицию на конец файла
///Устанавливает смещение от начала файла до начала элементов в байтах на offset
public procedure Append(fname: string; offset: int64);
///Ставит позицию в файле на элемент pos (нумеруя с 0)
public procedure Seek(pos: int64) := self.Pos := pos;
///Ставит файловый курсор на байт pos (нумеруя с 0) от начала файла
public procedure SeekByte(pos: int64) := self.PosByte := pos;
///Записывает все изменения в файл и отчищает внутренние буферы
///До вызова Flush или Close - все изменения и кеш хранятся в оперативной памяти
///Поэтому, если вы записываете/читаете много (сотни мегабайт) - лучше вызывать Flush время от времени
///До вызова Flush или Close все изменения и кеш хранятся в оперативной памяти
///Поэтому, если вы проводите операции с большими объёмами памяти, лучше вызывать Flush время от времени
public procedure Flush;
///Сохраняет и закрывает файл, если он открыт
public procedure Close;
///Записывает один элемент одним блоком в файл
///И переставляет файловый курсор на 1 элемет вперёд
///Переставляет файловый курсор на 1 элемет вперёд
public procedure Write(o: T);
///Записывает массив элементов одним блоком в файл
///И переставляет файловый курсор на o.Length элеметов вперёд
public procedure Write(params o:array of T);
///Переставляет файловый курсор на количество элементов, равному количеству элементов в переданном массиве
public procedure Write(params o: array of T);
///Записывает последовательность элементов, у которой можно узнать длину, одним блоком в файл
///И переставляет файловый курсор на o.Count элеметов вперёд
public procedure Write(o:ICollection<T>);
///Записывает последовательность элементов, у которой нельзя узнать длину, по 1 элементу типа T в файл
///И переставляет файловый курсор на o.Count элеметов вперёд
public procedure Write(o:sequence of T);
///Записывает count элементов массива, начиная с элемента #from, одним блоком в файл
///И переставляет файловый курсор на сount элеметов вперёд
public procedure Write(o:array of T; from,count:integer);
///Записывает count элементов последовательности, у которой можно узнать длину, начиная с элемента #from, одним блоком в файл
///И переставляет файловый курсор на сount элеметов вперёд
public procedure Write(o:ICollection<T>; from,count:integer);
///Записывает count элементов последовательности, у которой нельзя узнать длину, начиная с элемента #from, одним блоком в файл
///И после каждого элемента переставляет файловый курсор на 1 элемет вперёд
public procedure Write(o:sequence of T; from,count:integer);
///Переставляет файловый курсор на количество элементов, равному количеству элементов в переданной коллекции
public procedure Write(o: ICollection<T>);
///Записывает последовательность элементов, у которой нельзя узнать длину, по 1 элементу в файл
///Переставляет файловый курсор на количество элементов, равному количеству элементов в переданной последовательности
public procedure Write(o: sequence of T);
///Записывает count элементов массива, начиная с элемента from, одним блоком в файл
///Переставляет файловый курсор на сount элеметов вперёд
public procedure Write(o: array of T; from, count: integer);
///Записывает count элементов последовательности, у которой можно узнать длину, начиная с элемента from, одним блоком в файл
///Переставляет файловый курсор на сount элеметов вперёд
public procedure Write(o: ICollection<T>; from, count: integer);
///Записывает count элементов последовательности, у которой нельзя узнать длину, начиная с элемента from, одним блоком в файл
///После каждого элемента переставляет файловый курсор на 1 элемет вперёд
public procedure Write(o: sequence of T; from, count: integer);
///Читает один элемент из файла одним блоком
///И переставляет файловый курсор на 1 элемет вперёд
public function Read:T;
///Читает массив из count одним блоком
///Переставляет файловый курсор на 1 элемет вперёд
public function Read: T;
///Читает массив из count элементов из файла одним блоком
///Переставляет файловый курсор на count элеметов вперёд
public function Read(count: integer): array of T;
///Читает массив из count элементов одним блоком, начиная с элемента start_elm
///И переставляет файловый курсор на count элеметов вперёд
public function Read(count:integer):array of T;
///Читает массив из count элементов одним блоком, начиная с элемента #start_elm
///И переставляет файловый курсор на count элеметов вперёд
public function Read(start_elm, count:integer):array of T;
public function Read(start_elm, count: integer): array of T;
///Возвращает ленивую последовательность из count элементов
///После завершения чтения - курсор окажется на эдлементе #(start_elm+count)
///Каждый раз читать будет начиная с элемента, на котором сейчас стоит файловый курсор
public function ReadLazy(count:integer):sequence of T := InternalReadLazy(count, PosByte);
///Возвращает ленивую последовательность из count элементов, начиная с элемента #start_elm
///После прочтения i элементов последовательности - позиция в файле будет передвигаться на элемент #(start_elm+i)
///Каждый раз читать будет начиная с элемента #start_elm
public function ReadLazy(start_elm, count:integer):sequence of T := InternalReadLazy(count, _offset + start_elm*sz);
///После завершения чтения курсор окажется на последнем элементе возвращаемой последовательности
///Каждый раз чтение будет происходить, начиная с элемента, на котором в данный момент стоит файловый курсор
public function ReadLazy(count: integer): sequence of T := InternalReadLazy(count, PosByte);
///Возвращает ленивую последовательность из count элементов, начиная с элемента start_elm
///После завершения чтения курсор окажется на последнем элементе возвращаемой последовательности
///Каждый раз чтение будет происходить, начиная с элемента start_elm
public function ReadLazy(start_elm, count: integer): sequence of T := InternalReadLazy(count, _offset + start_elm*sz);
///Возвращает ленивую последовательность из блоков-массивов с элементами типа T
///Каждый блок хранит столько элементов - чтоб не превышать объём в 4096 байт (4КБ)
///После прочтения каждого блока - файловый корсор будет переставлен на его конец
public function ToSeqBlocks:sequence of array of T := ToSeqBlocks(4096);
///Каждый блок хранит такое количество байт, которое не превышает 4 КБ
///После прочтения каждого блока файловый корсор будет переставлен на его конец
public function ToSeqBlocks: sequence of array of T := ToSeqBlocks(4096);
///Возвращает ленивую последовательность из блоков-массивов с элементами типа T
///Каждый блок хранит столько элементов - чтоб не превышать объём в последовательность байт
///После прочтения каждого блока - файловый корсор будет переставлен на его конец
public function ToSeqBlocks(blocks_size:integer):sequence of array of T;
///Возвращает ленивую последовательность из всех элементов хранящихся в файле
///После прочтения i элементов последовательности - позиция в файле будет передвигаться на элемент #i
public function ToSeq:sequence of T;
///Каждый блок хранит такое количество байт, которое не превышает blocks_size
///После чтения каждого блока файловый корсор будет переставлен на его конец
public function ToSeqBlocks(blocks_size: integer): sequence of array of T;
///Возвращает ленивую последовательность из всех элементов, хранящихся в файле
///После прохода по элементам последовательности позиция в файле будет передвигаться на последний использованный элемент
public function ToSeq: sequence of T;
protected procedure Finalize; override;
begin
@ -316,19 +344,19 @@ type
type
FileNotAssignedException = class(Exception)
constructor :=
inherited Create($'Данная переменная не была привязана к файлу{10}Используйте метод Assign');
inherited Create($'Данная переменная не привязана к файлу{10}Используйте метод Assign');
end;
FileNotOpenedException = class(Exception)
constructor(fname:string) :=
inherited Create($'Файл {fname} ещё не открыт, откройте его с помощью Open, Reset, Append или Rewrite');
inherited Create($'Файл {fname} не открыт, откройте его с помощью Open, Reset, Append или Rewrite');
end;
FileNotClosedException = class(Exception)
constructor(fname:string) :=
inherited Create($'Файл {fname} ещё открыт, закройте его методом Close перед тем как продолжать');
inherited Create($'Файл {fname} открыт, закройте его методом Close перед тем как продолжать');
end;
CannotReadAfterEOF = class(Exception)
constructor :=
inherited Create($'Нельзя читать за пределами файла. Можно только записывать');
inherited Create($'Нельзя читать за пределами файла');
end;
{$endregion Exception's}
@ -337,7 +365,7 @@ implementation
{$region Linking}
procedure BlockFileBase.Link(f:BlockFileBase);
procedure BlockFileBase.Link(f: BlockFileBase);
begin
if f.str = nil then raise new FileNotOpenedException($'{f.fi.FullName}, чью переменную передали в конструктор BlockFileOf<T>,');
@ -369,14 +397,14 @@ end;
{$region property implementation}
function BlockFileOf<T>.GetName:string;
function BlockFileOf<T>.GetName: string;
begin
if fi = nil then raise new FileNotAssignedException;
fi.Refresh;
Result := fi.Name;
end;
function BlockFileOf<T>.GetFullName:string;
function BlockFileOf<T>.GetFullName: string;
begin
if fi = nil then raise new FileNotAssignedException;
//fi.Refresh;//А тут не надо
@ -385,7 +413,7 @@ end;
function BlockFileOf<T>.GetByteFileSize:int64;
function BlockFileOf<T>.GetByteFileSize: int64;
begin
if fi = nil then raise new FileNotAssignedException;
if str <> nil then
@ -397,7 +425,7 @@ begin
Result := fi.Length;
end;
procedure BlockFileOf<T>.SetByteFileSize(size:int64);
procedure BlockFileOf<T>.SetByteFileSize(size: int64);
begin
if fi = nil then raise new FileNotAssignedException;
if str = nil then raise new FileNotOpenedException(fi.FullName);
@ -406,14 +434,14 @@ end;
function BlockFileOf<T>.GetPosByte:int64;
function BlockFileOf<T>.GetPosByte: int64;
begin
if fi = nil then raise new FileNotAssignedException;
if str = nil then raise new FileNotOpenedException(fi.FullName);
Result := str.Position;
end;
procedure BlockFileOf<T>.SetPosByte(pos:int64);
procedure BlockFileOf<T>.SetPosByte(pos: int64);
begin
if fi = nil then raise new FileNotAssignedException;
if str = nil then raise new FileNotOpenedException(fi.FullName);
@ -426,13 +454,13 @@ end;
{$region Basic}
procedure BlockFileOf<T>.Assign(fname:string);
procedure BlockFileOf<T>.Assign(fname: string);
begin
if str <> nil then raise new FileNotClosedException(fi.FullName);
fi := new System.IO.FileInfo(fname);
end;
procedure BlockFileOf<T>.Assign(fname:string; offset:int64);
procedure BlockFileOf<T>.Assign(fname: string; offset: int64);
begin
Assign(fname);
_offset := offset;
@ -444,7 +472,7 @@ begin
fi := nil;
end;
procedure BlockFileOf<T>.Open(mode:FileMode);
procedure BlockFileOf<T>.Open(mode: FileMode);
begin
if fi = nil then raise new FileNotAssignedException;
if str <> nil then raise new FileNotClosedException(fi.FullName);
@ -459,14 +487,14 @@ begin
fi.Delete;
end;
function BlockFileOf<T>.GetExists:boolean;
function BlockFileOf<T>.GetExists: boolean;
begin
if fi = nil then raise new FileNotAssignedException;
fi.Refresh;
Result := fi.Exists;
end;
procedure BlockFileOf<T>.Rename(NewName:string);
procedure BlockFileOf<T>.Rename(NewName: string);
begin
if fi = nil then raise new FileNotAssignedException;
if str <> nil then raise new FileNotClosedException(fi.FullName);
@ -480,13 +508,13 @@ end;
procedure BlockFileOf<T>.Rewrite :=
Open(FileMode.Create);
procedure BlockFileOf<T>.Rewrite(fname:string);
procedure BlockFileOf<T>.Rewrite(fname: string);
begin
Assign(fname);
Rewrite;
end;
procedure BlockFileOf<T>.Rewrite(fname:string; offset:int64);
procedure BlockFileOf<T>.Rewrite(fname: string; offset: int64);
begin
Assign(fname, offset);
Rewrite;
@ -499,13 +527,13 @@ end;
procedure BlockFileOf<T>.Reset :=
Open(FileMode.Open);
procedure BlockFileOf<T>.Reset(fname:string);
procedure BlockFileOf<T>.Reset(fname: string);
begin
Assign(fname);
Reset;
end;
procedure BlockFileOf<T>.Reset(fname:string; offset:int64);
procedure BlockFileOf<T>.Reset(fname: string; offset: int64);
begin
Assign(fname, offset);
Reset;
@ -515,16 +543,19 @@ end;
{$region Append}
procedure BlockFileOf<T>.Append :=
Open(FileMode.Append);
procedure BlockFileOf<T>.Append;
begin
Open(FileMode.Open);
str.Position := str.Length;
end;
procedure BlockFileOf<T>.Append(fname:string);
procedure BlockFileOf<T>.Append(fname: string);
begin
Assign(fname);
Append;
end;
procedure BlockFileOf<T>.Append(fname:string; offset:int64);
procedure BlockFileOf<T>.Append(fname: string; offset: int64);
begin
Assign(fname, offset);
Append;
@ -575,7 +606,7 @@ begin
bw.Write(a);
end;
procedure BlockFileOf<T>.Write(params o:array of T);
procedure BlockFileOf<T>.Write(params o: array of T);
begin
if fi = nil then raise new FileNotAssignedException;
if str = nil then raise new FileNotOpenedException(fi.FullName);
@ -594,7 +625,7 @@ begin
bw.Write(a);
end;
procedure BlockFileOf<T>.Write(o:ICollection<T>);
procedure BlockFileOf<T>.Write(o: ICollection<T>);
type TArr = array of T;
begin
if o is TArr(var a) then
@ -622,13 +653,13 @@ begin
bw.Write(a);
end;
procedure BlockFileOf<T>.Write(o:sequence of T) :=
procedure BlockFileOf<T>.Write(o: sequence of T) :=
if o is ICollection<T>(var c) then
Write(c) else
foreach var el in o do
Write(el);
procedure BlockFileOf<T>.Write(o:array of T; from,count:integer);
procedure BlockFileOf<T>.Write(o: array of T; from, count: integer);
begin
if fi = nil then raise new FileNotAssignedException;
if str = nil then raise new FileNotOpenedException(fi.FullName);
@ -647,7 +678,7 @@ begin
bw.Write(a);
end;
procedure BlockFileOf<T>.Write(o:ICollection<T>; from,count:integer);
procedure BlockFileOf<T>.Write(o: ICollection<T>; from, count: integer);
type TArr = array of T;
begin
if o is TArr(var a) then
@ -678,7 +709,7 @@ begin
bw.Write(a);
end;
procedure BlockFileOf<T>.Write(o:sequence of T; from,count:integer) :=
procedure BlockFileOf<T>.Write(o: sequence of T; from, count: integer) :=
if o is ICollection<T>(var c) then
Write(c,from,count) else
Write(o.Skip(from).Take(count));
@ -687,7 +718,7 @@ if o is ICollection<T>(var c) then
{$region Read}
function BlockFileOf<T>.Read:T;
function BlockFileOf<T>.Read: T;
begin
if fi = nil then raise new FileNotAssignedException;
if str = nil then raise new FileNotOpenedException(fi.FullName);
@ -703,7 +734,7 @@ begin
gc_hnd.Free;
end;
function BlockFileOf<T>.Read(count:integer):array of T;
function BlockFileOf<T>.Read(count: integer): array of T;
begin
if fi = nil then raise new FileNotAssignedException;
if str = nil then raise new FileNotOpenedException(fi.FullName);
@ -723,13 +754,13 @@ begin
gc_hnd2.Free;
end;
function BlockFileOf<T>.Read(start_elm, count:integer):array of T;
function BlockFileOf<T>.Read(start_elm, count:integer): array of T;
begin
Pos := start_elm;
Result := Read(count);
end;
function BlockFileOf<T>.InternalReadLazy(c:integer; start_pos:int64):sequence of T;
function BlockFileOf<T>.InternalReadLazy(c: integer; start_pos: int64): sequence of T;
begin
if fi = nil then raise new FileNotAssignedException;
if str = nil then raise new FileNotOpenedException(fi.FullName);
@ -742,7 +773,7 @@ begin
end;
end;
function BlockFileOf<T>.ToSeqBlocks(blocks_size:integer):sequence of array of T;
function BlockFileOf<T>.ToSeqBlocks(blocks_size: integer): sequence of array of T;
begin
var c := blocks_size div sz;
var i := 0;
@ -767,7 +798,7 @@ begin
end;
end;
function BlockFileOf<T>.ToSeq:sequence of T;
function BlockFileOf<T>.ToSeq: sequence of T;
begin
var i := 0;
while not EOF do

View file

@ -448,21 +448,20 @@ var GraphWindow: GraphWindowType;
// -----------------------------------------------------
//>> События модуля GraphWPF # GraphWPF events
// -----------------------------------------------------
var
/// Событие нажатия на кнопку мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши
OnMouseDown: procedure(x, y: real; mousebutton: integer);
/// Событие отжатия кнопки мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если отжата левая кнопка мыши, и 2, если отжата правая кнопка мыши
OnMouseUp: procedure(x, y: real; mousebutton: integer);
/// Событие перемещения мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 0, если кнопка мыши не нажата, 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши
OnMouseMove: procedure(x, y: real; mousebutton: integer);
/// Событие нажатия клавиши
OnKeyDown: procedure(k: Key);
/// Событие отжатия клавиши
OnKeyUp: procedure(k: Key);
/// Событие нажатия символьной клавиши
OnKeyPress: procedure(ch: char);
/// Событие изменения размера графического окна
OnResize: procedure;
/// Событие нажатия на кнопку мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши
var OnMouseDown: procedure(x, y: real; mousebutton: integer);
/// Событие отжатия кнопки мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если отжата левая кнопка мыши, и 2, если отжата правая кнопка мыши
var OnMouseUp: procedure(x, y: real; mousebutton: integer);
/// Событие перемещения мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 0, если кнопка мыши не нажата, 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши
var OnMouseMove: procedure(x, y: real; mousebutton: integer);
/// Событие нажатия клавиши
var OnKeyDown: procedure(k: Key);
/// Событие отжатия клавиши
var OnKeyUp: procedure(k: Key);
/// Событие нажатия символьной клавиши
var OnKeyPress: procedure(ch: char);
/// Событие изменения размера графического окна
var OnResize: procedure;
//{{{--doc: Конец секции 3 }}}

View file

@ -0,0 +1,19 @@
type
Base<T> = class
XYZW: T;
procedure p(d: T);
begin
XYZW := d;
end;
end;
Derived<T1> = class(Base<T1>)
//XYZW: T1;
end;
begin
var a := new Derived<integer>;
a.p(2);
a.XYZW := 2;
Assert(a.XYZW=2);
end.

View file

@ -448,21 +448,20 @@ var GraphWindow: GraphWindowType;
// -----------------------------------------------------
//>> События модуля GraphWPF # GraphWPF events
// -----------------------------------------------------
var
/// Событие нажатия на кнопку мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши
OnMouseDown: procedure(x, y: real; mousebutton: integer);
/// Событие отжатия кнопки мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если отжата левая кнопка мыши, и 2, если отжата правая кнопка мыши
OnMouseUp: procedure(x, y: real; mousebutton: integer);
/// Событие перемещения мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 0, если кнопка мыши не нажата, 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши
OnMouseMove: procedure(x, y: real; mousebutton: integer);
/// Событие нажатия клавиши
OnKeyDown: procedure(k: Key);
/// Событие отжатия клавиши
OnKeyUp: procedure(k: Key);
/// Событие нажатия символьной клавиши
OnKeyPress: procedure(ch: char);
/// Событие изменения размера графического окна
OnResize: procedure;
/// Событие нажатия на кнопку мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши
var OnMouseDown: procedure(x, y: real; mousebutton: integer);
/// Событие отжатия кнопки мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 1, если отжата левая кнопка мыши, и 2, если отжата правая кнопка мыши
var OnMouseUp: procedure(x, y: real; mousebutton: integer);
/// Событие перемещения мыши. (x,y) - координаты курсора мыши в момент наступления события, mousebutton = 0, если кнопка мыши не нажата, 1, если нажата левая кнопка мыши, и 2, если нажата правая кнопка мыши
var OnMouseMove: procedure(x, y: real; mousebutton: integer);
/// Событие нажатия клавиши
var OnKeyDown: procedure(k: Key);
/// Событие отжатия клавиши
var OnKeyUp: procedure(k: Key);
/// Событие нажатия символьной клавиши
var OnKeyPress: procedure(ch: char);
/// Событие изменения размера графического окна
var OnResize: procedure;
//{{{--doc: Конец секции 3 }}}

Binary file not shown.