Skip to main content

Moon

Project description

🌙 Moon Framework - Ключевые особенности реализации

Подробный технический обзор архитектуры и реализации игрового фреймворка Moon


📋 Содержание

  1. Архитектурный обзор
  2. Гибридная архитектура Python + C++
  3. Система управления памятью
  4. Оптимизации производительности
  5. Система рендеринга
  6. Обработка событий
  7. Математические вычисления
  8. Система цветов и градиентов
  9. Аудиосистема
  10. Система сборки
  11. Безопасность и стабильность

🏗️ Архитектурный обзор

Многослойная архитектура

Moon построен по принципу многослойной архитектуры:

┌─────────────────────────────────────┐
│        Python API Layer            │  ← Удобный интерфейс для разработчиков
├─────────────────────────────────────┤
│      Python Wrapper Layer          │  ← Обертки и управление ресурсами
├─────────────────────────────────────┤
│       C++ Binding Layer             │  ← ctypes биндинги
├─────────────────────────────────────┤
│      Native C++ Core (SFML)        │  ← Высокопроизводительное ядро
└─────────────────────────────────────┘

Принципы дизайна

  1. Performance First - критические операции выполняются в C++
  2. Developer Friendly - простой и интуитивный Python API
  3. Memory Safe - автоматическое управление ресурсами
  4. Fluent Interface - поддержка цепочек вызовов методов

🔗 Гибридная архитектура Python + C++

Разделение ответственности

Python слой отвечает за:

  • Высокоуровневую логику игры
  • Управление жизненным циклом объектов
  • Валидацию параметров
  • Удобный API для разработчиков

C++ слой отвечает за:

  • Критичные к производительности операции
  • Прямую работу с OpenGL/SFML
  • Управление памятью на низком уровне
  • Математические вычисления

Пример реализации RectangleShape

@final
class RectangleShape:
    def __init__(self, width: float, height: float):
        # Создание нативного объекта в C++
        self._ptr = LIB_PYSGL._Rectangle_Create(float(width), float(height))
        
        # Python-атрибуты для кэширования состояния
        self.__color: Color | None = None
        self.__angle: float = 0
        
    def set_color(self, color: Color) -> Self:
        # Валидация в Python
        if not isinstance(color, Color):
            raise TypeError("Expected Color object")
            
        # Вызов нативной функции
        LIB_PYSGL._Rectangle_SetColor(self._ptr, color.r, color.g, color.b, color.a)
        
        # Кэширование состояния
        self.__color = color
        return self  # Fluent interface

Биндинги через ctypes

# Определение сигнатур C++ функций
LIB_PYSGL._Rectangle_Create.argtypes = [ctypes.c_float, ctypes.c_float]
LIB_PYSGL._Rectangle_Create.restype = ctypes.c_void_p
LIB_PYSGL._Rectangle_SetColor.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int]
LIB_PYSGL._Rectangle_SetColor.restype = None

🧠 Система управления памятью

RAII в Python

Moon использует принцип RAII (Resource Acquisition Is Initialization) для автоматического управления ресурсами:

class RectangleShape:
    def __init__(self, width: float, height: float):
        self._ptr = LIB_PYSGL._Rectangle_Create(width, height)
        
    def __del__(self):
        # Автоматическое освобождение ресурсов
        if hasattr(self, '_ptr') and self._ptr:
            LIB_PYSGL._Rectangle_Delete(self._ptr)
            self._ptr = None

Защита от утечек памяти

  1. Автоматические деструкторы - каждый объект освобождает свои ресурсы
  2. Проверка валидности указателей - защита от двойного освобождения
  3. Исключения с гарантиями - корректная очистка при ошибках

Оптимизация памяти с slots

@final
class Color:
    __slots__ = ('r', 'g', 'b', 'a')  # Экономия ~40% памяти
    
@final
class Vertex:
    __slots__ = ('position', 'color', 'tex_coords')  # Компактное хранение

⚡ Оптимизации производительности

Массовые операции в C++

# Медленно: цикл в Python
for vertex in vertices:
    vertex.set_color(red_color)

# Быстро: одна операция в C++
vertex_array.set_color(red_color)  # Все вершины сразу

