Files
2026-07-09 02:59:53 +03:00

248 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# FFI → Direct Rust Bağımlılığı Geçiş Planı
## Hedef
`hcie-engine-api`'de şu an dinamik `.so` üzerinden yüklenen tüm core rendering crate'lerini doğrudan Rust crate bağımlılığına çevirmek. Sadece AI ve Vision crate'leri FFI'de kalır (AI ajanlarının kod bozmasını engellemek için).
Bu sayede **regression #1** (her composite'te 330MB FFI pixel copy) tamamen ortadan kalkar.
## Kapsam
| Crate | Şu an | Yeni |
|---|---|---|
| `hcie-blend` | FFI `.so` | ✅ Direct Rust (zaten Cargo.toml'da var) |
| `hcie-brush-engine` | FFI `.so` | ✅ Direct Rust (zaten Cargo.toml'da var) |
| `hcie-draw` | FFI `.so` | 🆕 Cargo.toml'a ekle |
| `hcie-filter` | FFI `.so` | 🆕 Cargo.toml'a ekle |
| `hcie-composite` | FFI `.so` | 🆕 Cargo.toml'a ekle |
| `hcie-io` | FFI `.so` | 🆕 Cargo.toml'a ekle |
| `hcie-psd` | FFI `.so` | 🆕 Cargo.toml'a ekle (`package = "psd"`) |
| `hcie-kra` | FFI `.so` | 🆕 Cargo.toml'a ekle |
| `hcie-native` | FFI `.so` | 🆕 Cargo.toml'a ekle |
| `hcie-vector` | FFI `.so` | 🆕 Cargo.toml'a ekle |
| **`hcie-ai`** | FFI `.so` | 🔒 **FFI kalır** |
| **`hcie-vision`** | FFI `.so` | 🔒 **FFI kalır** |
## Adım Adım Değişiklikler
### Adım 1: `hcie-engine-api/Cargo.toml`
**Ekle:**
```toml
hcie-draw = { path = "../hcie-draw" }
hcie-composite = { path = "../hcie-composite" }
hcie-filter = { path = "../hcie-filter" }
hcie-io = { path = "../hcie-io" }
hcie-psd = { path = "../hcie-psd", package = "psd" }
hcie-kra = { path = "../hcie-kra" }
hcie-native = { path = "../hcie-native" }
hcie-vector = { path = "../hcie-vector" }
```
**Kaldır:**
```toml
bincode = "1.3" # artık sadece FFI serileştirme için kullanılıyordu
```
`libloading = "0.8"` kalır (hcie-ai + hcie-vision için hala gerekli).
### Adım 2: `hcie-engine-api/src/dynamic_loader.rs`
Tamamen yeniden yazılır. Sadece AI ve Vision kısımları FFI'de kalır.
**Silinecek:** ~900 satır (10 crate için FFI loader, symbol resolution, C struct tanımları)
**Değişecek wrapper fonksiyonlar** (imzaları aynı kalır, gövdeleri değişir):
| Eski | Yeni gövde |
|---|---|
| `blend_pixels(dst, src, mode, opacity)` | `hcie_blend::blend_pixels(dst, src, mode, opacity)` |
| `blend_buffers(dst, src, mode, opacity)` | `hcie_blend::blend_buffers(dst, src, mode, opacity)` *(yeni pub fn eklenmeli)* |
| `draw_line(layer, x0, y0, x1, y1, color, size, mask)` | `hcie_draw::draw_line(x0, y0, x1, y1, &mut layer.pixels, ...)` |
| `draw_filled_rect(layer, x1, y1, x2, y2, color, mask)` | `hcie_draw::draw_filled_rect(x1, y1, x2, y2, ...)` |
| `draw_filled_ellipse(layer, cx, cy, rx, ry, color, mask)` | `hcie_draw::draw_filled_ellipse(cx, cy, rx, ry, ...)` |
| `flood_fill(layer, x, y, color, tolerance, mask)` | `hcie_draw::flood_fill(x, y, color, tolerance, ...)` |
| `draw_brush_stroke(layer, points, color, tip, ...)` | `hcie_draw::draw_brush_stroke(points, &mut layer.pixels, ...)` |
| `draw_specialized_stroke(pixels, w, h, ...)` | `hcie_brush_engine::draw_specialized_stroke(pixels, w, h, ...)` |
| `apply_filter(id, params, pixels, w, h)` | `hcie_filter::apply_filter(...)` *(Layer wrapper gerekli)* |
| `composite_layers(layers, w, h) → Vec<u8>` | `hcie_composite::composite_layers(...)` *(Layer dönüşümü gerekli)* |
| `composite_layers_region(layers, w, h, x0, y0, x1, y1, out)` | `hcie_composite::composite_layers_region(...)` |
| `tiled::composite_tiled_into(layers, tiles, w, h, x0, y0, x1, y1, out)` | `hcie_composite::tiled::composite_tiled_into(...)` |
| `load_image(path) → Layer` | `hcie_io::load_image(path)` |
| `save_image(layer, path, format)` | `hcie_io::save_image(layer, path, format)` |
| `svg_import::import_svg(data)` | `hcie_io::svg_import::import_svg(data)` |
| `import_psd(path) → Vec<Layer>` | `hcie_psd::import_psd(path)` |
| `export_psd(layers, w, h, composited, path)` | `hcie_psd::export_psd(layers, w, h, composited, path)` |
| `import_kra(path) → Vec<Layer>` | `hcie_kra::import_kra(path)` |
| `export_kra(layers, w, h, composited, path)` | `hcie_kra::export_kra(layers, w, h, composited, path)` |
| `load_native(path) → Vec<Layer>` | `hcie_native::load_native(path)` |
| `save_native(layers, path)` | `hcie_native::save_native(layers, path)` |
| `vector::render_vector_shapes(layer)` | `hcie_vector::render_vector_shapes(layer)` |
| `vector::boolean_shapes(op, a, b)` | `hcie_vector::path_boolean::boolean_shapes(op, a, b)` |
### Adım 3: `hcie-engine-api/src/lib.rs` — Use import güncellemesi
Tüm `dynamic_loader::xxx` çağrılarının olduğu satırlar (toplam 22 çağrı noktası) aynı isimdeki yeni wrapper'lara yönlendirilir. Çağrı imzaları değişmediği için sadece `use` import'ları güncellenir.
**Kritik:** `composite_layers()` ve `tiled::composite_tiled_into()` çağrılmadan önce `&[hcie_protocol::Layer]``Vec<hcie_composite::Layer>` dönüşümü yapılmalıdır. Bu dönüşüm mantığı zaten `dynamic_loader::build_c_desc()`'te mevcut — sadece çıktı tipi `CCompositeLayerDesc` yerine `hcie_composite::Layer` olacak.
**Dönüşüm helper fonksiyonu** (dynamic_loader.rs'ye veya lib.rs'ye eklenir):
```rust
fn protocol_layers_to_composite(layers: &[Layer]) -> Vec<hcie_composite::Layer> {
layers.iter().map(|l| {
let (pixels, w, h) = /* effects_cache check */;
hcie_composite::Layer {
pixels: pixels.to_vec(), // ← TEK COPY BURADA
width: w, height: h,
visible: l.visible, opacity: l.opacity,
blend_mode: l.blend_mode as i32,
clipping_mask: l.clipping_mask,
fill_opacity: l.fill_opacity,
mask_pixels: l.mask_pixels.clone(),
mask_bounds: l.mask_bounds,
mask_default_color: l.mask_default_color,
adjustment: l.adjustment.clone(),
effects: l.effects.clone(),
styles: l.styles.clone(),
}
}).collect()
}
```
**Not:** V3'te bu copy yoktu çünkü referansla çalışıyordu. Burada kaçınılmaz bir copy var (çünkü `hcie_composite::Layer` owned `Vec<u8>` bekler). Ama eskiden FFI'da hem `CCompositeLayerDesc` yapısı kuruluyordu hem de FFI içinde tekrar copy yapılıyordu (2 copy). Şimdi sadece 1 copy kalır.
### Adım 4: Her Crate'te FFI Export Kodlarını Kaldır
Her crate'in `lib.rs`'sinden `#[no_mangle] pub unsafe extern "C" fn` fonksiyonları silinir. crate-type'dan `cdylib` kaldırılır.
**hcie-blend:**
- `Cargo.toml`: `crate-type``["staticlib", "rlib"]`
- `lib.rs`: Sil `blend_pixels_c`, `blend_buffers_c`
- `lib.rs`: **Ekle** `pub fn blend_buffers(dst: &mut [u8], src: &[u8], mode: BlendMode, opacity: f32)` — gövdesi `blend_buffers_c` fonksiyonunun içinden alınır (rayon parallel loop)
**hcie-draw:**
- `Cargo.toml`: `crate-type``["staticlib", "rlib"]`
- `lib.rs`: Sil `draw_line_c`, `draw_filled_rect_c`, `draw_filled_circle_c`, `flood_fill_c`, `draw_brush_stroke_c`
**hcie-filter:**
- `Cargo.toml`: `crate-type``["staticlib", "rlib"]`
- `lib.rs`: Sil `apply_filter_c`, `get_filter_ids_json_c`, `free_filter_list_string_c`
**hcie-composite:**
- `Cargo.toml`: `crate-type``["staticlib", "rlib"]`
- `lib.rs`: Sil `composite_layers_c`, `composite_layers_region_c`, `composite_tiled_c`
- `lib.rs`: `hcie_protocol`'u dev-dependencies'ten regular dependency'e çek (Layer tipini kullanmak için)
**hcie-io:**
- `Cargo.toml`: `crate-type``["staticlib", "rlib"]`, `ffi` feature'ını kaldır
- `lib.rs`: Sil `load_image_c`, `save_image_c`, `import_svg_c`, `free_buffer_c` ve `#[cfg(feature = "ffi")]` blokları
**hcie-psd:**
- `Cargo.toml`: `crate-type``["rlib"]`, `ffi` feature'ını kaldır
- `psd/src/lib.rs` veya `ffi.rs`: Sil `import_psd_c`, `export_psd_c`, `free_buffer_c`
**hcie-kra:**
- `Cargo.toml`: `crate-type``["rlib"]`, `ffi` feature'ını kaldır
- `lib.rs`: Sil `import_kra_c`, `export_kra_c`, `kra_free_buffer_c`
**hcie-native:**
- `Cargo.toml`: `crate-type``["rlib"]`, `ffi` feature'ını kaldır
- `lib.rs`: Sil `load_native_c`, `save_native_c`, `free_buffer_c`
**hcie-brush-engine:**
- `Cargo.toml`: `crate-type``["staticlib", "rlib"]`
- `lib.rs`: Sil `draw_specialized_stroke_c`
**hcie-vector:**
- `Cargo.toml`: `crate-type``["staticlib", "rlib"]`
- `lib.rs`: Sil `render_vector_shapes_c`, `vector_boolean_shapes_c`, `free_buffer_c`
### Adım 5: Build Script Güncellemesi
**`build_and_copy_plugins.sh`:**
- Sadece `hcie-ai` ve `hcie-vision` build adımları kalır (step 12, 13)
- Step 1-11 (hcie-color, hcie-blend, hcie-brush-engine, hcie-draw, hcie-composite, hcie-filter, hcie-io, hcie-vector, psd, hcie-kra, hcie-native) kaldırılır
**`build_brush_engine.sh`:**
- Tamamen silinebilir (hcie-brush-engine .so build'i build_and_copy_plugins.sh step 3 ile aynı)
### Adım 6: Derleme ve Doğrulama
```bash
cargo check --workspace # workspace üyeleri
cd hcie-engine-api && cargo check # engine-api
```
## Risk Değerlendirmesi
| Değişiklik | Risk | Açıklama |
|---|---|---|
| `hcie-blend` → direct | **Düşük** | İmzalar birebir aynı. Sadece `blend_buffers` Rust API'si eklenmeli. |
| `hcie-draw` → direct | **Düşük** | İmzalar birebir aynı (raw pixel buffer). |
| `hcie-brush-engine` → direct | **Düşük** | İmzalar birebir aynı. Zaten bağımlılık var. |
| `hcie-filter` → direct | **Orta** | `hcie_filter::Layer` tipi farklı. Dynamic loader'da `(&mut [u8], u32, u32)``hcie_filter::Layer` wrapper yazılmalı. |
| `hcie-composite` → direct | **Orta-Yüksek** | `hcie_composite::Layer` tipi farklı. `build_c_desc()` mantığı `hcie_composite::Layer`'e uyarlanmalı. 1 adet pixel copy kaçınılmaz (FFI'da 2 copy vardı). |
| `hcie-io` → direct | **Düşük** | İmzalar birebir aynı. Aynı `hcie_protocol::Layer` tipi. |
| `hcie-psd` / `hcie-kra` / `hcie-native` | **Orta** | Rust API imzaları kontrol edilmeli, büyük olasılıkla uyumlu. |
| `hcie-vector` → direct | **Düşük** | `render_vector_shapes(&mut Layer)` aynı. `boolean_shapes` path_boolean modülünde. |
| Build script değişikliği | **Düşük** | Sadece .so build adımları kaldırılır. |
| Plugin arama kodu | **Düşük** | Sadece AI/Vision için kalır. |
## Toplam Değişiklik İstatistiği (Tahmini)
| Dosya | Değişiklik |
|---|---|
| `hcie-engine-api/Cargo.toml` | +9 satır, -1 satır |
| `hcie-engine-api/src/dynamic_loader.rs` | ~900 satır silinir, ~200 satır yeniden yazılır |
| `hcie-engine-api/src/lib.rs` | ~5 satır import değişikliği |
| 10 crate'in `lib.rs`'si | ~30-80 satır FFI export silinir/her crate |
| 10 crate'in `Cargo.toml`'u | crate-type ve feature değişikliği |
| `build_and_copy_plugins.sh` | ~80 satır silinir (~110 → ~30) |
| `build_brush_engine.sh` | silinir (~30 satır) |
**Toplam:** ~300 satır eklenir, ~1300 satır silinir, ~100 satır değişir.
---
## Ek: Workspace + Git Hooks + Lock Güncellemesi
FFI→direct dönüşümüne **paralel** olarak yapıldı:
### Kök Workspace (Cargo.toml)
- `/mnt/extra/00_PROJECTS/hcie-rust-v4/Cargo.toml` — tüm 31 crate member olarak listelendi
- Eski workspace'ler (`hcie-egui-app/Cargo.toml`, `hcie-core-app/Cargo.toml`) → regular package'a çevrildi
- Tüm workspace dependency'leri (egui 0.34, serde, rayon, image vs.) root'tan yönetilir
- V3'teki `LOCKED_PERF_PROFILES` bloğu korundu
### Versiyon Çakışmaları Çözüldü
| Çakışma | Çözüm |
|---|---|
| egui 0.27/0.28/0.29/0.34 | Tümü 0.34'e çekildi (7 crate'te dev-dep güncellendi) |
| eframe 0.27/0.28/0.29/0.34 | Tümü 0.34'e çekildi |
| fontdue 0.7/0.9 | hcie-text 0.9'a çekildi |
| rfd 0.14/0.15 | hcie-io dev-dep 0.15'e çekildi |
### Git Hook Sistemi
V3'teki semantic etki analizi sistemi `.githooks/` dizinine kuruldu:
| Dosya | Açıklama |
|---|---|
| `.githooks/pre-commit` | Staged değişiklikleri `project_manifest.json` ile karşılaştırır. HIGH blast radius varsa `cargo test` zorunlu kılar, başarısızsa commit'i engeller. |
| `.githooks/post-commit` | Commit sonrası `generate_semantic_report.py` ile 3 katmanlı rapor üretir (Layer 1: bağımlılık grafiği, Layer 2: API diff, Layer 3: semver opsiyonel). |
| `.githooks/semantic_analyzer.py` | Pre-commit analiz motoru |
| `.githooks/generate_semantic_report.py` | 3 katmanlı raportör (1075 satır, V3'ten port edildi) |
| `.githooks/semantic_check.sh` | CLI wrapper (precommit/audit/full/quick/json) |
| `project_manifest.json` | 105 dosya entry'si, 23 crate, V3'ten uyarlanmış path'ler |
**Kurulum:**
```bash
git config core.hooksPath .githooks
```
### .gitignore
- Kök `.gitignore``/target/` ile tüm crate'ler tek target paylaşır
- Eski `hcie-egui-app/.gitignore` artık geçerli değil (workspace root'taki geçerli)
### lock.sh / unlock.sh
- Liste güncellendi: `hcie-pixel-bridge` unlock'ta gereksizdi → kaldırıldı
- FFI→direct sonrası `.so` build gerektirmeyen crate'ler de lock listesinde kalır (kaynak kodu AI ajanlarından korumak için)