Hoppa till innehållet

Den här sidan zoomar: att scrolla tar dig närmare, från ett namn in i en mening, in i ett projekt, in i dess kod. Använd piltangenterna för att stega mellan djupen, eller läs den platta versionen på /sv/all.

Ismail Safwat

Jag bygger mjukvara i hela stacken: webbapplikationer, tjänsterna bakom dem, firmwaren inuti industriella maskiner och en gång, för nöjes skull, en spelmotor.

Jag bygger mjukvara i hela stacken: webbapplikationer, tjänsterna bakom dem, firmwaren inuti industriella maskiner och en gång, för nöjes skull, en spelmotor.

den här sidan · 2026 · eget

ismailsafwat.com – den här webbplatsen

Den här sidan: en enda sida som zoomar från ett namn ner till en bit kod, byggd på Astro och serverad från Cloudflares kant.

Astro · TypeScript · CSS · Cloudflare Pages · Cloudflare Workers

gränssnitt · applikation · tjänster · data

Ismail Safwat 1× Ismail Safwat 4× Wexiödisk, 2023 → 20× Wexiödisk · 2023 → Mjukvaruingenjör en bit av koden ↓ 80× s = mål.w / nästa.w k = 1 / s FÖRSTORING MOT SCROLL · log 1× 10× 100× 1000× 0 1 2 3 4 · djup ≈ 330× out: translate((cx−tx)·p, (cy−ty)·p) scale(k^p) in: translate((tx−cx)·(1−p), …) scale(s^(1−p)) omgivningen tonar 0.03–0.28 · målet 0.28–0.50 · nästa 0.44–0.66 prefers-reduced-motion → samma dokument, platt 1 2 3 4 5
gränssnitt
applikation
tjänster
data
firmware
en bit av koden ↓

Wexiödisk · 2023 → · arbete

Mjukvaruingenjör på Wexiödisk

Jag skriver styrmjukvaran och pekgränssnittet i Qt/QML inuti Wexiödisks industriella diskmaskiner, och telemetrin som rapporterar varje maskin tillbaka till molnet. Firmware som måste vara rätt i ett kök mitt på dagen, och skärmar som fungerar med blöta händer.

C++ · QML · Linux · Rhapsody · IoT · Embedded Systems

gränssnitt · applikation · tjänster · data · firmware

GND POUR U1 ARM · 480 MHz LINUX · C++ Y1 · 25 MHz J1 · SENSORS T1 temp L1 level S1 door P1 press. K1 HEATER 16 A · 230 V K2 PUMP 8 A K3 DOOR LOCK M1 Wi‑Fi · BLE U2 PMIC F1 · 2 A D1 D2 D3 TP1–3 J3 · FPC 40p J2 RS‑485 ECO 65° 04:12 PROGRAM 2 · WASH WD‑TOUCH · 7" · QML MQTT · TLS 1.3 temp 64.8 · cycle 2 temp 64.5 · cycle 2 door closed · 04:12 120.00 84 A 1 2 3 4 5 6 7 8
gränssnitt
applikation
tjänster
data
firmware
en bit av koden ↓

ett distribuerat affärssystem · 2022 · universitet

Distribuerat affärssystem

Ett universitetsprojekt där jag byggde ett system så som stora organisationer gör: flera tjänster som var och en äger sin egen data och pratar över REST. Det mesta jag vet om gränserna mellan tjänster lärde jag mig genom att få dem fel här först.

SOA · Microservices · Service Architecture · Enterprise Patterns

applikation · tjänster · data

TJÄNSTEZON · PRIVAT NÄT PUBLIK KANT client browser · JSON gateway auth · JWT rate limit route · retry REST · HTTP/1.1 account :8081 ctrl svc repo accounts person :8082 ctrl svc repo persons bank :8083 ctrl svc repo banks ETT LAGER PER TJÄNST GET /persons/{id} EN BEGÄRAN, TIDSLINJE · req 7f3a client gateway account person t=0 · POST /transfer +4 ms · auth ok +11 ms · owner? +23 ms · 200 +31 ms · 201 created +33 ms timeout 800 ms · 2 försök 1 2 3 4 5 6
gränssnitt
applikation
tjänster
data
firmware
en bit av koden ↓

Kundvagn · 2021 · universitet

Kundvagn – Android-app för kundvagn

