Розыгрыш багов на Альфу 1.1.0
Кто найдет -тому 10 лет условно 💀
Успей получить свой долгожданный отпуск!
GameJolt: тык
Кто найдет -
Успей получить свой долгожданный отпуск!
GameJolt: тык
❤3🤩2❤🔥1😭1😎1
Искусство Построения Архитектуры Проекта
Глава 5: inline-функции и правило одной реализации
Данная глава будет маленькой, но крайне полезной. Основной вопрос: Можно ли реализовывать функции в .h файле?
Ответ: Да, но с оговорками
Вы сделали это:
Что тогда? Ну... Во-первых компилятор вам банально не даст этого сделать - сработает намеренная защита. Представьте, что вы подключите этот Test.h файл в нескольких .cpp файлах -> Препроцессор раскроет #include "Test.h" -> В нескольких .cpp файлах будет int Add(...) {...} (прошу заметить - с реализацией!) - и когда линкер начнет сшивать .obj файлы вместе, то в каждом из них будет объявлена и реализована функция Add, и вопрос: Какую реализацию ему выбрать? Вот именно...
Так что нам придумали одно правило: Правило Одного Определения (ODR - One Definition Rule)
"А если я хочу намеренно реализовать функцию в .h файле?" - Для нас дядя Бьёрн позаботился и придумал пометку inline - это пометка компилятору, которая говорит: вставь код функции напрямую в место её вызова вместо выполнения традиционного вызова. То есть:
Что это дает? При компиляции, эта функция по факту не будет создана, а ее машинный код будет вшит в тех местах, где она вызывается. То есть это такой "своеобразный #include для функций". И главное: при той же линковке, функция Add по факту не будет создана, а значит не будет проблем с ODR
И главный вопрос: какие плюсы-минусы у этого? - Безусловно это меньше беготни процессору. Серьезно, если он меньше бегает между функциями, то это имеет оптимизирующий эффект. Вместо того, чтобы вызвать функцию и ждать ее ответа, он сразу здесь и сейчас исполняет ее.
Но и у этого есть оттягивающий эффект: Я не зря сравнил inline с #include - ибо он также имеет накопительный эффект: Чем больше функций будут раскрываться - тем крупнее будет бинарник. А также учтите ещё размер функции, и получите охерительно жирный бинарник и несколько часов компиляции. Бинго!
В любом случае, как и говорилось ранее, главное разобраться в этой теме и сделать выводы. Я не говорю не использовать эту механику. Наоборот, даже в своем проекте Portal: Solver у меня есть отдельный файл утилит (PortalSolverUtilities.h) в которых реализованы небольшие inline функции-помощники и используются при необходимости. Но реализовывать целый движок в единственном .h... Мда... Надеюсь теперь вы понимаете цену своих действий
ODR Looks Like Error - But It's Just Protection From Chaos. Think Cold.
Глава 5: inline-функции и правило одной реализации
Данная глава будет маленькой, но крайне полезной. Основной вопрос: Можно ли реализовывать функции в .h файле?
Ответ: Да, но с оговорками
Вы сделали это:
// Test.h
#pragma once
int Add(int a, int b) {
return a + b;
}
Что тогда? Ну... Во-первых компилятор вам банально не даст этого сделать - сработает намеренная защита. Представьте, что вы подключите этот Test.h файл в нескольких .cpp файлах -> Препроцессор раскроет #include "Test.h" -> В нескольких .cpp файлах будет int Add(...) {...} (прошу заметить - с реализацией!) - и когда линкер начнет сшивать .obj файлы вместе, то в каждом из них будет объявлена и реализована функция Add, и вопрос: Какую реализацию ему выбрать? Вот именно...
Так что нам придумали одно правило: Правило Одного Определения (ODR - One Definition Rule)
"А если я хочу намеренно реализовать функцию в .h файле?" - Для нас дядя Бьёрн позаботился и придумал пометку inline - это пометка компилятору, которая говорит: вставь код функции напрямую в место её вызова вместо выполнения традиционного вызова. То есть:
// Test.h
#pragma once
inline int Add(int a, int b) {
return a + b;
}
Что это дает? При компиляции, эта функция по факту не будет создана, а ее машинный код будет вшит в тех местах, где она вызывается. То есть это такой "своеобразный #include для функций". И главное: при той же линковке, функция Add по факту не будет создана, а значит не будет проблем с ODR
И главный вопрос: какие плюсы-минусы у этого? - Безусловно это меньше беготни процессору. Серьезно, если он меньше бегает между функциями, то это имеет оптимизирующий эффект. Вместо того, чтобы вызвать функцию и ждать ее ответа, он сразу здесь и сейчас исполняет ее.
Но и у этого есть оттягивающий эффект: Я не зря сравнил inline с #include - ибо он также имеет накопительный эффект: Чем больше функций будут раскрываться - тем крупнее будет бинарник. А также учтите ещё размер функции, и получите охерительно жирный бинарник и несколько часов компиляции. Бинго!
В любом случае, как и говорилось ранее, главное разобраться в этой теме и сделать выводы. Я не говорю не использовать эту механику. Наоборот, даже в своем проекте Portal: Solver у меня есть отдельный файл утилит (PortalSolverUtilities.h) в которых реализованы небольшие inline функции-помощники и используются при необходимости. Но реализовывать целый движок в единственном .h... Мда... Надеюсь теперь вы понимаете цену своих действий
ODR Looks Like Error - But It's Just Protection From Chaos. Think Cold.
🔥4❤🔥1
Есть еще главы, но, что вы хотите услышать первее?
Final Results
90%
Работа с enum - Удобная замена чисел на слова = читаемость (+ небольшие хаки от меня)
40%
Пространство имен (namespace) - Как инструмент для разделения и читаемости кода
40%
Разделение ответственности - Фундаментальный принцип в проектировании архитектуры
❤1❤🔥1🤩1
Portal: Solver с открытым исходным кодом?!
ДА! Вы не ослышались - Portal Solver теперь open-source!
Но чтобы вы меньше тратили время на билд проекта (почти 1.5к ассетов, я не шучу 💀)
Я решил скомпилировать все за вас! Так что успейте опробовать скомпилированные исходники Портал Солвера БЕСПЛАТНО!
Ссылочка: тык
ДА! Вы не ослышались - Portal Solver теперь open-source!
Но чтобы вы меньше тратили время на билд проекта (почти 1.5к ассетов, я не шучу 💀)
Я решил скомпилировать все за вас! Так что успейте опробовать скомпилированные исходники Портал Солвера БЕСПЛАТНО!
Ссылочка: тык
🤩3👀1
𝐑𝐨𝐨𝐭𝐓𝐨𝐨𝐥 𝐁𝐥𝐨𝐠
Искусство Построения Архитектуры Проекта Глава 4: "Квантовая запутанность" классов и "теория большого #includ'а" Вспомним: - Глава 2 - #include "Path/File.h" - открывает файл по пути и жестко заменяет себя на его содержимое - Глава 3 - Forward Declaration…
Forward Declaration на реальном примере
Как всегда работал (да.. в 2:25 ночи) и встретил распространенную/привычную проблему - в одной структуре я ссылаюсь (упоминаю) другую структуру, что находится чуть ниже
Что делать? Forward Declaration!
вот так примеры с учебника реально встречаются на работе))
Don’t Just Learn - Understand It. Think Cold
Как всегда работал (да.. в 2:25 ночи) и встретил распространенную/привычную проблему - в одной структуре я ссылаюсь (упоминаю) другую структуру, что находится чуть ниже
Что делать? Forward Declaration!
вот так примеры с учебника реально встречаются на работе))
Don’t Just Learn - Understand It. Think Cold
❤3👍1🔥1
Что ж, взял себе наконец-таки новый (второй) блокнот для Portal: Solver
А что с первым? А первый я взял ещё в прошлом году, когда только Альфа начиналась...
И сейчас он весь исписан расчётами, концептами камер, архитектур кода, систем/подсистем, и вообще темный лес☠️
Теперь, как говорится, начнем с чистого листа
А что с первым? А первый я взял ещё в прошлом году, когда только Альфа начиналась...
И сейчас он весь исписан расчётами, концептами камер, архитектур кода, систем/подсистем, и вообще темный лес☠️
Теперь, как говорится, начнем с чистого листа
❤2💯2🔥1
Искусство Построения Архитектуры Проекта
Глава 6: Enumerating the world!
Enum, enum, енум... что такое этот ваш enum? По сути - более красивая замена чисел на понятные слова.
Его синтаксис прост до безобразия:
Что можно сразу выделить:
- EnumName - название нашего перечисления
- EnumType - тип перечисления. По дефолту это int, но могут быть любые другие целочисленные типы (поговорим чуть позже)
Теперь можно обращаться к перечислению как: if(EnumName::A == EnumName::B);, или, EnumName MyEnumVar = EnumName::A;
Прикольно, да? Но что находится под enum? При компиляции компилятор просто идёт по элементам сверху вниз. Если значение у элемента не указано - берёт значение предыдущего и прибавляет к нему +1 (И да, по умолчанию первый элемент равен 0) То есть:
Но каков предел и размерность значений? А вот именно тут ключевую роль играет EnumType (по умолчанию - int). Но можно, например, enum class EnumName : uint8_t - 8 битное целое число без знака (от 0 до 255)
Но плюсы на то плюсы, что их гибкость позволяет задавать элементам любые значения. Разберем конкретный кейс:
И теперь при компиляции, код OK примет значение 200, NotFound - 404, а Something (как мы сказали выше) будет равен 405, так как компилятор даст ему значение относительно значения предыдущего элемента, да +1 (404 + 1 = 405)
А благодаря удобству enum, теперь мы можем создавать функции ECode GetCode(); и возвращать значения с помощью return ECode::OK; - удобно? Ещё как! И это одна из причин, почему enum активно используют в архитектуре
Да, конечно вышло суховато... но примите базу. В следующей главе более откровенно поговорим про хитрости использования enum
Enumerate The World. Think Cold.
Глава 6: Enumerating the world!
Enum, enum, енум... что такое этот ваш enum? По сути - более красивая замена чисел на понятные слова.
Его синтаксис прост до безобразия:
enum class EnumName : EnumType
{
A, B, C
};
Что можно сразу выделить:
- EnumName - название нашего перечисления
- EnumType - тип перечисления. По дефолту это int, но могут быть любые другие целочисленные типы (поговорим чуть позже)
Теперь можно обращаться к перечислению как: if(EnumName::A == EnumName::B);, или, EnumName MyEnumVar = EnumName::A;
Прикольно, да? Но что находится под enum? При компиляции компилятор просто идёт по элементам сверху вниз. Если значение у элемента не указано - берёт значение предыдущего и прибавляет к нему +1 (И да, по умолчанию первый элемент равен 0) То есть:
enum class EnumName : EnumType
{
// Начинаем счет с нуля
A, // 0
B, // 1
C // 2
};
Но каков предел и размерность значений? А вот именно тут ключевую роль играет EnumType (по умолчанию - int). Но можно, например, enum class EnumName : uint8_t - 8 битное целое число без знака (от 0 до 255)
Но плюсы на то плюсы, что их гибкость позволяет задавать элементам любые значения. Разберем конкретный кейс:
enum class ECode // int
{
OK = 200,
NotFound = 404,
Something // 405
};
И теперь при компиляции, код OK примет значение 200, NotFound - 404, а Something (как мы сказали выше) будет равен 405, так как компилятор даст ему значение относительно значения предыдущего элемента, да +1 (404 + 1 = 405)
А благодаря удобству enum, теперь мы можем создавать функции ECode GetCode(); и возвращать значения с помощью return ECode::OK; - удобно? Ещё как! И это одна из причин, почему enum активно используют в архитектуре
Да, конечно вышло суховато... но примите базу. В следующей главе более откровенно поговорим про хитрости использования enum
Enumerate The World. Think Cold.
❤4❤🔥1💯1
C++ - самый, сука, константный язык
Глядите, у нас есть базовый пример:
^ Указатель на x
Можно менять указатель
Можно менять значение
^ Указатель на константное значение
Можно менять указатель
Нельзя менять значение
^ Константный указатель на значение
Нельзя менять указатель
Можно менять значение
Что ж.. а теперь барабанная дробь:
^ Константный указатель на константное значение
Нельзя менять указатель
Нельзя менять значение
Но тише, тише, это только начало:
^ Указатель на константный указатель на значение
Можно менять указатель
Нельзя менять значение указателя p
Можно менять само значение x (через
^ Константный указатель на константный указатель на константное значение
Нельзя менять указатель
Нельзя менять значение указателя p
Нельзя менять само значение x
Ладно, хватит! Я еще не стал душнить про
указатель на указатель на константный указатель на константный указатель на x
C++ штука такая. Живите с этим :)
Глядите, у нас есть базовый пример:
int x = 5;
int* px = &x;
^ Указатель на x
Можно менять указатель
Можно менять значение
const int* px = &x;
^ Указатель на константное значение
Можно менять указатель
Нельзя менять значение
int* const px = &x;
^ Константный указатель на значение
Нельзя менять указатель
Можно менять значение
Что ж.. а теперь барабанная дробь:
const int* const px = &x;
^ Константный указатель на константное значение
Нельзя менять указатель
Нельзя менять значение
Но тише, тише, это только начало:
int* const* ppx = &px;
^ Указатель на константный указатель на значение
Можно менять указатель
Нельзя менять значение указателя p
Можно менять само значение x (через
**ppx)const int* const* ppx = &px;
^ Константный указатель на константный указатель на константное значение
Нельзя менять указатель
Нельзя менять значение указателя p
Нельзя менять само значение x
Ладно, хватит! Я еще не стал душнить про
int* const* const** ppppx....указатель на указатель на константный указатель на константный указатель на x
C++ штука такая. Живите с этим :)
❤4👀1
this->CelebrateBirthday();
//TODO: :tada effect
И вот.. Подходит мой8-й год в С++ 17-й год жизни, и знаете? Я счастлив что встретил вас всех, с кем остались, а с кем, конечно, разошлись
И правда, еще 2 года назад, до начала Portal: Solver и всего этого я думал что к 16-17 годам буду как те самые подростки на вписках - алкоголь, курение и всякое подобное. Считал что моя жизнь увязнет в этом, но....
Сейчас проект, цель, будущее - и правда, это не произошло бы без всех вас.
Безусловно в общей картине влияние каждого - как капля в море, но именно существование этого, как кирпичик за кирпичиком, объединило всех нас здесь, в этом скромном, но теплом, окружении. И без вас - этот день не был бы таким приятным ;)
Спасибо
//TODO: :tada effect
И вот.. Подходит мой
И правда, еще 2 года назад, до начала Portal: Solver и всего этого я думал что к 16-17 годам буду как те самые подростки на вписках - алкоголь, курение и всякое подобное. Считал что моя жизнь увязнет в этом, но....
Сейчас проект, цель, будущее - и правда, это не произошло бы без всех вас.
Безусловно в общей картине влияние каждого - как капля в море, но именно существование этого, как кирпичик за кирпичиком, объединило всех нас здесь, в этом скромном, но теплом, окружении. И без вас - этот день не был бы таким приятным ;)
Спасибо
❤5🎉3