From 19da3c7d8ed832bc06275d8a306d4a1610d23861 Mon Sep 17 00:00:00 2001 From: rus07tam Date: Sun, 26 Oct 2025 17:42:11 +0000 Subject: [PATCH] docs: refactor README --- README.md | 680 +++--------------------------------------------------- 1 file changed, 32 insertions(+), 648 deletions(-) diff --git a/README.md b/README.md index a2a7a91..670c288 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,41 @@ +
+ # 🐍 Snakia Framework +![Code Quality](https://img.shields.io/codacy/grade/s) +![Code Size](https://img.shields.io/github/languages/code-size/ruject/snakia) +![License](https://img.shields.io/github/license/ruject/snakia) +![Open Issues](https://img.shields.io/github/issues-raw/ruject/snakia) +![Commit Activity](https://img.shields.io/github/commit-activity/m/ruject/snakia) + +[API Reference](https://ruject.github.io/snakia/) + •  +[Telegram Chat](https://t.me/RuJect_Community) + +
+ **Snakia** is a modern Python framework for creating applications with Entity-Component-System (ECS) architecture, event system, and reactive programming. Built with performance (maybe) and modularity in mind, Snakia provides a clean API for developing complex applications ranging from games to terminal user interfaces. ## 📋 Table of Contents -- [🎯 Roadmap & TODO](#-roadmap--todo) -- [🚀 Installation](#-installation) -- [🚀 Quick Start](#-quick-start) -- [🏗️ Architecture](#️-architecture) -- [⚙️ Core](#️-core) -- [🎯 ECS System](#-ecs-system) -- [📡 Event System (ES)](#-event-system-es) -- [🔌 Plugin System](#-plugin-system) -- [🎨 TUI System](#-tui-system) -- [⚡ Reactive Programming (RX)](#-reactive-programming-rx) -- [🛠️ Utilities](#️-utilities) -- [🎭 Decorators](#-decorators) -- [🏷️ Properties](#-properties) -- [🌐 Platform Abstraction](#-platform-abstraction) -- [📦 Examples](#-examples) -- [🤝 Contributing](#-contributing) -- [🆘 Support](#-support) -- [📄 License](#-license) +- [🐍 Snakia Framework](#-snakia-framework) + - [📋 Table of Contents](#-table-of-contents) + - [✨ Key Features](#-key-features) + - [🚀 Installation](#-installation) + - [Prerequisites](#prerequisites) + - [Install from PyPi (recommended)](#install-from-pypi-recommended) + - [Install from Source](#install-from-source) + - [🎯 Roadmap \& TODO](#-roadmap--todo) + - [🚀 Quick Start](#-quick-start) + - [🏗️ Architecture](#️-architecture) + - [📦 Examples](#-examples) + - [Health System](#health-system) + - [TUI Application](#tui-application) + - [🤝 Contributing](#-contributing) + - [How to Contribute](#how-to-contribute) + - [Development Guidelines](#development-guidelines) -### ✨ Key Features +## ✨ Key Features - 🏗️ **ECS Architecture** - Flexible entity-component-system for scalable game/app logic - 📡 **Event System** - Asynchronous event handling with filters and priorities @@ -52,15 +64,9 @@ pip install snakia ### Install from Source ```bash -# Clone the repository git clone https://github.com/RuJect/Snakia.git cd Snakia - -# Install with pip pip install -e . - -# Or with uv (recommended) -uv sync ``` ## 🎯 Roadmap & TODO @@ -133,616 +139,6 @@ Snakia/ └── types/ # Special types ``` -## ⚙️ Core - -### Engine - -The central component of the framework that coordinates all systems: - -```python -from snakia.core.engine import Engine - -engine = Engine() -# Systems: -# - engine.system - ECS system -# - engine.dispatcher - Event system -# - engine.loader - Plugin loader - -engine.start() # Start all systems -engine.stop() # Stop all systems -engine.update() # Update systems -``` - -## 🎯 ECS System - -Entity-Component-System architecture for creating flexible and performant applications. - -### Component - -Base class for all components: - -```python -from snakia.core.ecs import Component -from pydantic import Field - -class PositionComponent(Component): - x: float = Field(default=0.0) - y: float = Field(default=0.0) - -class VelocityComponent(Component): - vx: float = Field(default=0.0) - vy: float = Field(default=0.0) -``` - -### Processor - -Processors handle components in the system: - -```python -from snakia.core.ecs import Processor, System - -class MovementProcessor(Processor): - def process(self, system: System) -> None: - # Get all entities with Position and Velocity - for entity, (pos, vel) in system.get_components( - PositionComponent, VelocityComponent - ): - pos.x += vel.vx - pos.y += vel.vy -``` - -### System - -Entity and component management: - -```python -# Creating an entity with components -entity = system.create_entity( - PositionComponent(x=10, y=20), - VelocityComponent(vx=1, vy=0) -) - -# Adding a component to an existing entity -system.add_component(entity, HealthComponent(value=100)) - -# Getting entity components -pos, vel = system.get_components_of_entity( - entity, PositionComponent, VelocityComponent -) - -# Checking for components -if system.has_components(entity, PositionComponent, VelocityComponent): - print("Entity has position and velocity") - -# Removing a component -system.remove_component(entity, VelocityComponent) - -# Deleting an entity -system.delete_entity(entity) -``` - -## 📡 Event System (ES) - -Asynchronous event system with filter and priority support. - -### Event - -Base class for events: - -```python -from snakia.core.es import Event -from pydantic import Field - -class PlayerDiedEvent(Event): - player_id: int = Field() - cause: str = Field(default="unknown") - ttl: int = Field(default=10) # Event lifetime -``` - -### Handler - -Event handlers: - -```python -from snakia.core.es import Handler, Action - -def on_player_died(event: PlayerDiedEvent) -> Action | None: - print(f"Player {event.player_id} died from {event.cause}") - return Action.move(1) # Move to next handler -``` - -### Filter - -Event filters: - -```python -from snakia.core.es import Filter - -def only_important_deaths(event: PlayerDiedEvent) -> bool: - return event.cause in ["boss", "pvp"] - -# Using a filter -@dispatcher.on(PlayerDiedEvent, filter=only_important_deaths) -def handle_important_death(event: PlayerDiedEvent): - print("Important death occurred!") -``` - -### Dispatcher - -Central event dispatcher: - -```python -from snakia.core.es import Dispatcher, Subscriber - -dispatcher = Dispatcher() - -# Subscribing to an event -dispatcher.subscribe(PlayerDiedEvent, Subscriber( - handler=on_player_died, - filter=only_important_deaths, - priority=10 -)) - -# Decorator for subscription -@dispatcher.on(PlayerDiedEvent, priority=5) -def handle_death(event: PlayerDiedEvent): - print("Death handled!") - -# Publishing an event -dispatcher.publish(PlayerDiedEvent(player_id=123, cause="boss")) -``` - -## 🔌 Plugin System - -Modular system for loading and managing plugins. - -### Plugin - -Base class for plugins: - -```python -from snakia.core.loader import Meta, Plugin, PluginProcessor -from snakia.types import Version - -class MyProcessor(PluginProcessor): - def process(self, system): - # Processor logic - pass - -class MyPlugin(Plugin, meta=Meta( - name="my_plugin", - author="developer", - version=Version.from_args(1, 0, 0), - processors=(MyProcessor,), - subscribers=() -)): - def on_load(self): - print("Plugin loaded!") - - def on_unload(self): - print("Plugin unloaded!") -``` - -### Meta - -Plugin metadata: - -```python -from snakia.core.loader import Meta -from snakia.core.es import Subscriber - -meta = Meta( - name="plugin_name", - author="author_name", - version=Version.from_args(1, 0, 0), - processors=(Processor1, Processor2), - subscribers=( - (EventType, Subscriber(handler, filter, priority)), - ) -) -``` - -### Loader - -Plugin loader: - -```python -from snakia.core.loader import Loader - -loader = Loader(engine) - -# Registering a plugin -loader.register(MyPlugin) - -# Loading all plugins -loader.load_all() - -# Unloading all plugins -loader.unload_all() -``` - -## 🎨 TUI System - -System for creating text-based user interfaces. - -### Widget - -Base class for widgets: - -```python -from snakia.core.tui import Widget, Canvas, CanvasChar -from snakia.core.rx import Bindable - -class MyWidget(Widget): - def __init__(self): - super().__init__() - self.text = self.state("Hello World") - self.color = self.state(CanvasChar(fg_color="red")) - - def on_render(self) -> Canvas: - canvas = Canvas(20, 5) - canvas.draw_text(0, 0, self.text.value, self.color.value) - return canvas -``` - -### Canvas - -Drawing canvas: - -```python -from snakia.core.tui import Canvas, CanvasChar - -canvas = Canvas(80, 24) - -# Drawing text -canvas.draw_text(10, 5, "Hello", CanvasChar(fg_color="blue")) - -# Drawing rectangle -canvas.draw_rect(0, 0, 20, 10, CanvasChar("█", fg_color="green")) - -# Filling area -canvas.draw_filled_rect(5, 5, 10, 5, CanvasChar(" ", bg_color="red")) - -# Lines -canvas.draw_line_h(0, 0, 20, CanvasChar("-")) -canvas.draw_line_v(0, 0, 10, CanvasChar("|")) -``` - -### CanvasChar - -Character with attributes: - -```python -from snakia.core.tui import CanvasChar - -char = CanvasChar( - char="A", - fg_color="red", # Text color - bg_color="blue", # Background color - bold=True, # Bold - italic=False, # Italic - underline=True # Underline -) -``` - -### Renderer - -Screen rendering: - -```python -from snakia.core.tui import RenderContext -from snakia.core.tui.render import ANSIRenderer -import sys - -class StdoutTarget: - def write(self, text: str): sys.stdout.write(text) - def flush(self): sys.stdout.flush() - -renderer = ANSIRenderer(StdoutTarget()) - -with RenderContext(renderer) as ctx: - ctx.render(widget.render()) -``` - -### Ready-made Widgets - -```python -from snakia.core.tui.widgets import ( - TextWidget, BoxWidget, - HorizontalSplitWidget, VerticalSplitWidget -) - -# Text widget -text = TextWidget("Hello", CanvasChar(fg_color="red", bold=True)) - -# Box widget -box = BoxWidget(10, 5, CanvasChar("█", fg_color="yellow")) - -# Splitters -h_split = HorizontalSplitWidget([text1, text2], "|") -v_split = VerticalSplitWidget([h_split, box], "-") -``` - -## ⚡ Reactive Programming (RX) - -Reactive programming system for creating responsive interfaces. - -### Bindable - -Reactive variables: - -```python -from snakia.core.rx import Bindable, ValueChanged - -# Creating a reactive variable -counter = Bindable(0) - -# Subscribing to changes -def on_change(event: ValueChanged[int]): - print(f"Counter changed from {event.old_value} to {event.new_value}") - -counter.subscribe(on_change) - -# Changing value -counter.set(5) # Will call on_change -counter(10) # Alternative syntax -``` - -### AsyncBindable - -Asynchronous reactive variables: - -```python -from snakia.core.rx import AsyncBindable - -async_counter = AsyncBindable(0) - -async def async_handler(event: ValueChanged[int]): - print(f"Async counter: {event.new_value}") - -await async_counter.subscribe(async_handler, run_now=True) -await async_counter.set(42) -``` - -### Operators - -```python -from snakia.core.rx import map, filter, combine, merge - -# Transformation -doubled = map(counter, lambda x: x * 2) - -# Filtering -even_only = filter(counter, lambda x: x % 2 == 0) - -# Combining -combined = combine(counter, doubled, lambda a, b: a + b) - -# Merging streams -merged = merge(counter, async_counter) -``` - -## 🛠️ Utilities - -### to_async - -Converting synchronous functions to asynchronous: - -```python -from snakia.utils import to_async - -def sync_function(x): - return x * 2 - -async_function = to_async(sync_function) -result = await async_function(5) -``` - -### nolock - -Performance optimization: - -```python -from snakia.utils import nolock - -def busy_loop(): - while running: - # Work - nolock() # Release GIL -``` - -### inherit - -Simplified inheritance: - -```python -from snakia.utils import inherit - -class Base: - def method(self): pass - -class Derived(inherit(Base)): - def method(self): - super().method() - # Additional logic -``` - -### this - -Reference to current object: - -```python -from snakia.utils import this - -def func(): - return this() # Returns `` -``` - -### throw - -Throwing exceptions: - -```python -from snakia.utils import throw - -def validate(value): - if value < 0: - throw(ValueError("Value must be positive")) -``` - -### frame - -Working with frames: - -```python -from snakia.utils import frame - -def process_frame(): - current_frame = frame() - # Process frame -``` - -## 🎭 Decorators - -### inject_replace - -Method replacement: - -```python -from snakia.decorators import inject_replace - -class Original: - def method(self): return "original" - -@inject_replace(Original, "method") -def new_method(self): return "replaced" -``` - -### inject_before / inject_after - -Hooks before and after execution: - -```python -from snakia.decorators import inject_before, inject_after - -@inject_before(MyClass, "method") -def before_hook(self): print("Before method") - -@inject_after(MyClass, "method") -def after_hook(self): print("After method") -``` - -### singleton - -Singleton pattern: - -```python -from snakia.decorators import singleton - -@singleton -class Database: - def __init__(self): - self.connection = "connected" -``` - -### pass_exceptions - -Exception handling: - -```python -from snakia.decorators import pass_exceptions - -@pass_exceptions(ValueError, TypeError) -def risky_function(): - # Code that might throw exceptions - pass -``` - -## 🏷️ Properties - -### readonly - -Read-only property: - -```python -from snakia.property import readonly - - -class Currency: - @readonly - def rate(self) -> int: - return 100 - - -currency = Currency() -currency.rate = 200 -print(currency.rate) # Output: 100 -``` - -### initonly - -Initialization-only property: - -```python -from snakia.property import initonly - - -class Person: - name = initonly[str]("name") - - -bob = Person() -bob.name = "Bob" -print(bob.name) # Output: "Bob" -bob.name = "not bob" -print(bob.name) # Output: "Bob" -``` - -### 🏛️ classproperty - -Class property: - -```python -from snakia.property import classproperty - -class MyClass: - @classproperty - def class_value(cls): - return "class_value" -``` - -## 🌐 Platform Abstraction - -### 🖥️ PlatformOS - -Operating system abstraction: - -```python -from snakia.platform import PlatformOS, OS - -# Detecting current OS -current_os = OS.current() - -if current_os == PlatformOS.LINUX: - print("Running on Linux") -elif current_os == PlatformOS.ANDROID: - print("Running on Android") -``` - -### 🏗️ PlatformLayer - -Platform layers: - -```python -from snakia.platform import LinuxLayer, AndroidLayer - -# Linux layer -linux_layer = LinuxLayer() - -# Android layer -android_layer = AndroidLayer() -``` - ## 📦 Examples ### Health System @@ -856,16 +252,4 @@ We welcome contributions to Snakia development! Whether you're fixing bugs, addi - Add type hints to all new code - Write clear commit messages - Update documentation for new features -- Test your changes thoroughly - -## 🆘 Support - -Need help? We're here to assist you! - -- 🐛 **Bug Reports** - [GitHub Issues](https://github.com/RuJect/Snakia/issues) -- 💬 **Community Chat** - [RuJect Community Telegram](https://t.me/RuJect_Community) -- 📧 **Direct Contact** - mailto:rus07tam.uwu@gmail.com - -## 📄 License - -See the `LICENSE` file for details. +- Test your changes thoroughly \ No newline at end of file