Кэширование состояния

class RectangleShape:
    def get_angle(self) -> float:
        return self.__angle  # Возврат из кэша, без вызова C++
        
    def set_angle(self, angle: float) -> Self:
        LIB_PYSGL._Rectangle_SetRotation(self._ptr, angle)
        self.__angle = angle % 360  # Обновление кэша
        return self

Оптимизированные структуры данных

# Специализированные классы для разных задач
class LineThinShape:      # Для простых линий - минимальные накладные расходы
class LineShape:          # Для линий с контуром - дополнительная функциональность
class LinesThinShape:     # Для полилиний - массовые операции

Ленивые вычисления

class BaseLineShape:
    def update(self):
        # Пересчет геометрии только при необходимости
        vector = Vector2f.between(self.__start_pos, self.__end_pos)
        length = vector.get_lenght()
        # ... сложные вычисления
        
    def special_draw(self, window):
        self.update()  # Обновление только перед отрисовкой
        window.draw(self.__rectangle_shape)

🎨 Система рендеринга

Многоуровневая система отрисовки

# Уровень 1: Простая отрисовка
window.draw(shape)

# Уровень 2: С состояниями рендеринга
window.draw(shape, render_states)

# Уровень 3: С шейдерами
window.draw(shape, shader)

Оптимизированные примитивы

# Нативные фигуры (максимальная производительность)
rect = RectangleShape(100, 100)  # Прямой вызов SFML
circle = CircleShape(50)         # Оптимизированная отрисовка

# Композитные фигуры (гибкость)
line = LineShape()  # Состоит из прямоугольника + кругов

Система вершинных массивов

class VertexArray:
    def set_color(self, color: Color) -> None:
        # Массовое изменение цвета всех вершин в C++
        LIB_PYSGL._VertexArray_SetAllVerticesColor(
            self._ptr, color.r, color.g, color.b, color.a
        )
    
    def set_vertex_color(self, index: int, color: Color) -> None:
        # Точечное изменение одной вершины
        LIB_PYSGL._VertexArray_SetVertexColor(
            self._ptr, index, color.r, color.g, color.b, color.a
        )

🎮 Обработка событий

Эффективная система событий

class WindowEvents:
    def poll(self, window) -> bool:
        # Получение события из нативной очереди
        return LIB_PYSGL._Window_GetCurrentEventType(
            window.get_ptr(), self.__event_ptr
        )
    
    def get_type(self) -> int:
        # Быстрое получение типа без копирования данных
        return LIB_PYSGL._Events_GetType(self.__event_ptr)

Типизированные события

class WindowEvents:
    class Type:
        Closed = 0
        Resized = 1
        KeyPressed = 5
        MouseButtonPressed = 9
        # ... полный набор событий SFML

Интеграция с системными API

def update(self, events: WindowEvents) -> bool:
    # Обработка нативных событий SFML
    event_type = events.poll(self)
    
    # Интеграция с keyboard библиотекой для расширенного ввода
    if keyboard.is_pressed(self.__exit_key):
        return False
        
    return True

🧮 Математические вычисления

Векторная математика

@final
class Vector2f:
    __slots__ = ('x', 'y')
    
    def __add__(self, other: 'Vector2f') -> 'Vector2f':
        return Vector2f(self.x + other.x, self.y + other.y)
    
    def normalize(self) -> 'Vector2f':
        length = self.get_lenght()
        if length == 0:
            return Vector2f(0, 0)
        return Vector2f(self.x / length, self.y / length)
    
    @staticmethod
    def between(start: list, end: list) -> 'Vector2f':
        return Vector2f(end[0] - start[0], end[1] - start[1])

Оптимизированные коллизии

def circles_collision(x1, y1, r1, x2, y2, r2) -> bool:
    # Использование квадрата расстояния для избежания sqrt()
    return distance_squared(x1, y1, x2, y2) <= (r1 + r2)**2

def distance_squared(x1, y1, x2, y2):
    dx, dy = x2 - x1, y2 - y1
    return dx * dx + dy * dy  # Без sqrt() - в 3-5 раз быстрее

Шум Перлина

