ASPL لباتASPL 0.7.0

Search documentation

Search starts with current English documentation · ASPL 0.7.0

Enter a complete name such as read_line, or words about a topic.

    العربية
    Source files

    Open one UTF-8 .aspl or .لبات file, up to 1 MiB, in a new draft. It stays in this browser and does not run automatically.

    Keep drawing while HTTP handlers share turns

    ASPL 0.7.0 · Current release

    Keep drawing while HTTP handlers share turns

    On this page

    Prepare the native host

    Native only, published ASPL 0.7.0.

    Raylib guide · API · Installation · Deployment.

    Native ASPL 0.7.0 on x86_64 Linux with glibc 2.34 or later.

    Running needs a reachable Wayland/EGL or X11/GLX display and OpenGL 3.3 core. Checking/building need no devices, C compiler or system Raylib.

    Free loopback ports 8000 and 8001. Start the upstream on 127.0.0.1:8001 before the program and promptly request /busy, /wait and /fast concurrently on port 8000. Delaying the upstream makes the stale snapshot reproducible. No source modules or file assets are needed.

    Start this reader-prepared upstream in another terminal. Python 3 and curl are preparation tools, not ASPL runtime dependencies. It delays replies by 200 ms; no public helper file is required.

    python3 - <<'UPSTREAM'
    from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
    import time
    class Upstream(BaseHTTPRequestHandler):
        def do_GET(self):
            time.sleep(0.2)
            self.send_response(200)
            self.send_header("Content-Length", "4")
            self.end_headers()
            self.wfile.write(b"done")
    ThreadingHTTPServer(("127.0.0.1", 8001), Upstream).serve_forever()
    UPSTREAM

    After ready appears, promptly issue these independent clients from another terminal. /busy remains unfinished until immediate session close. The other clients print conflict and fast with status 200. Upstream failure gives /wait status 502 and its HTTP error code.

    curl --max-time 6 -i http://127.0.0.1:8000/busy &
    curl --max-time 6 -i http://127.0.0.1:8000/wait &
    curl --max-time 6 -i http://127.0.0.1:8000/fast &
    wait

    Page language and source vocabulary are independent. Keep original filenames; no translated user source is generated. Each source panel shows its checked expected behavior.

    Arabic source

    Native only · ASPL 0.7.0 · Arabic source

    Execution: Native only · ASPL 0.7.0

    Prerequisites:
    • Native ASPL 0.7.0 on x86_64 Linux with glibc 2.34 or later.
    • Running needs a reachable Wayland/EGL or X11/GLX display and OpenGL 3.3 core. Checking/building need no devices, C compiler or system Raylib.
    • Free loopback ports 8000 and 8001. Prepare the local upstream and independent concurrent clients as shown on this page. Delaying the upstream makes the stale snapshot reproducible. No source modules or file assets are needed.

    Input: No input lines are required.

    // شغل خادم ويب بعيد على 127.0.0.1:8001، ثم اطلب /busy و/wait و
    // /fast على المنفذ 8000. تواصل النافذة الرسم بينما تتناوب المعالجات.
    استورد أساسي::رايليب.
    استورد أساسي::ويب.
    
    سجل حالة { إطارات: ص64, مشغول: منطقي, سريع: منطقي, تعارض: منطقي }
    
    دالة طلب_صادر(سياق: ويب::سياق<نص,حالة>, محفوظ: ص64) -> ويب::استجابة_خادم {
        دع لقطة = ويب::التقط_الحالة(سياق).
        دع طلب = ويب::أنشئ_طلب("GET", ويب::اقرأ_إعدادات(سياق))::قيمة.
        دع رد = ويب::اطلب(طلب, ويب::خيارات_طلب()).
        إذا لا رد::نجاح {
            أرجع ويب::استجابة_نصية(502, رد::الخطأ::الرمز, "text/plain")::قيمة.
        }
        إذا محفوظ لا يطابق 7 { أرجع ويب::أنشئ_استجابة(500, [])::قيمة. }
        دع منشور = ويب::استبدل_الحالة_إن_كانت_حالية(سياق, لقطة, لقطة::قيمة)::قيمة.
        متغير حالي = ويب::اقرأ_حالة(سياق).
        حالي::تعارض = لا منشور.
        ويب::استبدل_حالة(سياق, حالي).
        أرجع ويب::استجابة_نصية(200, "conflict", "text/plain")::قيمة.
    }
    
    دالة معالج(الطلب: ويب::طلب_وارد, سياق: ويب::سياق<نص,حالة>) -> ويب::استجابة_خادم {
        إذا الطلب::مسار يطابق "/busy" {
            متغير الحالة = ويب::اقرأ_حالة(سياق).
            الحالة::مشغول = صواب.
            ويب::استبدل_حالة(سياق, الحالة).
            طالما صواب {}
        }
        إذا الطلب::مسار يطابق "/wait" { أرجع طلب_صادر(سياق, 7). }
        متغير حالي = ويب::اقرأ_حالة(سياق).
        حالي::سريع = رايليب::هل_النافذة_جاهزة().
        ويب::استبدل_حالة(سياق, حالي).
        أرجع ويب::استجابة_نصية(200, "fast", "text/plain")::قيمة.
    }
    
    دالة ابدأ_الرئيسية() -> ص64 {
        دع مفتوح = رايليب::هيئ_نافذة(480, 240, "ASPL HTTP and drawing").
        إذا لا مفتوح::نجاح { اطبع(مفتوح::الخطأ::الرمز). أرجع 1. }
        دع معدل_الإطارات = رايليب::اضبط_معدل_الإطارات(60).
        إذا لا معدل_الإطارات::نجاح { أرجع 9. }
        متغير خادم = ويب::إعدادات_خدمة().
        خادم::مستمعون = [ويب::أنشئ_مستمع("127.0.0.1", 8000)::قيمة].
        دع وجهات = ويب::أنشئ_موجه([
            ويب::أنشئ_وجهة("GET", "/busy", معالج)::قيمة,
            ويب::أنشئ_وجهة("GET", "/wait", معالج)::قيمة,
            ويب::أنشئ_وجهة("GET", "/fast", معالج)::قيمة
        ])::قيمة.
        دع مبدوء = ويب::ابدأ(خادم, وجهات, "http://127.0.0.1:8001/",
            حالة {إطارات: 0, مشغول: خطأ, سريع: خطأ, تعارض: خطأ}).
        إذا لا مبدوء::نجاح { اطبع(مبدوء::الخطأ::الرمز). أرجع 2. }
        دع مالك = مبدوء::قيمة.
        اطبع("ready\س").
        متغير ميزانية = ويب::ميزانية_التقدم().
        ميزانية::حد_التعليمات = 128.
        متغير إطارات: ص32 = 0.
        طالما إطارات < 180 و لا رايليب::هل_يجب_إغلاق_النافذة()::قيمة {
            إذا لا ويب::تقدم(مالك, ميزانية)::نجاح { أرجع 3. }
            إذا لا رايليب::ابدأ_الرسم()::نجاح { أرجع 4. }
            إذا لا رايليب::امسح_الخلفية(رايليب::أبيض_رايليب)::نجاح { أرجع 10. }
            متغير الحالة = ويب::التقط_حالة_الجلسة(مالك)::قيمة::قيمة.
            الحالة::إطارات = الحالة::إطارات + 1.
            إذا لا ويب::استبدل_حالة_الجلسة(مالك, الحالة)::نجاح { أرجع 5. }
            إذا لا رايليب::ارسم_مستطيلا(إطارات, 90, 40, 40, رايليب::أزرق)::نجاح { أرجع 11. }
            إذا لا رايليب::أنه_الرسم()::نجاح { أرجع 6. }
            إطارات = إطارات + 1.
        }
        دع نهائي = ويب::حالة_الجلسة(مالك)::قيمة.
        إذا لا ويب::أغلق_الجلسة(مالك)::نجاح { أرجع 7. }
        إذا لا رايليب::أغلق_النافذة()::نجاح { أرجع 8. }
        إذا نهائي::مشغول و نهائي::سريع و نهائي::تعارض {
            اطبع("busy fast conflict\س").
        }
        أرجع 0.
    }
    

    Follow the Linux instructions to run this example. Download the source to keep a copy.

    Download ويب-متزامن.لبات

    Expected outcomes
    {
      "native": {
        "check": 0,
        "status": 0,
        "behavior": {
          "en": "A square moves for up to 180 frames. The program prints ready followed by a newline after listener startup. Concurrent busy, wait and fast requests exercise bounded handler turns and a stale snapshot. It prints busy fast conflict followed by a newline only if all three observations occur, then returns 0. Client timing and early window closure affect that final line.",
          "ar": "يتحرك مربع حتى 180 إطارا. يطبع البرنامج ready ثم سطرا جديدا بعد بدء المستمع. تفحص طلبات busy وwait وfast المتزامنة أدوار المعالج المحدودة ولقطة قديمة. يطبع busy fast conflict ثم سطرا جديدا فقط عند تحقق الملاحظات الثلاث، ثم يعيد 0. يؤثر توقيت العملاء والإغلاق المبكر في السطر النهائي."
        }
      }
    }

    English source

    Native only · ASPL 0.7.0 · English source

    Execution: Native only · ASPL 0.7.0

    Prerequisites:
    • Native ASPL 0.7.0 on x86_64 Linux with glibc 2.34 or later.
    • Running needs a reachable Wayland/EGL or X11/GLX display and OpenGL 3.3 core. Checking/building need no devices, C compiler or system Raylib.
    • Free loopback ports 8000 and 8001. Prepare the local upstream and independent concurrent clients as shown on this page. Delaying the upstream makes the stale snapshot reproducible. No source modules or file assets are needed.

    Input: No input lines are required.

    // Run an upstream HTTP server on 127.0.0.1:8001, then request /busy, /wait and
    // /fast on port 8000. The window keeps drawing while the handlers share turns.
    import core::raylib;
    import core::http;
    
    record State { frames: i64, busy: bool, fast: bool, conflict: bool }
    
    fn outbound(ctx: http::Context<string,State>, saved: i64) -> http::ServerResponse {
        let snapshot = http::snapshot_state(ctx);
        let request = http::client_request("GET", http::read_config(ctx))::value;
        let reply = http::request(request, http::client_options());
        if not reply::ok {
            return http::text_response(502, reply::error::code, "text/plain")::value;
        }
        if saved not matches 7 { return http::response(500, [])::value; }
        let published = http::replace_state_if_current(ctx, snapshot, snapshot::value)::value;
        var current = http::read_state(ctx);
        current::conflict = not published;
        http::replace_state(ctx, current);
        return http::text_response(200, "conflict", "text/plain")::value;
    }
    
    fn handler(req: http::IncomingRequest, ctx: http::Context<string,State>) -> http::ServerResponse {
        if req::path matches "/busy" {
            var state = http::read_state(ctx);
            state::busy = true;
            http::replace_state(ctx, state);
            while true {}
        }
        if req::path matches "/wait" { return outbound(ctx, 7); }
        var current = http::read_state(ctx);
        current::fast = raylib::IsWindowReady();
        http::replace_state(ctx, current);
        return http::text_response(200, "fast", "text/plain")::value;
    }
    
    fn start_main() -> i64 {
        let opened = raylib::InitWindow(480, 240, "ASPL HTTP and drawing");
        if not opened::ok { print(opened::error::code); return 1; }
        let pacing = raylib::SetTargetFPS(60);
        if not pacing::ok { return 9; }
        var server = http::server_config();
        server::listeners = [http::listener("127.0.0.1", 8000)::value];
        let routes = http::router([
            http::route("GET", "/busy", handler)::value,
            http::route("GET", "/wait", handler)::value,
            http::route("GET", "/fast", handler)::value
        ])::value;
        let started = http::start(server, routes, "http://127.0.0.1:8001/",
            State {frames: 0, busy: false, fast: false, conflict: false});
        if not started::ok { print(started::error::code); return 2; }
        let owner = started::value;
        print("ready\n");
        var budget = http::progress_budget();
        budget::max_instructions = 128;
        var frames: i32 = 0;
        while frames < 180 and not raylib::WindowShouldClose()::value {
            if not http::progress(owner, budget)::ok { return 3; }
            if not raylib::BeginDrawing()::ok { return 4; }
            if not raylib::ClearBackground(raylib::RAYWHITE)::ok { return 10; }
            var state = http::snapshot_session_state(owner)::value::value;
            state::frames = state::frames + 1;
            if not http::replace_session_state(owner, state)::ok { return 5; }
            if not raylib::DrawRectangle(frames, 90, 40, 40, raylib::BLUE)::ok { return 11; }
            if not raylib::EndDrawing()::ok { return 6; }
            frames = frames + 1;
        }
        let final = http::session_state(owner)::value;
        if not http::close_session(owner)::ok { return 7; }
        if not raylib::CloseWindow()::ok { return 8; }
        if final::busy and final::fast and final::conflict {
            print("busy fast conflict\n");
        }
        return 0;
    }
    

    Follow the Linux instructions to run this example. Download the source to keep a copy.

    Download concurrent-http.aspl

    Expected outcomes
    {
      "native": {
        "check": 0,
        "status": 0,
        "behavior": {
          "en": "A square moves for up to 180 frames. The program prints ready followed by a newline after listener startup. Concurrent busy, wait and fast requests exercise bounded handler turns and a stale snapshot. It prints busy fast conflict followed by a newline only if all three observations occur, then returns 0. Client timing and early window closure affect that final line.",
          "ar": "يتحرك مربع حتى 180 إطارا. يطبع البرنامج ready ثم سطرا جديدا بعد بدء المستمع. تفحص طلبات busy وwait وfast المتزامنة أدوار المعالج المحدودة ولقطة قديمة. يطبع busy fast conflict ثم سطرا جديدا فقط عند تحقق الملاحظات الثلاث، ثم يعيد 0. يؤثر توقيت العملاء والإغلاق المبكر في السطر النهائي."
        }
      }
    }

    Mixed source

    Native only · ASPL 0.7.0 · Mixed source

    Execution: Native only · ASPL 0.7.0

    Prerequisites:
    • Native ASPL 0.7.0 on x86_64 Linux with glibc 2.34 or later.
    • Running needs a reachable Wayland/EGL or X11/GLX display and OpenGL 3.3 core. Checking/building need no devices, C compiler or system Raylib.
    • Free loopback ports 8000 and 8001. Prepare the local upstream and independent concurrent clients as shown on this page. Delaying the upstream makes the stale snapshot reproducible. No source modules or file assets are needed.

    Input: No input lines are required.

    // Run an upstream HTTP server on 127.0.0.1:8001, then request /busy, /wait and
    // /fast on port 8000. The window keeps drawing while the handlers share turns.
    import core::raylib;
    استورد أساسي::رايليب.
    import core::http;
    
    record State { frames: i64, busy: bool, fast: bool, conflict: bool }
    
    fn outbound(ctx: http::Context<string,State>, saved: i64) -> http::ServerResponse {
        let snapshot = http::snapshot_state(ctx);
        let request = http::client_request("GET", http::read_config(ctx))::value;
        let reply = http::request(request, http::client_options());
        if not reply::ok {
            return http::text_response(502, reply::error::code, "text/plain")::value;
        }
        if saved not matches 7 { return http::response(500, [])::value; }
        let published = http::replace_state_if_current(ctx, snapshot, snapshot::value)::value;
        var current = http::read_state(ctx);
        current::conflict = not published;
        http::replace_state(ctx, current);
        return http::text_response(200, "conflict", "text/plain")::value;
    }
    
    fn handler(req: http::IncomingRequest, ctx: http::Context<string,State>) -> http::ServerResponse {
        if req::path matches "/busy" {
            var state = http::read_state(ctx);
            state::busy = true;
            http::replace_state(ctx, state);
            while true {}
        }
        if req::path matches "/wait" { return outbound(ctx, 7); }
        var current = http::read_state(ctx);
        current::fast = raylib::IsWindowReady();
        http::replace_state(ctx, current);
        return http::text_response(200, "fast", "text/plain")::value;
    }
    
    fn start_main() -> i64 {
        let opened = raylib::InitWindow(480, 240, "ASPL HTTP and drawing");
        if not opened::ok { print(opened::error::code); return 1; }
        let pacing = raylib::SetTargetFPS(60);
        if not pacing::ok { return 9; }
        var server = http::server_config();
        server::listeners = [http::listener("127.0.0.1", 8000)::value];
        let routes = http::router([
            http::route("GET", "/busy", handler)::value,
            http::route("GET", "/wait", handler)::value,
            http::route("GET", "/fast", handler)::value
        ])::value;
        let started = http::start(server, routes, "http://127.0.0.1:8001/",
            State {frames: 0, busy: false, fast: false, conflict: false});
        if not started::ok { print(started::error::code); return 2; }
        let owner = started::value;
        print("ready\n");
        var budget = http::progress_budget();
        budget::max_instructions = 128;
        var frames: i32 = 0;
        while frames < 180 and not raylib::WindowShouldClose()::value {
            if not http::progress(owner, budget)::ok { return 3; }
            if not raylib::ابدأ_الرسم()::ok { return 4; }
            if not raylib::ClearBackground(raylib::RAYWHITE)::ok { return 10; }
            var state = http::snapshot_session_state(owner)::value::value;
            state::frames = state::frames + 1;
            if not http::replace_session_state(owner, state)::ok { return 5; }
            if not raylib::DrawRectangle(frames, 90, 40, 40, raylib::BLUE)::ok { return 11; }
            if not raylib::أنه_الرسم()::ok { return 6; }
            frames = frames + 1;
        }
        let final = http::session_state(owner)::value;
        if not http::close_session(owner)::ok { return 7; }
        if not raylib::CloseWindow()::ok { return 8; }
        if final::busy and final::fast and final::conflict {
            print("busy fast conflict\n");
        }
        return 0;
    }
    

    Follow the Linux instructions to run this example. Download the source to keep a copy.

    Download concurrent-http.mixed.aspl

    Expected outcomes
    {
      "native": {
        "check": 0,
        "status": 0,
        "behavior": {
          "en": "A square moves for up to 180 frames. The program prints ready followed by a newline after listener startup. Concurrent busy, wait and fast requests exercise bounded handler turns and a stale snapshot. It prints busy fast conflict followed by a newline only if all three observations occur, then returns 0. Client timing and early window closure affect that final line.",
          "ar": "يتحرك مربع حتى 180 إطارا. يطبع البرنامج ready ثم سطرا جديدا بعد بدء المستمع. تفحص طلبات busy وwait وfast المتزامنة أدوار المعالج المحدودة ولقطة قديمة. يطبع busy fast conflict ثم سطرا جديدا فقط عند تحقق الملاحظات الثلاث، ثم يعيد 0. يؤثر توقيت العملاء والإغلاق المبكر في السطر النهائي."
        }
      }
    }

    Commands and outcomes

    Check/build acquire no device. Run from the directory containing the prepared docs/ tree. Keep the generated .THIRD-PARTY-NOTICES companion when distributing the ELF.

    ar:

    aspl check docs/examples/raylib/ويب-متزامن.لبات
    aspl run docs/examples/raylib/ويب-متزامن.لبات
    aspl build -o raylib-concurrent-http-ar-program docs/examples/raylib/ويب-متزامن.لبات
    ./raylib-concurrent-http-ar-program

    en:

    aspl check docs/examples/raylib/concurrent-http.aspl
    aspl run docs/examples/raylib/concurrent-http.aspl
    aspl build -o raylib-concurrent-http-en-program docs/examples/raylib/concurrent-http.aspl
    ./raylib-concurrent-http-en-program

    mixed:

    aspl check docs/examples/raylib/concurrent-http.mixed.aspl
    aspl run docs/examples/raylib/concurrent-http.mixed.aspl
    aspl build -o raylib-concurrent-http-mixed-program docs/examples/raylib/concurrent-http.mixed.aspl
    ./raylib-concurrent-http-mixed-program

    A missing display prints raylib.host_unavailable and returns 1 before listener startup. An occupied listener port prints the HTTP startup error and returns 2. Success without clients returns 0 with only ready printed.

    Raylib collection.

    Historical normative scope

    Browse pages