2025-03 Транслятор CLD генерит Контекст | CLD translator generates Context
This commit is contained in:
137
ru/news/2025-03_cld_ctx-gen.md
Normal file
137
ru/news/2025-03_cld_ctx-gen.md
Normal file
@@ -0,0 +1,137 @@
|
||||
Title: CLD: Генерация контекста
|
||||
Date: 2025-03-11 00:00
|
||||
Category: News
|
||||
Slug: cld_ctx-gen
|
||||
Lang: ru
|
||||
|
||||
![splash][splash]
|
||||
|
||||
# Генерация контекста
|
||||
|
||||
В феврале доработал транслятор Межъязыкового диалекта
|
||||
(**C**ross-**l**anguage **d**ialect) (CLD) до генерации
|
||||
Контекста на основе описания в YML. Сгенерированные Контексты уже использованы
|
||||
в следующих проектах:
|
||||
|
||||
* CLD (транслятор CLD генерирует свой собственный Контекст)
|
||||
* LHA
|
||||
* PSKOV
|
||||
|
||||
Доселе я никогда прежде не тратил время на объяснение сути Контекста, поэтому
|
||||
сейчас самое время для очень краткого описания: Контекст очень близок
|
||||
к понятию [Store в Redux][store]. К сожалению, на этом месте пояснение заканчиваю,
|
||||
т.к. без каких-либо весомых доказательств пользы Контекста не готов
|
||||
обосновывать его применимость. Как только придёт таковое время, так я сразу
|
||||
расскажу детали.
|
||||
|
||||
Теперь вернёмся к генерации Контекста. Вот как выглядит YML Контекста в проекте LHA
|
||||
([entities.yml][entities]):
|
||||
|
||||
```
|
||||
# Application state context
|
||||
Context:
|
||||
type: context
|
||||
fields:
|
||||
# Command line arguments
|
||||
arguments: [String]
|
||||
consoleOutput: String
|
||||
defaultDir: String
|
||||
didLaunch: Bool
|
||||
dir: String
|
||||
httpDefaultPort: Int
|
||||
httpLaunch: Bool
|
||||
httpPort: Int
|
||||
httpReply: String
|
||||
httpRequest: NetRequest
|
||||
```
|
||||
|
||||
Транслятор CLD преобразует его в следующий код на Kotlin ([entities.kt][entities-result]):
|
||||
|
||||
```
|
||||
// Application state context
|
||||
data class Context(
|
||||
// Command line arguments
|
||||
var arguments: Array<String> = arrayOf(),
|
||||
var consoleOutput: String = "",
|
||||
var defaultDir: String = "",
|
||||
var didLaunch: Boolean = false,
|
||||
var dir: String = "",
|
||||
var httpDefaultPort: Int = 0,
|
||||
var httpLaunch: Boolean = false,
|
||||
var httpPort: Int = 0,
|
||||
var httpReply: String = "",
|
||||
var httpRequest: NetRequest = NetRequest(),
|
||||
override var recentField: String = "",
|
||||
): CLDContext {
|
||||
override fun <T> field(name: String): T {
|
||||
if (name == "arguments") {
|
||||
return arguments as T
|
||||
} else if (name == "consoleOutput") {
|
||||
return consoleOutput as T
|
||||
} else if (name == "defaultDir") {
|
||||
return defaultDir as T
|
||||
} else if (name == "didLaunch") {
|
||||
return didLaunch as T
|
||||
} else if (name == "dir") {
|
||||
return dir as T
|
||||
} else if (name == "httpDefaultPort") {
|
||||
return httpDefaultPort as T
|
||||
} else if (name == "httpLaunch") {
|
||||
return httpLaunch as T
|
||||
} else if (name == "httpPort") {
|
||||
return httpPort as T
|
||||
} else if (name == "httpReply") {
|
||||
return httpReply as T
|
||||
} else if (name == "httpRequest") {
|
||||
return httpRequest as T
|
||||
}
|
||||
return "unknown-field-name" as T
|
||||
}
|
||||
|
||||
override fun selfCopy(): CLDContext {
|
||||
return this.copy()
|
||||
}
|
||||
|
||||
override fun setField(
|
||||
name: String,
|
||||
value: Any?
|
||||
) {
|
||||
if (name == "arguments") {
|
||||
arguments = value as Array<String>
|
||||
} else if (name == "consoleOutput") {
|
||||
consoleOutput = value as String
|
||||
} else if (name == "defaultDir") {
|
||||
defaultDir = value as String
|
||||
} else if (name == "didLaunch") {
|
||||
didLaunch = value as Boolean
|
||||
} else if (name == "dir") {
|
||||
dir = value as String
|
||||
} else if (name == "httpDefaultPort") {
|
||||
httpDefaultPort = value as Int
|
||||
} else if (name == "httpLaunch") {
|
||||
httpLaunch = value as Boolean
|
||||
} else if (name == "httpPort") {
|
||||
httpPort = value as Int
|
||||
} else if (name == "httpReply") {
|
||||
httpReply = value as String
|
||||
} else if (name == "httpRequest") {
|
||||
httpRequest = value as NetRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Март
|
||||
|
||||
На текущий момент Kotlin является якорным языком CLD. Для использования
|
||||
Kotlin необходимо установить соответствующие инструменты Java (Gradle,
|
||||
Android Studio либо сама JVM). Такое требование делает создание инструмента
|
||||
разработки чисто для браузера невозможным. Однако, я считаю работу инструмента
|
||||
разработки в браузере ключевой особенностью для достижения портируемости кода.
|
||||
|
||||
Поэтому в марте я планирую создать заготовку инструмента, работающего в браузере.
|
||||
|
||||
[entities]: https://github.com/OGStudio/local-host-access/blob/main/cld/entities.yml
|
||||
[entities-result]: https://github.com/OGStudio/local-host-access/blob/main/src/entities.kt#L3
|
||||
[splash]: ../../images/2025-03_redux-data-flow.jpg
|
||||
[store]: https://redux.js.org/introduction/getting-started#basic-example
|
||||
171
ru/news/cld_ctx-gen.html
Normal file
171
ru/news/cld_ctx-gen.html
Normal file
@@ -0,0 +1,171 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../style.css">
|
||||
</head>
|
||||
<body>
|
||||
<script data-goatcounter="https://services.opengamestudio.org:443/count" async src="//services.opengamestudio.org:443/count.js"></script>
|
||||
<div id="header">
|
||||
<div class="header2">
|
||||
<div class="menu">
|
||||
<a href="../../ru/news/index.html">Новости</a>
|
||||
<a href="../../ru/game/index.html">Игры</a>
|
||||
<a href="../../ru/tool/index.html">Инструменты</a>
|
||||
<a href="../../ru/page/about.html">О нас</a>
|
||||
</div>
|
||||
<div id="lang">
|
||||
<a href="../../en/news/cld_ctx-gen.html">EN</a>
|
||||
<a href="../../ru/news/cld_ctx-gen.html">RU</a>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="left_item_title">В новостях...</h3>
|
||||
<center>
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="cld_ctx-gen.html">CLD: Генерация контекста</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2025-03-11 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2025-03_redux-data-flow.jpg" alt="splash" /></p>
|
||||
<h1 id="">Генерация контекста</h1>
|
||||
<p>В феврале доработал транслятор Межъязыкового диалекта
|
||||
(<strong>C</strong>ross-<strong>l</strong>anguage <strong>d</strong>ialect) (CLD) до генерации
|
||||
Контекста на основе описания в YML. Сгенерированные Контексты уже использованы
|
||||
в следующих проектах:</p>
|
||||
<ul>
|
||||
<li>CLD (транслятор CLD генерирует свой собственный Контекст)</li>
|
||||
<li>LHA</li>
|
||||
<li>PSKOV</li>
|
||||
</ul>
|
||||
<p>Доселе я никогда прежде не тратил время на объяснение сути Контекста, поэтому
|
||||
сейчас самое время для очень краткого описания: Контекст очень близок
|
||||
к понятию <a href="https://redux.js.org/introduction/getting-started#basic-example">Store в Redux</a>. К сожалению, на этом месте пояснение заканчиваю,
|
||||
т.к. без каких-либо весомых доказательств пользы Контекста не готов
|
||||
обосновывать его применимость. Как только придёт таковое время, так я сразу
|
||||
расскажу детали.</p>
|
||||
<p>Теперь вернёмся к генерации Контекста. Вот как выглядит YML Контекста в проекте LHA
|
||||
(<a href="https://github.com/OGStudio/local-host-access/blob/main/cld/entities.yml">entities.yml</a>):</p>
|
||||
<pre><code># Application state context
|
||||
Context:
|
||||
type: context
|
||||
fields:
|
||||
# Command line arguments
|
||||
arguments: [String]
|
||||
consoleOutput: String
|
||||
defaultDir: String
|
||||
didLaunch: Bool
|
||||
dir: String
|
||||
httpDefaultPort: Int
|
||||
httpLaunch: Bool
|
||||
httpPort: Int
|
||||
httpReply: String
|
||||
httpRequest: NetRequest
|
||||
</code></pre>
|
||||
<p>Транслятор CLD преобразует его в следующий код на Kotlin (<a href="https://github.com/OGStudio/local-host-access/blob/main/src/entities.kt#L3">entities.kt</a>):</p>
|
||||
<pre><code>// Application state context
|
||||
data class Context(
|
||||
// Command line arguments
|
||||
var arguments: Array<String> = arrayOf(),
|
||||
var consoleOutput: String = "",
|
||||
var defaultDir: String = "",
|
||||
var didLaunch: Boolean = false,
|
||||
var dir: String = "",
|
||||
var httpDefaultPort: Int = 0,
|
||||
var httpLaunch: Boolean = false,
|
||||
var httpPort: Int = 0,
|
||||
var httpReply: String = "",
|
||||
var httpRequest: NetRequest = NetRequest(),
|
||||
override var recentField: String = "",
|
||||
): CLDContext {
|
||||
override fun <T> field(name: String): T {
|
||||
if (name == "arguments") {
|
||||
return arguments as T
|
||||
} else if (name == "consoleOutput") {
|
||||
return consoleOutput as T
|
||||
} else if (name == "defaultDir") {
|
||||
return defaultDir as T
|
||||
} else if (name == "didLaunch") {
|
||||
return didLaunch as T
|
||||
} else if (name == "dir") {
|
||||
return dir as T
|
||||
} else if (name == "httpDefaultPort") {
|
||||
return httpDefaultPort as T
|
||||
} else if (name == "httpLaunch") {
|
||||
return httpLaunch as T
|
||||
} else if (name == "httpPort") {
|
||||
return httpPort as T
|
||||
} else if (name == "httpReply") {
|
||||
return httpReply as T
|
||||
} else if (name == "httpRequest") {
|
||||
return httpRequest as T
|
||||
}
|
||||
return "unknown-field-name" as T
|
||||
}
|
||||
|
||||
override fun selfCopy(): CLDContext {
|
||||
return this.copy()
|
||||
}
|
||||
|
||||
override fun setField(
|
||||
name: String,
|
||||
value: Any?
|
||||
) {
|
||||
if (name == "arguments") {
|
||||
arguments = value as Array<String>
|
||||
} else if (name == "consoleOutput") {
|
||||
consoleOutput = value as String
|
||||
} else if (name == "defaultDir") {
|
||||
defaultDir = value as String
|
||||
} else if (name == "didLaunch") {
|
||||
didLaunch = value as Boolean
|
||||
} else if (name == "dir") {
|
||||
dir = value as String
|
||||
} else if (name == "httpDefaultPort") {
|
||||
httpDefaultPort = value as Int
|
||||
} else if (name == "httpLaunch") {
|
||||
httpLaunch = value as Boolean
|
||||
} else if (name == "httpPort") {
|
||||
httpPort = value as Int
|
||||
} else if (name == "httpReply") {
|
||||
httpReply = value as String
|
||||
} else if (name == "httpRequest") {
|
||||
httpRequest = value as NetRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<h1 id="-1">Март</h1>
|
||||
<p>На текущий момент Kotlin является якорным языком CLD. Для использования
|
||||
Kotlin необходимо установить соответствующие инструменты Java (Gradle,
|
||||
Android Studio либо сама JVM). Такое требование делает создание инструмента
|
||||
разработки чисто для браузера невозможным. Однако, я считаю работу инструмента
|
||||
разработки в браузере ключевой особенностью для достижения портируемости кода.</p>
|
||||
<p>Поэтому в марте я планирую создать заготовку инструмента, работающего в браузере.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="disqus_thread"></div>
|
||||
<script>
|
||||
var disqus_config = function () {
|
||||
this.page.url = "https://opengamestudio.org/ru/news/cld_ctx-gen.html";
|
||||
this.page.identifier = "cld_ctx-gen.html";
|
||||
};
|
||||
(function() { // DON'T EDIT BELOW THIS LINE
|
||||
var d = document, s = d.createElement('script');
|
||||
s.src = 'https://opengamestudio.disqus.com/embed.js';
|
||||
s.setAttribute('data-timestamp', +new Date());
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
</script>
|
||||
<noscript>Пожалуйста, включите JavaScript для просмотра <a href="https://disqus.com/?ref_noscript">комментариев на платформе Disqus.</a></noscript>
|
||||
<div id="footer">
|
||||
Сайт сгенерирован <a href="http://opengamestudio.org/pskov/ru">ПСКОВОМ</a>
|
||||
из <a href="http://github.com/ogstudio/site-opengamestudio">этого исходного кода</a>.
|
||||
</div>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
168
ru/news/ctx-gen.html
Normal file
168
ru/news/ctx-gen.html
Normal file
@@ -0,0 +1,168 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../style.css">
|
||||
</head>
|
||||
<body>
|
||||
<script data-goatcounter="https://services.opengamestudio.org:443/count" async src="//services.opengamestudio.org:443/count.js"></script>
|
||||
<div id="header">
|
||||
<div class="header2">
|
||||
<div class="menu">
|
||||
<a href="../../ru/news/index.html">Новости</a>
|
||||
<a href="../../ru/game/index.html">Игры</a>
|
||||
<a href="../../ru/tool/index.html">Инструменты</a>
|
||||
<a href="../../ru/page/about.html">О нас</a>
|
||||
</div>
|
||||
<div id="lang">
|
||||
<a href="../../en/news/ctx-gen.html">EN</a>
|
||||
<a href="../../ru/news/ctx-gen.html">RU</a>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="left_item_title">В новостях...</h3>
|
||||
<center>
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="ctx-gen.html">Генерация Контекста из YML</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2025-03-11 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/??.png" alt="splash" /></p>
|
||||
<h1 id="">Генерация Контекста</h1>
|
||||
<p>В феврале доработал конвертер межъязыкового диалекта для генерации
|
||||
Контекста на основе описания в YML и уже применил его для проектов
|
||||
Local Host Access, самого конвертера, ПСКОВа.</p>
|
||||
<p>Если очень кратко, то Контекст представляет из себя полное состояние
|
||||
приложения, по сути аналог <a href="https://redux.js.org/introduction/getting-started#basic-example">store в Redux</a>.</p>
|
||||
<p>Для примера возьмём описание Контекста из Local Host Access
|
||||
(<a href="https://github.com/OGStudio/local-host-access/blob/main/cld/entities.yml">entities.yml</a>):</p>
|
||||
<pre><code># Application state context
|
||||
Context:
|
||||
type: context
|
||||
fields:
|
||||
# Command line arguments
|
||||
arguments: [String]
|
||||
consoleOutput: String
|
||||
defaultDir: String
|
||||
didLaunch: Bool
|
||||
dir: String
|
||||
httpDefaultPort: Int
|
||||
httpLaunch: Bool
|
||||
httpPort: Int
|
||||
httpReply: String
|
||||
httpRequest: NetRequest
|
||||
</code></pre>
|
||||
<p>Конвертер преобразует его в следующий код на Kotlin (<a href="https://github.com/OGStudio/local-host-access/blob/main/src/entities.kt#L3">entities.kt</a>):</p>
|
||||
<pre><code>// Application state context
|
||||
data class Context(
|
||||
// Command line arguments
|
||||
var arguments: Array<String> = arrayOf(),
|
||||
var consoleOutput: String = "",
|
||||
var defaultDir: String = "",
|
||||
var didLaunch: Boolean = false,
|
||||
var dir: String = "",
|
||||
var httpDefaultPort: Int = 0,
|
||||
var httpLaunch: Boolean = false,
|
||||
var httpPort: Int = 0,
|
||||
var httpReply: String = "",
|
||||
var httpRequest: NetRequest = NetRequest(),
|
||||
override var recentField: String = "",
|
||||
): CLDContext {
|
||||
override fun <T> field(name: String): T {
|
||||
if (name == "arguments") {
|
||||
return arguments as T
|
||||
} else if (name == "consoleOutput") {
|
||||
return consoleOutput as T
|
||||
} else if (name == "defaultDir") {
|
||||
return defaultDir as T
|
||||
} else if (name == "didLaunch") {
|
||||
return didLaunch as T
|
||||
} else if (name == "dir") {
|
||||
return dir as T
|
||||
} else if (name == "httpDefaultPort") {
|
||||
return httpDefaultPort as T
|
||||
} else if (name == "httpLaunch") {
|
||||
return httpLaunch as T
|
||||
} else if (name == "httpPort") {
|
||||
return httpPort as T
|
||||
} else if (name == "httpReply") {
|
||||
return httpReply as T
|
||||
} else if (name == "httpRequest") {
|
||||
return httpRequest as T
|
||||
}
|
||||
return "unknown-field-name" as T
|
||||
}
|
||||
|
||||
override fun selfCopy(): CLDContext {
|
||||
return this.copy()
|
||||
}
|
||||
|
||||
override fun setField(
|
||||
name: String,
|
||||
value: Any?
|
||||
) {
|
||||
if (name == "arguments") {
|
||||
arguments = value as Array<String>
|
||||
} else if (name == "consoleOutput") {
|
||||
consoleOutput = value as String
|
||||
} else if (name == "defaultDir") {
|
||||
defaultDir = value as String
|
||||
} else if (name == "didLaunch") {
|
||||
didLaunch = value as Boolean
|
||||
} else if (name == "dir") {
|
||||
dir = value as String
|
||||
} else if (name == "httpDefaultPort") {
|
||||
httpDefaultPort = value as Int
|
||||
} else if (name == "httpLaunch") {
|
||||
httpLaunch = value as Boolean
|
||||
} else if (name == "httpPort") {
|
||||
httpPort = value as Int
|
||||
} else if (name == "httpReply") {
|
||||
httpReply = value as String
|
||||
} else if (name == "httpRequest") {
|
||||
httpRequest = value as NetRequest
|
||||
}
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<h1 id="-1">Проблемы</h1>
|
||||
<p>Тем не менее, на текущий момент ощутил огромный минус Котлина для
|
||||
проекта CLD - необходимость оригинального компилятора Котлин, т.к.
|
||||
без него я не могу валидировать код. Могу транслировать, но не валидировать.
|
||||
Выходит, я не смогу написать чисто браузерный транслятор, чтобы в браузере
|
||||
писать Котлин, а он чтобы мне выдавал, скажем, Питон, т.к. в этом случае
|
||||
я в браузере не могу проверить ни Котлин, ни Питон.</p>
|
||||
<p>Поэтому в марте я рассмотрю возможность использования всё-таки чистого
|
||||
JavaScript в качестве якорного языка для CLD, хоть в JS и не строгой типизации,
|
||||
зато браузер уже содержит компилятор JS.
|
||||
А типы можно комментом ведь написать!</p>
|
||||
<h1 id="-2">Март</h1>
|
||||
<p>В марте начну создание нового инструмента для решения своих
|
||||
хобби-задач на основе Isomorphic-Git.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="disqus_thread"></div>
|
||||
<script>
|
||||
var disqus_config = function () {
|
||||
this.page.url = "https://opengamestudio.org/ru/news/ctx-gen.html";
|
||||
this.page.identifier = "ctx-gen.html";
|
||||
};
|
||||
(function() { // DON'T EDIT BELOW THIS LINE
|
||||
var d = document, s = d.createElement('script');
|
||||
s.src = 'https://opengamestudio.disqus.com/embed.js';
|
||||
s.setAttribute('data-timestamp', +new Date());
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
</script>
|
||||
<noscript>Пожалуйста, включите JavaScript для просмотра <a href="https://disqus.com/?ref_noscript">комментариев на платформе Disqus.</a></noscript>
|
||||
<div id="footer">
|
||||
Сайт сгенерирован <a href="http://opengamestudio.org/pskov/ru">ПСКОВОМ</a>
|
||||
из <a href="http://github.com/ogstudio/site-opengamestudio">этого исходного кода</a>.
|
||||
</div>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
@@ -25,6 +25,32 @@
|
||||
<h1>Новости</h1>
|
||||
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="cld_ctx-gen.html">CLD: Генерация контекста</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2025-03-11 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2025-03_redux-data-flow.jpg" alt="splash" /></p>
|
||||
<h1 id="">Генерация контекста</h1>
|
||||
<p>В феврале доработал транслятор Межъязыкового диалекта
|
||||
(<strong>C</strong>ross-<strong>l</strong>anguage <strong>d</strong>ialect) (CLD) до генерации
|
||||
Контекста на основе описания в YML. Сгенерированные Контексты уже использованы
|
||||
в следующих проектах:</p>
|
||||
<ul>
|
||||
<li>CLD (транслятор CLD генерирует свой собственный Контекст)</li>
|
||||
<li>LHA</li>
|
||||
<li>PSKOV</li>
|
||||
</ul>
|
||||
<p>Доселе я никогда прежде не тратил время на объяснение сути Контекста, поэтому
|
||||
сейчас самое время для очень краткого описания: Контекст очень близок
|
||||
к понятию <a href="https://redux.js.org/introduction/getting-started#basic-example">Store в Redux</a>. К сожалению, на этом месте пояснение заканчиваю,. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="cld_ctx-gen.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="psk-jvm-item.html">ПСКОВ 2 на JVM</a>
|
||||
</h2>
|
||||
@@ -204,27 +230,8 @@ Python в JavaScript. Этого не произошло, потому что п
|
||||
<div class="news_item_more">
|
||||
<a href="memory-gui.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="memory-text-ui.html">Текстовый интерфейс «Памяти»</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2024-06-14 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<h1 id="">Текстовый интерфейс «Памяти»</h1>
|
||||
<p>В мае реализовал текстовый интерфейс игры «Память» на Python. В C++ перевёл инструментом.</p>
|
||||
<p>Реализация логического игрового цикла привела к появлению контроллера, управляющего
|
||||
контекстом. Создание контроллера на Python прошло без происшествий, а вот с версией
|
||||
для C++ пришлось помучиться. Мучения были вызваны тем, что контроллер использует
|
||||
<a href="https://en.cppreference.com/w/cpp/utility/any">std::any</a> из C++17, а инструмент ограничен C++11 с целью поддержки OpenWrt.</p>
|
||||
<p>Что касается объёма кода, то картина получилась следующей (в строках):. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="memory-text-ui.html">Читать далее</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="pagination_title">Страница 1 из 8</p>
|
||||
<p class="pagination_title">Страница 1 из 9</p>
|
||||
<p>
|
||||
<a href="index2.html">Старее »</a>
|
||||
</p>
|
||||
|
||||
@@ -25,6 +25,25 @@
|
||||
<h1>Новости</h1>
|
||||
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="memory-text-ui.html">Текстовый интерфейс «Памяти»</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2024-06-14 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<h1 id="">Текстовый интерфейс «Памяти»</h1>
|
||||
<p>В мае реализовал текстовый интерфейс игры «Память» на Python. В C++ перевёл инструментом.</p>
|
||||
<p>Реализация логического игрового цикла привела к появлению контроллера, управляющего
|
||||
контекстом. Создание контроллера на Python прошло без происшествий, а вот с версией
|
||||
для C++ пришлось помучиться. Мучения были вызваны тем, что контроллер использует
|
||||
<a href="https://en.cppreference.com/w/cpp/utility/any">std::any</a> из C++17, а инструмент ограничен C++11 с целью поддержки OpenWrt.</p>
|
||||
<p>Что касается объёма кода, то картина получилась следующей (в строках):. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="memory-text-ui.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="memory-logic.html">Игровая логика «Памяти»</a>
|
||||
</h2>
|
||||
@@ -197,25 +216,8 @@ Ubuntu Edge</a>. Особенностью продукта должна была
|
||||
<div class="news_item_more">
|
||||
<a href="teaching-to-program-2019.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="the-pros-and-cons-of-restarting-from-scratch.html">Минусы и плюсы начинания с начала</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2020-01-01 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2020-01-01-ny.jpg" alt="Happy 2020" /></p>
|
||||
<p>Любой, кто следит за нашим прогрессом достаточно долго, может сказать, что мы много раз перезапускали разработку с нуля.</p>
|
||||
<p>Еще до выпуска <a href="../game/ogs-mahjong-1.html">"OGS Mahjong"</a> мы несколько раз меняли технологии "под капотом". После релиза мы неоднократно делали это снова, отбрасывая уже готовые решения.
|
||||
Может показаться, что сейчас у нас меньше готового, чем перед выходом <a href="../game/ogs-mahjong-1.html">"OGS Mahjong"</a>. Это правда, но не совсем.</p>
|
||||
<p>Когда вышел <a href="../game/ogs-mahjong-1.html">"OGS Mahjong"</a>, у нас была приятно выглядящая (на тот момент) игра с открытым исходным кодом, которая работала под Windows и Linux. С некоторой удачей и усилием в нее можно поиграть и сегодня, но уже не "из коробки".. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="the-pros-and-cons-of-restarting-from-scratch.html">Читать далее</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="pagination_title">Страница 2 из 8</p>
|
||||
<p class="pagination_title">Страница 2 из 9</p>
|
||||
<p>
|
||||
<a href="index.html">« Новее</a>
|
||||
<a href="index3.html">Старее »</a>
|
||||
|
||||
@@ -25,6 +25,23 @@
|
||||
<h1>Новости</h1>
|
||||
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="the-pros-and-cons-of-restarting-from-scratch.html">Минусы и плюсы начинания с начала</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2020-01-01 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2020-01-01-ny.jpg" alt="Happy 2020" /></p>
|
||||
<p>Любой, кто следит за нашим прогрессом достаточно долго, может сказать, что мы много раз перезапускали разработку с нуля.</p>
|
||||
<p>Еще до выпуска <a href="../game/ogs-mahjong-1.html">"OGS Mahjong"</a> мы несколько раз меняли технологии "под капотом". После релиза мы неоднократно делали это снова, отбрасывая уже готовые решения.
|
||||
Может показаться, что сейчас у нас меньше готового, чем перед выходом <a href="../game/ogs-mahjong-1.html">"OGS Mahjong"</a>. Это правда, но не совсем.</p>
|
||||
<p>Когда вышел <a href="../game/ogs-mahjong-1.html">"OGS Mahjong"</a>, у нас была приятно выглядящая (на тот момент) игра с открытым исходным кодом, которая работала под Windows и Linux. С некоторой удачей и усилием в нее можно поиграть и сегодня, но уже не "из коробки".. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="the-pros-and-cons-of-restarting-from-scratch.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="on-the-way-to-durable-applications.html">На пути к долговечным приложениям</a>
|
||||
</h2>
|
||||
@@ -171,23 +188,8 @@
|
||||
<div class="news_item_more">
|
||||
<a href="example-driven-development.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="openscenegraph-examples.html">Кросс-платформенные примеры OpenSceneGraph</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2018-04-20 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2018-04-20-openscenegraph-examples.png" alt="iOS Simulator отображает куб" /></p>
|
||||
<p>Эта статья резюмирует создание первых двух кросс-платформенных примеров OpenSceneGraph.</p>
|
||||
<p>К тому времени, как мы выпустили <a href="mahjong-techdemo1-gameplay.html">первую техническую демонстрацию OGS Mahjong 2</a>, нас уже дожидался <a href="https://github.com/OGStudio/openscenegraph-cross-platform-guide/issues/4">запрос на описание работы с изображениями</a> в OpenSceneGraph на Android. Сначала мы рассматривали возможность создания нового самоучителя для <a href="https://github.com/OGStudio/openscenegraph-cross-platform-guide">кросс-платформенного руководства OpenSceneGraph</a>, но позже мы оценили необходимые трудозатраты и посчитали их излишними для освещения такой небольшой темы (по сравнению с тем, что умеет средняя игра) как загрузка изображений. Мы решили продолжить делиться нашими знаниями в виде конкретных примеров. Так на свет появились <a href="https://github.com/OGStudio/openscenegraph-cross-platform-examples">кросс-платформенные примеры OpenSceneGraph</a>.. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="openscenegraph-examples.html">Читать далее</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="pagination_title">Страница 3 из 8</p>
|
||||
<p class="pagination_title">Страница 3 из 9</p>
|
||||
<p>
|
||||
<a href="index2.html">« Новее</a>
|
||||
<a href="index4.html">Старее »</a>
|
||||
|
||||
@@ -25,6 +25,21 @@
|
||||
<h1>Новости</h1>
|
||||
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="openscenegraph-examples.html">Кросс-платформенные примеры OpenSceneGraph</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2018-04-20 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2018-04-20-openscenegraph-examples.png" alt="iOS Simulator отображает куб" /></p>
|
||||
<p>Эта статья резюмирует создание первых двух кросс-платформенных примеров OpenSceneGraph.</p>
|
||||
<p>К тому времени, как мы выпустили <a href="mahjong-techdemo1-gameplay.html">первую техническую демонстрацию OGS Mahjong 2</a>, нас уже дожидался <a href="https://github.com/OGStudio/openscenegraph-cross-platform-guide/issues/4">запрос на описание работы с изображениями</a> в OpenSceneGraph на Android. Сначала мы рассматривали возможность создания нового самоучителя для <a href="https://github.com/OGStudio/openscenegraph-cross-platform-guide">кросс-платформенного руководства OpenSceneGraph</a>, но позже мы оценили необходимые трудозатраты и посчитали их излишними для освещения такой небольшой темы (по сравнению с тем, что умеет средняя игра) как загрузка изображений. Мы решили продолжить делиться нашими знаниями в виде конкретных примеров. Так на свет появились <a href="https://github.com/OGStudio/openscenegraph-cross-platform-examples">кросс-платформенные примеры OpenSceneGraph</a>.. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="openscenegraph-examples.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="mahjong-techdemo1-gameplay.html">Первая технодемка OGS Mahjong 2: Игровая механика</a>
|
||||
</h2>
|
||||
@@ -171,23 +186,8 @@
|
||||
<div class="news_item_more">
|
||||
<a href="openscenegraph-cross-platform-guide.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="ios-tutorial.html">Самоучитель iOS</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2017-06-08 10:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2017-06-08-ios-refactoring.png" alt="Земля и ракета" /></p>
|
||||
<p>Эта статья описывает проблемы, с которыми мы столкнулись во время создания самоучителя для iOS в мае 2017.</p>
|
||||
<p><a href="https://twitter.com/OpenGameStudio/status/826816343433498627">В феврале</a> мы сумели отобразить простую модель под iOS за считанные дни. Это дало нам уверенность, что самоучитель для iOS мы сделаем столь же быстро. Тем не менее, реальность напомнила нам о простой вещи: быстро сделать можно лишь поделку на коленке, работающую только у самого разработчика; над логически связанным примером, работающим у всех, придётся попотеть.. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="ios-tutorial.html">Читать далее</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="pagination_title">Страница 4 из 8</p>
|
||||
<p class="pagination_title">Страница 4 из 9</p>
|
||||
<p>
|
||||
<a href="index3.html">« Новее</a>
|
||||
<a href="index5.html">Старее »</a>
|
||||
|
||||
@@ -25,6 +25,21 @@
|
||||
<h1>Новости</h1>
|
||||
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="ios-tutorial.html">Самоучитель iOS</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2017-06-08 10:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2017-06-08-ios-refactoring.png" alt="Земля и ракета" /></p>
|
||||
<p>Эта статья описывает проблемы, с которыми мы столкнулись во время создания самоучителя для iOS в мае 2017.</p>
|
||||
<p><a href="https://twitter.com/OpenGameStudio/status/826816343433498627">В феврале</a> мы сумели отобразить простую модель под iOS за считанные дни. Это дало нам уверенность, что самоучитель для iOS мы сделаем столь же быстро. Тем не менее, реальность напомнила нам о простой вещи: быстро сделать можно лишь поделку на коленке, работающую только у самого разработчика; над логически связанным примером, работающим у всех, придётся попотеть.. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="ios-tutorial.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="osg-sample.html">Приложение OpenSceneGraph</a>
|
||||
</h2>
|
||||
@@ -162,30 +177,8 @@
|
||||
<div class="news_item_more">
|
||||
<a href="2016-tech-showcases.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="2016-september-recap.html">Сентябрь 2016 кратко</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2016-10-11 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2016-10-11_september-recap.png" alt="Маджонг, созданный в прямом эфире" /></p>
|
||||
<p>Эта статья описывает стадии по подготовке и проведению прямого эфира сентября 2016: черновик, репетиция, прямой эфир и публикация.</p>
|
||||
<p>Несмотря на то, что сам прямой эфир длится лишь несколько часов, мы готовимся к нему целый месяц. Рассмотрим каждую стадию прямого эфира подробнее.</p>
|
||||
<ol>
|
||||
<li><p><strong>Черновик.</strong> Создание игры в первый раз.</p>
|
||||
<p>Цели:</p>
|
||||
<ul>
|
||||
<li>проверить наши технологии и исправить основные ошибки;</li>
|
||||
<li>узнать о неудобствах использования технологий, чтобы исправить их в следующей итерации разработки;. . .</li></ul></li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="2016-september-recap.html">Читать далее</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="pagination_title">Страница 5 из 8</p>
|
||||
<p class="pagination_title">Страница 5 из 9</p>
|
||||
<p>
|
||||
<a href="index4.html">« Новее</a>
|
||||
<a href="index6.html">Старее »</a>
|
||||
|
||||
@@ -25,6 +25,28 @@
|
||||
<h1>Новости</h1>
|
||||
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="2016-september-recap.html">Сентябрь 2016 кратко</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2016-10-11 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p><img src="../../images/2016-10-11_september-recap.png" alt="Маджонг, созданный в прямом эфире" /></p>
|
||||
<p>Эта статья описывает стадии по подготовке и проведению прямого эфира сентября 2016: черновик, репетиция, прямой эфир и публикация.</p>
|
||||
<p>Несмотря на то, что сам прямой эфир длится лишь несколько часов, мы готовимся к нему целый месяц. Рассмотрим каждую стадию прямого эфира подробнее.</p>
|
||||
<ol>
|
||||
<li><p><strong>Черновик.</strong> Создание игры в первый раз.</p>
|
||||
<p>Цели:</p>
|
||||
<ul>
|
||||
<li>проверить наши технологии и исправить основные ошибки;</li>
|
||||
<li>узнать о неудобствах использования технологий, чтобы исправить их в следующей итерации разработки;. . .</li></ul></li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="2016-september-recap.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="ogs-editor-0.10.html">OGS Editor 0.10 и материалы прямого эфира</a>
|
||||
</h2>
|
||||
@@ -158,22 +180,8 @@
|
||||
<div class="news_item_more">
|
||||
<a href="ogs-editor-0.9.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="may-live-session-announcement.html">Прямой эфир: 28 мая 2016</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2016-05-17 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p>Мы рады сообщить, что трансляция <a title="LiveCoding" href="https://www.livecoding.tv/kornerr">LiveCoding</a> состоится <a href="http://www.timeanddate.com/worldclock/fixedtime.html?msg=%D0%9C%D0%B0%D0%B9%D1%81%D0%BA%D0%B8%D0%B9+%D0%BF%D1%80%D1%8F%D0%BC%D0%BE%D0%B9+%D1%8D%D1%84%D0%B8%D1%80+Open+Game+Studio&iso=20160528T13&p1=166&ah=3">28 мая 2016 в 13:00 MSK</a>. Присоединяйтесь!
|
||||
. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="may-live-session-announcement.html">Читать далее</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="pagination_title">Страница 6 из 8</p>
|
||||
<p class="pagination_title">Страница 6 из 9</p>
|
||||
<p>
|
||||
<a href="index5.html">« Новее</a>
|
||||
<a href="index7.html">Старее »</a>
|
||||
|
||||
@@ -25,6 +25,20 @@
|
||||
<h1>Новости</h1>
|
||||
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="may-live-session-announcement.html">Прямой эфир: 28 мая 2016</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2016-05-17 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p>Мы рады сообщить, что трансляция <a title="LiveCoding" href="https://www.livecoding.tv/kornerr">LiveCoding</a> состоится <a href="http://www.timeanddate.com/worldclock/fixedtime.html?msg=%D0%9C%D0%B0%D0%B9%D1%81%D0%BA%D0%B8%D0%B9+%D0%BF%D1%80%D1%8F%D0%BC%D0%BE%D0%B9+%D1%8D%D1%84%D0%B8%D1%80+Open+Game+Studio&iso=20160528T13&p1=166&ah=3">28 мая 2016 в 13:00 MSK</a>. Присоединяйтесь!
|
||||
. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="may-live-session-announcement.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="may-live-session-decision.html">Майский прямой эфир (Редактор 0.9)</a>
|
||||
</h2>
|
||||
@@ -149,26 +163,8 @@
|
||||
<div class="news_item_more">
|
||||
<a href="livesession-editor-07.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="soon-game-creation-editor-07.html">СКОРО: Создание простой игры в прямом эфире (Редактор 0.7)</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2015-11-02 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p>Как и было обещано, мы готовы предоставить вам Редактор 0.7, с помощью которого можно создать тестовый цех. Тем не менее, после воссоздания цеха стало ясно, что:</p>
|
||||
<ol>
|
||||
<li>это занимает более 8 часов (слишком долго)</li>
|
||||
<li>описание в виде статьи не подходит по формату (слишком скучно)</li>
|
||||
</ol>
|
||||
<p>Поэтому мы решили провести прямую трансляцию на <a title="LiveCoding" href="https://www.livecoding.tv/kornerr">LiveCoding</a> СКОРО, чтобы показать, как создать простую <a title="Whac-a-mole" href="http://google.com/search?q=whac+a+mole">игру типа "поймай крота"</a> с нуля.. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="soon-game-creation-editor-07.html">Читать далее</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="pagination_title">Страница 7 из 8</p>
|
||||
<p class="pagination_title">Страница 7 из 9</p>
|
||||
<p>
|
||||
<a href="index6.html">« Новее</a>
|
||||
<a href="index8.html">Старее »</a>
|
||||
|
||||
@@ -25,6 +25,24 @@
|
||||
<h1>Новости</h1>
|
||||
|
||||
<div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="soon-game-creation-editor-07.html">СКОРО: Создание простой игры в прямом эфире (Редактор 0.7)</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2015-11-02 00:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p>Как и было обещано, мы готовы предоставить вам Редактор 0.7, с помощью которого можно создать тестовый цех. Тем не менее, после воссоздания цеха стало ясно, что:</p>
|
||||
<ol>
|
||||
<li>это занимает более 8 часов (слишком долго)</li>
|
||||
<li>описание в виде статьи не подходит по формату (слишком скучно)</li>
|
||||
</ol>
|
||||
<p>Поэтому мы решили провести прямую трансляцию на <a title="LiveCoding" href="https://www.livecoding.tv/kornerr">LiveCoding</a> СКОРО, чтобы показать, как создать простую <a title="Whac-a-mole" href="http://google.com/search?q=whac+a+mole">игру типа "поймай крота"</a> с нуля.. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="soon-game-creation-editor-07.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="bye-desura-hello-humblebundle.html">Прощай, Desura. Здравствуй, Humble Bundle Widget</a>
|
||||
</h2>
|
||||
@@ -164,26 +182,11 @@
|
||||
<div class="news_item_more">
|
||||
<a href="user-servey-finish-promise.html">Читать далее</a>
|
||||
</div>
|
||||
</div><div class="news_item">
|
||||
<h2 class="news_item_title">
|
||||
<a href="2014-another-year-passed.html">И вот прошел еще один год</a>
|
||||
</h2>
|
||||
<p class="news_item_date">
|
||||
2014-12-31 12:00
|
||||
</p>
|
||||
<div class="news_item_contents">
|
||||
<p>Привет.</p>
|
||||
<p>Подходит к концу год, в течение которого мы разместили на сайте рекордно малое количество новостей. Мы не прекратили разработку, однако пока она находится в фазе "показывать нечего", а свободного времени, которое можно уделять проекту, у каждого из его участников сейчас найдется редко больше чем 30-40 часов в месяц.</p>
|
||||
<p>Но работа продвигается, и подробнее о ней расскажет <a href="exaggerated-expectations.html">статья нашего программиста Михаила Капелько</a>.</p>
|
||||
<p>. . .</p>
|
||||
</div>
|
||||
<div class="news_item_more">
|
||||
<a href="2014-another-year-passed.html">Читать далее</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="pagination_title">Страница 8 из 8</p>
|
||||
<p class="pagination_title">Страница 8 из 9</p>
|
||||
<p>
|
||||
<a href="index7.html">« Новее</a>
|
||||
<a href="index9.html">Старее »</a>
|
||||
</p>
|
||||
|
||||
<div id="footer">
|
||||
|
||||
Reference in New Issue
Block a user