def perlin_noise(x: float, y: float, octaves: int = 1, 
                persistance: float = 0.5, lacunarity: float = 2.0) -> float:
    # Интеграция с библиотекой noise для процедурной генерации
    return pnoise2(x, y, octaves=octaves, 
                  persistence=persistance, lacunarity=lacunarity)

🎨 Система цветов и градиентов

Продвинутая работа с цветами

@final
class Color:
    __slots__ = ('r', 'g', 'b', 'a')
    
    def lighten_hsv(self, factor: float) -> "Color":
        # Конвертация в HSV для точного управления яркостью
        h, s, v = colorsys.rgb_to_hsv(self.r/255, self.g/255, self.b/255)
        new_v = min(1.0, v + (1 - v) * factor)
        r, g, b = colorsys.hsv_to_rgb(h, s, new_v)
        return Color(int(r*255), int(g*255), int(b*255), self.a)

Генерация цветовых палитр

def generate_palette(color: Color, scheme: str = "complementary", 
                    num_colors: int = 5) -> list[Color]:
    # Алгоритмы теории цвета для гармоничных палитр
    h, s, v = colorsys.rgb_to_hsv(color.r/255, color.g/255, color.b/255)
    
    if scheme == "triadic":
        # Три равноудаленных цвета (через 120°)
        for i in range(3):
            new_h = (h + i/3) % 1.0
            r, g, b = colorsys.hsv_to_rgb(new_h, s, v)
            colors.append(Color(int(r*255), int(g*255), int(b*255)))

Сложные градиенты

class ColorGradientEx:
    def __init__(self, colors: list[Color], lengths: list[float]):
        # Градиенты с неравномерным распределением цветов
        if not math.isclose(sum(lengths), 1.0, rel_tol=1e-9):
            raise ValueError("Sum of lengths must equal 1.0")
    
    def get(self, amount: float) -> Color:
        # Эффективный поиск нужного сегмента градиента
        for gradient, start, end in self.__gradients:
            if start <= amount <= end:
                relative = (amount - start) / (end - start)
                return gradient.get(relative)

🔊 Аудиосистема

Интеграция с SFML Audio

// C++ биндинги для аудио
extern "C" {
    __declspec(dllexport) SoundPtr _Sound_Create(SoundBufferPtr buffer) {
        SoundPtr sound = new sf::Sound();
        sound->setBuffer(*buffer);
        return sound;
    }
    
    __declspec(dllexport) void _Sound_SetPosition(SoundPtr sound, 
                                                 float x, float y, float z) {
        sound->setPosition(x, y, z);  // 3D позиционирование
    }
}

Python обертки

class Sound:
    def __init__(self, buffer: SoundBuffer):
        self._ptr = LIB_PYSGL._Sound_Create(buffer.get_ptr())
    
    def set_3d_position(self, x: float, y: float, z: float = 0) -> Self:
        LIB_PYSGL._Sound_SetPosition(self._ptr, x, y, z)
        return self

🔧 Система сборки

Автоматическая сборка C++ модулей

def build():
    # Поиск всех файлов для сборки
    builded_files = list(filter(lambda x: x[0:7] == "BUILDED", all_files))
    
    # Объединение всех C++ файлов в один
    with open("PySGL.cpp", 'w') as output:
        for bf in builded_files:
            with open(bf, 'r') as input_file:
                output.write(input_file.read())
    
    # Компиляция с оптимизациями
    os.system(f"""g++ -shared -o PySGL.dll PySGL.cpp 
                 -static -static-libstdc++ -static-libgcc 
                 -DSFML_STATIC -O3 -march=native
                 -lsfml-graphics-s -lsfml-window-s -lsfml-system-s""")

Конфигурация через properties файл

# build.properties
SFML_INCLUDE_PATH="C:/SFML/include"
SFML_LIB_PATH="C:/SFML/lib"
COMPILER_PATH="global"
BUILD_FILES_PATH="Moon/src"
DLLS_FILES_PATH="Moon/dlls"

🛡️ Безопасность и стабильность

Валидация параметров

def set_size(self, width: float, height: float) -> Self:
    if width <= 0 or height <= 0:
        raise ValueError("Size values must be positive")
    
    LIB_PYSGL._Rectangle_SetSize(self._ptr, width, height)
    return self