Ett universitetsprojekt: en kundvagnsapp för Android i Kotlin. Det jag brydde mig om var synken: två telefoner, en kundvagn, och Firestore som håller dem ärliga i realtid.

Kotlin · Android SDK · Firebase · Firestore · Mobile Development

gränssnitt · applikation · data

09:41 09:41 kundvagn uid 3f…A mjölk×2 · 34 kr bröd×1 · 42 kr kaffe×1 · 69 kr betala · 145 kr TELEFON A · LÄGGER TILL kundvagn uid 3f…B mjölk×2 · 34 kr bröd×1 · 42 kr kaffe×1 · 69 kr betala · 145 kr TELEFON B · LYSSNAR Firestore europe‑west1 carts/ {uid}/ items/ k7f2 { name:"kaffe", qty:1 } a91c { name:"mjölk", qty:2 } c04e { name:"bröd", qty:1 } regler: auth.uid == uid index: items.addedAt ↑ offline: skrivningar köas set() onSnapshot onSnapshot set() INGEN ANSLUTNING set() väntar lokalt → spelas upp vid återanslutning ~200 ms skrivning till synlig ändring, Jönköping → europe‑west1 → Jönköping 1 2 3 4 5
gränssnitt
applikation
tjänster
data
firmware
en bit av koden ↓

Shape Shooters · 2020 · universitet

Shape Shooters – spelmotor i C++

Ett universitetsprojekt: ett arkadskjutspel för flera spelare och den lilla motorn under det, skrivet från grunden i C++ med SFML. Min första riktiga lektion i spelloopar, timing och varför kollisionsdetektering aldrig blir riktigt klar.

C++ · SFML · OOP · UML · Game Development

gränssnitt · applikation

SCORE 0420 LIVES 3 · WAVE 4 rutnät 80 px · 18 celler AABB 56² Ship · p(234,248) v(0,42) v(‑26,36) v(‑40,0) hit · +20 KLASSER Entity pos · vel · box Ship Enemy Bullet entiteter 14 kollisionstest 31 / 91 spar 66 % med rutnätet frame time · 60 Hz EN BILDRUTA · 16,7 ms input 0.4 · update 2.1 collide 1.3 render 6.8 idle 6.1 · vsync dt = clock.restart() · position += hastighet · dt 1 2 3 4 5
gränssnitt
applikation
tjänster
data
firmware
en bit av koden ↓
// Between depth i and i+1, p runs from 0 to 1.
// The outgoing layer grows around its target;
// the incoming layer shrinks onto that same target.
const s = target.width / incoming.width; // < 1
const k = 1 / s;

out.style.transform =
  `translate(${(cx - tx) * p}px, ${(cy - ty) * p}px) scale(${k ** p})`;

inc.style.transform =
  `translate(${(tx - cx) * (1 - p)}px, ${(ty - cy) * (1 - p)}px) scale(${s ** (1 - p)})`;
enum class State { Idle, Fill, Heat, Wash, Drain, Fault };

State next(State s, const Sensors& in) {
  switch (s) {
    case State::Idle:  return in.doorClosed && in.start ? State::Fill  : s;
    case State::Fill:  return in.level >= target.level  ? State::Heat  : s;
    case State::Heat:  return in.temp  >= target.temp   ? State::Wash  : s;
    case State::Wash:  return timer.expired()           ? State::Drain : s;
    case State::Drain: return in.level <= 0             ? State::Idle  : s;
    case State::Fault: return s;
  }
  return State::Fault;
}
@GET
@Path("/accounts/{id}/balance")
public Response balance(@PathParam("id") String id) {
    Account account = accounts.find(id)
        .orElseThrow(NotFoundException::new);
    Person owner = personService.get(account.ownerId()); // another service, over REST
    return Response.ok(new BalanceDto(owner.name(), account.balance())).build();
}
cartRef.addSnapshotListener { snapshot, error ->
    if (error != null) return@addSnapshotListener
    val items = snapshot?.documents?.mapNotNull { it.toObject<CartItem>() }.orEmpty()
    _cart.value = items.sortedBy { it.addedAt }
}
while (window.isOpen()) {
    float dt = clock.restart().asSeconds();
    handleInput(window);
    for (auto& entity : entities) entity->update(dt, world);
    resolveCollisions(entities);
    window.clear();
    for (auto& entity : entities) entity->draw(window);
    window.display();
}