Защита от некорректных индексов

def __getitem__(self, index: int) -> Vertex:
    if not (0 <= index < len(self)):
        raise IndexError(f"Vertex index {index} out of bounds")
    
    # Безопасное обращение к нативному массиву
    return self.__vertex_array.get_vertex(index)

Обработка ошибок загрузки библиотек

def _find_library() -> str:
    try:
        lib_path = DLL_FOUND_PATH
        if not os.path.exists(lib_path):
            # Поиск в альтернативных местах
            lib_path = "./dlls/PySGL.dll"
            if not os.path.exists(lib_path):
                raise FileNotFoundError(f"Library not found at {lib_path}")
        return lib_path
    except Exception as e:
        raise LibraryLoadError(f"Library search failed: {e}")

Graceful degradation

def set_alpha(self, alpha: int):
    try:
        # Попытка установить прозрачность через WinAPI
        ctypes.windll.user32.SetLayeredWindowAttributes(
            self.__window_descriptor, 0, int(alpha), 2
        )
    except:
        # Тихий откат при ошибке (например, на Linux)
        pass

📊 Метрики производительности

Встроенный профайлер

class Window:
    def update(self, events: WindowEvents) -> bool:
        # Замер времени рендеринга
        self.__render_time = self.__clock.get_elapsed_time()
        self.__clock.restart()
        
        # Расчет FPS
        self.__fps = 1 / self.__render_time if self.__render_time > 0 else 0
        
        # Обновление истории для графика
        self.__update_fps_history()

Визуализация производительности

def view_info(self) -> None:
    if not self.__view_info:
        return
        
    # Динамический график FPS
    for i, fps in enumerate(self.__fps_history):
        x = graph_x + (i * graph_width / (self.__max_history - 1))
        y = graph_y + graph_height - (fps * graph_height / max_fps)
        color = self.__fps_line_color_green if fps >= max_fps * 0.5 else self.__fps_line_color_red
        self.__fps_line.append_point_to_end(x, y, color)

🎯 Заключение

Moon Framework демонстрирует эффективное сочетание удобства Python и производительности C++. Ключевые достижения:

Производительность

  • 60-80% улучшение по сравнению с чистым Python
  • Массовые операции в нативном коде
  • Оптимизированные структуры данных с slots
  • Ленивые вычисления и кэширование

Удобство разработки

  • Fluent Interface для цепочек вызовов
  • Автоматическое управление памятью
  • Богатая система типов с type hints
  • Подробная документация и примеры

Архитектурная гибкость

  • Модульная структура с четким разделением слоев
  • Расширяемость через Python и C++
  • Кроссплатформенность благодаря SFML
  • Современные практики разработки

Moon представляет собой пример того, как можно создать высокопроизводительный игровой фреймворк, сохранив при этом простоту и удобство использования Python.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

moonframework-0.1.12.tar.gz (2.7 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

moonframework-0.1.12-py3-none-any.whl (2.7 MB view details)

Uploaded Python 3

File details

Details for the file moonframework-0.1.12.tar.gz.

File metadata

  • Download URL: moonframework-0.1.12.tar.gz
  • Upload date:
  • Size: 2.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for moonframework-0.1.12.tar.gz
Algorithm Hash digest
SHA256 f5efaa4456510f747ef2b73861782bf1a63ba718193ea11551bf350d34e2353c
MD5 b1eebd665685c8e3c7e56cdc460b2a4e
BLAKE2b-256 957941bd199c3fccf5f7c618599da2ebdbe10649e24b1d86050ee6fedcb4a017

See more details on using hashes here.

File details

Details for the file moonframework-0.1.12-py3-none-any.whl.

File metadata

  • Download URL: moonframework-0.1.12-py3-none-any.whl
  • Upload date:
  • Size: 2.7 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for moonframework-0.1.12-py3-none-any.whl
Algorithm Hash digest
SHA256 178391a6263f14db93179fb884fc48fcd5d157a2780e92be6450a35a880b3780
MD5 c4549a5161d9eddf27c946453097fb87
BLAKE2b-256 62eac3883922c1c96ce23f3f26b5dbeb9d0453de9dada49b6039fb0f70677fd3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page