3 คะแนน โดย GN⁺ 2024-08-12 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ในกระบวนการพัฒนา Textual สามารถสร้าง แอนิเมชัน TUI ที่ลื่นไหล ได้แม้อยู่บนโปรโตคอลเทอร์มินัลแบบเก่า แต่ต้องจัดการวิธีรีเฟรชหน้าจอและการซิงก์เอาต์พุตอย่างรอบคอบ
  • หากต้องการลดการกะพริบ สิ่งสำคัญคือไม่ล้างหน้าจอแล้วค่อยวาดใหม่ แต่ให้เขียนทับ, เขียนลง standard output ในครั้งเดียว, และใช้โปรโตคอล Synchronized Output
  • dict.items() view และ @lru_cache ของ Python มีประโยชน์ต่อการคำนวณส่วนต่างของการเรนเดอร์และการปรับแต่งฟังก์ชันขนาดเล็กที่ถูกเรียกถี่ ๆ โดยมี implementation แบบ C ของ CPython ช่วยรองรับ ประสิทธิภาพของแคช
  • อ็อบเจ็กต์ที่เกือบไม่เปลี่ยนแปลง, ไดอะแกรมอักขระกล่อง Unicode และ fractions.Fraction ต่างช่วยเพิ่ม ความแม่นยำ ในด้านการให้เหตุผล·การแคช·การทดสอบ, ความเข้าใจเอกสาร, และการคำนวณเลย์เอาต์ตามลำดับ
  • Emoji บนเทอร์มินัลคาดเดาได้ยากเพราะความต่างของเวอร์ชัน Unicode, ความกว้างอักขระ และการเรนเดอร์หลาย code point ดังนั้นในการใช้งานจริง Emoji แบบเรียบง่ายระดับ Unicode 9 จึงเสถียรกว่า

แอนิเมชันบนเทอร์มินัลและการควบคุมการกะพริบ

  • เทอร์มินัลอีมูเลเตอร์สมัยใหม่ทำงานอยู่บนโปรโตคอลแบบเก่า แต่หลาย implementation ใช้เทคนิคกราฟิกที่พบได้ในวิดีโอเกมด้วย
  • เอฟเฟกต์ภาพบนเทอร์มินัลเกิดอาการกะพริบหรือ tearing ได้ง่าย แต่ถ้ารักษาเงื่อนไขบางอย่างก็สามารถทำ แอนิเมชันที่ลื่นไหล ได้
  • วิธีแรกในการลดการกะพริบคือไม่ใช้ “clear แล้ว draw” แต่เป็นการ เขียนทับเนื้อหาเดิม
    • ถ้าล้างหน้าจอแล้วค่อยเพิ่มเนื้อหาใหม่ อาจเห็นเฟรมว่างหรือเฟรมที่วาดไม่ครบชั่วขณะ
  • วิธีที่สองคือเขียนข้อมูลอัปเดตลง standard output ด้วย write เดียว
    • หากเรียก file.write หลายครั้ง ผู้ใช้อาจเห็นสถานะอัปเดตเพียงบางส่วนได้
  • วิธีที่สามคือใช้โปรโตคอล Synchronized Output
    • หากแจ้งจุดเริ่มต้นและจุดสิ้นสุดของเฟรมให้เทอร์มินัลรู้ เทอร์มินัลก็สามารถใช้สิ่งนี้เพื่อช่วยอัปเดตแบบไม่กะพริบได้
  • Textual ตั้งเป้าไว้ที่ 60fps และที่สูงกว่านั้นอาจไม่ได้ให้ความต่างที่สังเกตได้มากนัก
  • ไม่ใช่ทุกแอนิเมชันจะมีคุณค่าเท่ากัน
    • เอฟเฟกต์อย่างแถบด้านข้างที่เลื่อนเข้ามาจากซ้ายอาจดูดี แต่ไม่ได้เพิ่มประโยชน์ต่อประสบการณ์ผู้ใช้มากนัก
    • การเลื่อนอย่างลื่นไหลช่วยให้รักษาตำแหน่งปัจจุบันในข้อความยาว ๆ ได้
    • ด้วยเหตุนี้ Textual จึงมีแผนจะเพิ่มกลไกสำหรับปิดแอนิเมชันบางประเภท

หา diff ของการเรนเดอร์ด้วย DictView

  • keys() และ items() ของ dict ใน Python จะคืนค่า KeysView และ ItemsView ตามลำดับ ซึ่งมีอินเทอร์เฟซคล้ายเซต
  • กระบวนการจัดเลย์เอาต์ของ Textual จะสร้าง render map ซึ่งเป็นการแมประหว่าง Widget กับตำแหน่งบนหน้าจอ
  • วิธีเดิมทำให้แม้จะเปลี่ยนตำแหน่งของ Widget เพียงตัวเดียว ก็ยังรีเฟรชทั้งหน้าจออย่างสิ้นเปลือง
  • หากใช้ symmetric difference ของ ItemsView สองชุด ก็จะหา item ที่เพิ่มใหม่หรือเปลี่ยนไปได้
    • การทำงานนี้ประมวลผลในระดับ C
    • Textual ใช้สิ่งนี้เพื่อหา area บนหน้าจอที่เปลี่ยนไปเมื่อคุณสมบัติ CSS เปลี่ยน และนำไปสู่ การอัปเดตที่ปรับแต่งแล้ว

lru_cache และการปรับแต่งฟังก์ชันขนาดเล็ก

  • @lru_cache ใน standard library functools เป็น decorator สำหรับแคชค่าที่ฟังก์ชันคืนกลับ
  • การตั้ง maxsize ช่วยจำกัดไม่ให้แคชโตแบบไร้ขีดจำกัด
  • lru_cache ของ CPython ใช้ implementation แบบ C จึงทำงานได้เร็วทั้งกรณี cache hit และ miss
  • ใน Textual มีฟังก์ชันขนาดเล็กจำนวนมากที่ไม่ได้ช้าในตัวเอง แต่ถูกเรียกบ่อยมาก และหลายฟังก์ชันก็เหมาะกับการแคช
  • โดยทั่วไปการตั้ง maxsize ราว 1000~4000 ก็เพียงพอที่จะทำให้การเรียกส่วนใหญ่กลายเป็น cache hit
  • เมื่อใช้แคช ควรตรวจดู cache_info()
    • หากแคชมีประสิทธิภาพ ก็ควรเห็นว่า hits เพิ่มเร็วกว่า misses
  • เมธอด intersection ที่คำนวณส่วนทับซ้อนของพื้นที่สี่เหลี่ยมสองส่วน แม้งานต่อครั้งจะไม่มาก แต่เมื่อถูกเรียกหลายพันครั้งก็ได้ประโยชน์จากการแคช

ความเรียบง่ายที่ได้จากอ็อบเจ็กต์ไม่เปลี่ยนแปลง

  • ใน Python ไม่มีอ็อบเจ็กต์ immutable อย่างแท้จริง แต่ tuple, NamedTuple และ frozen dataclass ก็ให้ประโยชน์ได้มาก
  • ข้อจำกัดที่ว่าอ็อบเจ็กต์เปลี่ยนค่าไม่ได้อาจดูเหมือนเป็นการจำกัดโดยไม่จำเป็น แต่ในโค้ดจริงกลับช่วยได้บ่อยครั้ง
  • โค้ดใน Textual ที่ใช้อ็อบเจ็กต์ immutable นั้น ให้เหตุผลง่าย, เหมาะกับการแคช และเอื้อต่อการทดสอบ
  • เหตุผลสำคัญคือมันทำให้เขียนโค้ดที่ไม่มีผลข้างเคียงได้ง่ายขึ้น
    • เมื่อส่งคลาสอินสแตนซ์เข้าไปในฟังก์ชัน จะหลีกเลี่ยงผลข้างเคียงในลักษณะเดียวกันได้ยากกว่า

Unicode art และการทำเอกสาร

  • เมื่ออธิบายเรื่องเชิงเทคนิคด้วยคำพูดอย่างเดียวได้ยาก ไดอะแกรมที่ทำจากอักขระกล่อง Unicode จะช่วยให้เข้าใจเอกสารได้มาก
  • ใน docstring ของ Textual มีการใช้ ไดอะแกรมอักขระกล่อง เพื่ออธิบายเมธอดที่แบ่งพื้นที่ออกเป็นสี่ sub-region
  • ไดอะแกรมแบบนี้ไม่ได้แทนที่ docstring ที่เขียนดีอยู่แล้ว แต่เมื่อใช้ร่วมกันจะช่วยเพิ่มความเข้าใจได้
  • ใช้ monodraw เป็นเครื่องมือวาดไดอะแกรม
    • Monodraw ใช้ได้เฉพาะบน macOS
    • อาจมีทางเลือกอื่นสำหรับแพลตฟอร์มอื่น

ลดความคลาดเคลื่อนของเลย์เอาต์ด้วย fractions.Fraction

  • โมดูล fractions ใน standard library ของ Python มีมาตั้งแต่ Python 2.6
  • Fraction เป็นอีกวิธีหนึ่งในการแทนตัวเลข และเมื่อสร้างแล้วก็สามารถใช้แทน float ได้
  • จำนวนทศนิยมแบบลอยตัวมีข้อจำกัดที่รู้จักกันดี
    • ตัวอย่างเช่น 0.1 + 0.1 + 0.1 == 0.3 ให้ค่าเป็น False
  • ใน Textual ปัญหา ความคลาดเคลื่อนจากการปัดเศษของ floating point เกิดขึ้นในเลย์เอาต์ที่แบ่งหน้าจอตามสัดส่วนหลายระดับ
    • เช่น เมื่อมีพาเนลกว้าง 1/3 ของหน้าจอ แล้วนำ 2/3 ที่เหลือไปแบ่งต่อ อาจเกิดช่องว่างขนาดหนึ่งตัวอักษรได้
  • หากเปลี่ยนจาก float เป็น Fraction ก็จะหลีกเลี่ยงความคลาดเคลื่อนจากการปัดเศษแบบนี้ได้
    • ผลรวมของ Fraction(1, 10) จำนวนสามตัว เท่ากับ Fraction(3, 10)
  • ในตัวอย่างการแบ่งอักขระ 24 ตัวออกเป็น 7 ส่วน เวอร์ชัน float ขาดไปหนึ่งตัวอักษร แต่เวอร์ชัน Fraction เติมความยาวได้ครบ

ความยากของ Emoji บนเทอร์มินัล

  • การรองรับ Emoji เป็นปัญหาต่อเนื่องมาตั้งแต่ยุคแรกของ Rich และ Textual ก็รับปัญหานี้ต่อมาเช่นกัน
  • บนเทอร์มินัล อักขระมักกินพื้นที่หนึ่งช่องหรือสองช่อง และบางอักขระมีความกว้างเป็น 0
    • อักขระ CJK ใช้พื้นที่มากกว่าตัวอักษรตะวันตกเป็นสองเท่า
    • ถ้าต้องการจัดกึ่งกลางหรือวาดกรอบแบบพื้นฐาน ก็จำเป็นต้องรู้ความกว้างบนเทอร์มินัลของข้อความที่จะพิมพ์ออกมา
    • ดังนั้น len(text) เพียงอย่างเดียวจึงไม่บอกความกว้างที่ข้อความกินจริงบนเทอร์มินัล
  • ในฐานข้อมูล Unicode มีการแมประหว่างอักขระความกว้างเดี่ยวและความกว้างคู่
    • Rich และ Textual จะค้นฐานข้อมูลนี้สำหรับทุกอักขระที่ต้องแสดงผล
    • งานนี้ไม่เบา แต่ด้วยการออกแบบวิศวกรรมและการแคชก็ทำให้เร็วพอได้
  • แม้ Emoji จะอยู่ในฐานข้อมูล Unicode แต่เมื่อมี Emoji ใหม่เพิ่มเข้ามาในแต่ละรีลีสของ Unicode ผลลัพธ์ก็ยังคาดเดาได้ยาก
    • เมื่อพิมพ์ Emoji ใหม่ลงเทอร์มินัล มันอาจแสดงผลเป็นหนึ่งช่องหรือสองช่องก็ได้
    • หรืออาจเรนเดอร์ไม่ถูกต้องเลยก็ได้
  • ไม่มีวิธีมาตรฐานที่เชื่อถือได้ในการตรวจจับเวอร์ชัน Unicode ที่เทอร์มินัลอีมูเลเตอร์ใช้อยู่
    • ไม่มี environment variable มาตรฐานด้วย
    • แม้จะมี heuristic ที่พิมพ์ sequence เฉพาะแล้วถามตำแหน่งเคอร์เซอร์ แต่ในการทดสอบ ต่อให้สมมติว่ารู้ฐานข้อมูล Unicode แล้ว เทอร์มินัลก็ยังเรนเดอร์ Emoji อย่างคาดเดาไม่ได้
  • Emoji ที่ประกอบจากหลาย code point ทำให้ปัญหาซับซ้อนขึ้นอีก
    • ตัวอย่างเช่น 👨🏻‍🦰 ประกอบด้วย 4 code point
    • เทอร์มินัลบางตัวอาจเรนเดอร์มันเป็น 4 ตัวอักษร, 2 ตัวอักษร, 1 ตัวอักษร, กว้างหนึ่งช่องหรือสองช่อง, หรือเป็น ? 4 ตัวก็ได้
  • ในทางปฏิบัติ หากใช้ Emoji ระดับ Unicode 9 จะค่อนข้างเสถียรบนหลายแพลตฟอร์ม
    • ต่อให้ Emoji ใหม่และอักขระหลาย code point จะแสดงได้ดีบนเทอร์มินัลปัจจุบัน ก็ควรหลีกเลี่ยงไว้ก่อน

Textualize กำลังรับสมัคร

  • Textualize กำลังรับสมัครเพื่อสร้างเฟรมเวิร์ก TUI ที่สามารถเข้ามาแทนบทบาทบางส่วนของเบราว์เซอร์ได้
  • ดูข้อมูลงานได้ที่ Jobs

1 ความคิดเห็น

 
GN⁺ 2024-08-12
ความคิดเห็นบน Hacker News
  • น่าสนใจที่ นักพัฒนา TUI ทุกคนสุดท้ายก็ต้องเจอกับ Unicode และการจัดการตัวอักษรนานาชาติกับอีโมจิให้ถูกต้องก็กลายเป็นโปรเจกต์แยกอีกชิ้นหนึ่งที่ใหญ่พอ ๆ กับ หรือใหญ่กว่าโปรเจกต์ TUI เดิม
    เรื่องเดียวกันนี้เคยเกิดกับ rivo/tview ด้วย และแพ็กเกจ rivo/uniseg ที่ทำขึ้นมาจากเรื่องนั้นก็ทำให้รู้ว่าผู้ดูแลไลบรารี TUI อื่น ๆ ก็เจอปัญหาเดียวกัน
    ท้ายที่สุด เพราะความกว้างของตัวอักษรไม่ได้ถูกทำให้เป็นมาตรฐาน และเทอร์มินัลก็ซับซ้อน ทุกคนจึงต้องคิดวิธีแก้ของตัวเอง ผู้เขียนบทความรองรับแค่ Unicode 9 แต่ปัจจุบัน Unicode อยู่ที่ 15.1 จึงยากจะมั่นใจว่านี่เป็นทางออกที่ดีหรือไม่ เพราะสักวันหนึ่งคงมีคำบ่นว่าอีโมจิหรือตัวอักษรนานาชาติบางตัวแสดงผลผิด

    • ทางที่ดีที่สุดตอนนี้คือการตรวจจับ mode 2027 และเปิดใช้งานเมื่อรองรับ จากนั้นก็จะรู้ได้ว่าเทอร์มินัลจัดการกราฟีมได้ถูกต้อง
      กำลังดูแลไลบรารี TUI สองตัวที่ใช้เทคนิคนี้อยู่ และการรองรับอีโมจิก็แทบจะยอดเยี่ยมมาก หนึ่งในนั้นใช้ไลบรารี uniseg ด้วย
      https://mitchellh.com/writing/grapheme-clusters-in-terminals
    • สงสัยว่ามีไลบรารีที่ทำ normalization ให้อีโมจิทั้งหมดกลายเป็น สัญลักษณ์เดี่ยว อยู่แล้วหรือไม่
  • ความไม่พอใจใหญ่ที่สุดต่อ textual คือมัน พยายามจะเป็นเหมือน React เข้าใจได้ว่าทำไมถึงเป็นแบบนั้น เพราะเป็นเฟรมเวิร์กยอดนิยมที่หลายคนคุ้นเคย แต่ไม่คิดว่านั่นเป็นวิธีที่ดีในการสร้างส่วนติดต่อผู้ใช้
    แนวทาง reactive design เองเป็นเส้นทางที่พิสูจน์มาแล้ว และการวางสถาปัตยกรรมระบบบนวิธีที่รู้กันว่าทำงานได้ดีก็เป็นวิธีที่ดีในการลดความเสี่ยงของโปรเจกต์
    แต่การเอา CSS เวอร์ชันดัดแปลง มาใช้ด้วยนั้นดูจะเกินไป โมเดลของ React ชอบคอมโพเนนต์ที่เป็นมาตรฐาน ขณะเดียวกันก็ทำลายแนวคิดของ CSS ไปแล้วหลายด้าน และการที่นักพัฒนาปรับแต่งคอมโพเนนต์ด้วย CSS ดูเหมือนเป็นผลข้างเคียงจากวิวัฒนาการของ React มากกว่าจะเป็นสถาปัตยกรรมที่สมเหตุสมผล
    ตอนที่ลองใช้ครั้งล่าสุดต้องใช้ CSS และไม่มีคอมโพเนนต์มาตรฐานดี ๆ เลย ต้องสร้างเอง แทนที่คอมโพเนนต์จะเป็นคลาส Python เดียวที่ encapsulate ได้อย่างสะอาด เอกสารทางการกลับเป็นแนวสร้างคอมโพเนนต์รายการแล้วตกแต่งด้วยสไตล์ชีตภายนอก
    ใน Python ควรมีวิธีที่ชัดเจนหนึ่งวิธีในการทำสิ่งใดสิ่งหนึ่ง และถ้าเป็นไปได้ก็ควรมีแค่วิธีเดียว การตาม React ใกล้เกินไปทำให้ดูเหมือนกำลังตามเอานิสัยแย่ที่สุดของชุมชน JavaScript มาด้วย

    • ไม่จำเป็นต้องใช้ CSS เสมอไป อันที่จริงเป็นแบบนั้นมาตั้งนานแล้ว และสไตล์ทั้งหมดตั้งค่าในโค้ดได้ โดยในเอกสารมี โค้ด CSS และ Python ที่เทียบเท่ากัน สำหรับทุกสไตล์
      เรื่องที่ว่าไม่มีคอมโพเนนต์มาตรฐานดี ๆ ก็ดูเหมือนจะไม่ได้เช็กมานานแล้ว: https://textual.textualize.io/widget_gallery/
    • ไม่ค่อยเข้าใจความรู้สึกที่ว่ามันพยายามจะเป็น React นัก แน่นอนว่ามันพยายามใช้แนวคิดบางอย่างจาก HTML และ CSS หรืออาจรวมถึง JavaScript ด้วย แต่เพราะไม่ต้องเรียนรู้ระบบ UI ใหม่ทั้งหมดตั้งแต่ศูนย์ กลับทำให้เดินหน้าได้เร็วมาก
      ไม่จำเป็นต้องสร้างคอมโพเนนต์เองด้วย และ CSS ก็เป็นสิ่งที่รู้อยู่แล้ว กลับกัน ความแตกต่างเล็กน้อยเรื่อง เลย์เอาต์ และจุดที่เบี่ยงออกจาก CSS ต่างหากที่ทำให้สับสนเป็นบางครั้ง
    • ต้องการวิธี ฝังเทอร์มินัล ไว้ในโปรแกรมกราฟิก ไม่จำเป็นต้องรองรับ terminal emulation จำนวนมาก ขอแค่ตัวเดียวก็พอ โดยให้ macOS มาก่อน และถ้ารองรับแพลตฟอร์มอื่นด้วยก็ดี
      ให้นึกภาพว่าในหน้าต่าง GUI ปกติมีคอมโพเนนต์หนึ่งเป็นหน้าต่างเทอร์มินัล อยากรู้ว่ามีของแบบนี้ไหม หรือควรใช้แค่ text view แบบฟอนต์ความกว้างคงที่
    • อยากให้ช่วยอธิบายเพิ่มว่า textual พยายามจะเป็นเหมือนเฟรมเวิร์ก React อย่างไร ในบทความไม่เห็นมีคำว่า React เลย
    • ถ้า React และโดยทั่วไปแล้ว functional reactive programming ไม่ใช่วิธีที่ดีในการสร้าง UI ก็สงสัยว่าคิดว่าวิธีไหนถึงจะดี
  • TUI นี้ดูสวย แต่ยากจะจินตนาการถึงสถานการณ์ที่ผมจะใช้จริงและถึงขั้นยอมจ่ายเงิน อาจเป็นเพราะผมไม่ได้อยู่ในสภาพแวดล้อมที่เหมาะก็ได้ แต่จากประสบการณ์ของผม ผู้คนมักพอใจกับเครื่องมือที่มินิมอลจริง ๆ หรือไม่ก็หันไปทำ GUI เพื่อให้ผู้ใช้พอใจทันที
    ตัวอย่างเช่น ลิงก์ YouTube ในบทความแสดงตารางที่ไฮไลต์เซลล์ แต่ผมไม่เข้าใจว่าทำไมต้องทำสิ่งนั้นเป็น TUI ถ้าต้องย้ายเซลล์ที่กำลังแอ็กทีฟซึ่งถูกไฮไลต์อยู่ สุดท้ายก็ต้องมีฟีเจอร์อื่น ๆ อีกมาก และท้ายที่สุดน่าจะต้องมี GUI ที่เหมาะสม

    • เหตุผลหนึ่งที่อาจชอบ UI แบบข้อความคือใช้ได้รวดเร็วทุกที่ บนคอมพิวเตอร์เครื่องไหนก็ได้ ไม่ต้องใช้ VNC แบบวิดีโอที่ช้า ถ้าใช้งานเทอร์มินัลอยู่แล้ว การปรับปรุงประสบการณ์นั้นก็เป็นเรื่องดี และมีตลาดใหญ่พอให้บริษัทนี้เล็งได้
      อย่างไรก็ตาม ผมก็ไม่แน่ใจว่า “GUI ที่เหมาะสม” คืออะไร เทอร์มินัลมีมาตรฐานเปิดที่ใช้กันแพร่หลาย และโปรโตคอลเหล่านี้มีความเป็นมาตรฐานและทำงานร่วมกันได้มากกว่าเฟรมเวิร์ก GUI ใด ๆ อีก ทั้งยังรองรับในทุกระบบ
      หากเพิ่มองค์ประกอบอย่างวิดีโอเข้าไปและอุดช่องว่างบางส่วนได้ การจะแข่งขันกับเบราว์เซอร์หรือพาประสบการณ์การใช้งานคอมพิวเตอร์ทั้งหมดมาไว้ในเทอร์มินัลก็ดูสมเหตุสมผล
      แน่นอนว่าเมื่อเทอร์มินัลเพิ่มวิดีโอเข้าไป ก็เท่ากับลอกเลียน rendering pipeline ของ “GUI ที่เหมาะสม” แต่ก็เป็นการปรับปรุงประสบการณ์เทอร์มินัล และถ้าประสบความสำเร็จอย่างมาก ก็อาจมองได้ว่าเป็นการนำ ความเรียบง่ายแบบ UNIX มาสู่ GUI
    • ตัวอย่างเช่น มีงานอย่าง การป้อนข้อมูลเคลมค่ารักษาพยาบาล ที่พนักงานรู้รหัสเคลมทั้งหมด และยังใช้คอนโซลจอเขียว AS400 อยู่
      พนักงานทำงานด้วยคีย์ลัดได้อย่างมีประสิทธิภาพมาก และทุกครั้งที่มีคนพยายามเปลี่ยน AS400 ให้เป็นเว็บแอปสมัยใหม่ ประสิทธิภาพการทำงานจะตกลง 100 เท่า
      เป็นสถานการณ์เดียวกับความแตกต่างระหว่างเซียน Vim/Emacs กับ GUI ที่ดูเนี้ยบแต่ไม่มีคีย์ลัด
    • ตอนนี้มันดูเป็นตลาดเฉพาะอย่างชัดเจน หากต้องการอะไรที่เป็นมิตรกับผู้ใช้มากกว่าบรรทัดคำสั่งล้วน ๆ แต่ด้วยเหตุผลบางอย่าง การให้บริการ Web UI นั้นเสี่ยง TUI ก็อาจเหมาะ
      สามารถให้ผู้ใช้ SSH เข้าเซิร์ฟเวอร์แล้วใช้แอป TUI เหมือนเป็นเชลล์ได้ ซึ่งผมยอมรับว่าเป็นสถานการณ์ที่ค่อนข้างฝืน
      โดยส่วนตัว Textual ใช้งานแล้วรู้สึกแปลก ๆ นิดหน่อย แต่ก็ดีกว่า ncurses อย่างไรก็ตาม มันไม่ได้ให้ผลลัพธ์ที่ผมต้องการ แอปพลิเคชัน TUI แบบเมนเฟรมยุคเก่า ให้ความรู้สึกว่ามีประสิทธิภาพมาก
    • GUI ที่เหมาะสมก็ดี แต่เมื่อจำเป็นต้องทำงานเดียวกันผ่าน การเชื่อมต่อ SSH เรื่องก็เปลี่ยนไป
      บางครั้งมันทำงานได้ดี แต่ค่อนข้างจำกัด เช่น การใช้ X forwarding บนการเชื่อมต่อที่มีแบนด์วิดท์สูง กรณีอื่น ๆ GUI จะหน่วงไปหมด
      GUI แบบข้อความดูเหมือนจะเก็บข้อดีของทั้งสองฝั่งได้
  • วิธี “เคล็ดลับแรกคืออย่าลบ แต่ให้เขียนทับ” เป็นแบบเดียวกับวิธีที่ใช้เขียน เกมยุคก่อน DirectX
    เขียนลง framebuffer โดยตรง และแทนที่จะล้างทั้งหมดแล้ววาดใหม่ ก็วาดเฉพาะส่วนที่เปลี่ยนกับบริเวณรอบ ๆ/ด้านล่างใหม่ เพราะไม่มีเวลาพอที่จะอัปเดตทั้งหน้าจอให้ทัน

    • ตอนนั้นยังมีเทคนิคอื่นอย่างน้อยสองแบบ
      แบบแรกคือเขียนลงบัฟเฟอร์อื่น แล้วเมื่อจบเฟรมก็คัดลอกบัฟเฟอร์ทั้งหมดทีเดียว เพื่อให้แต่ละพิกเซลเปลี่ยนเพียงครั้งเดียว บัฟเฟอร์นี้โดยปกติอาจเป็น RAM ปกติ ไม่ใช่ video RAM
      แบบที่สองคือเขียนลงบัฟเฟอร์อื่นใน video RAM แล้วเปลี่ยนรีจิสเตอร์ของฮาร์ดแวร์กราฟิก เพื่อให้พิกเซลที่แสดงบนจอภาพถูกสร้างจากบัฟเฟอร์นั้น
      จุดแลกเปลี่ยนไม่เหมือนกัน การคัดลอกทั้งบัฟเฟอร์มีต้นทุนสูง ส่วนการเปลี่ยนรีจิสเตอร์ที่อยู่มีต้นทุนต่ำ แต่รายละเอียดของรีจิสเตอร์อาจขึ้นกับฮาร์ดแวร์ และตอนนั้นก็ยังไม่มีเฟรมเวิร์กไดรเวอร์กราฟิกที่เป็นเรื่องเป็นราว
      ถ้าจะทำแค่ “buffer flipping” แม้ตอนเรนเดอร์ไปยังบัฟเฟอร์นอกจอ ก็ยังต้องส่งพิกเซลไปยัง video RAM ซึ่งเท่าที่จำได้ การเข้าถึง video RAM ช้ากว่า RAM ปกติ ในทางปฏิบัติมันเป็นโครงสร้างแบบ NUMA ดังนั้นขึ้นอยู่กับว่าพิกเซลถูกวาดทับบ่อยแค่ไหน การเรนเดอร์ใน RAM ปกติอาจเร็วกว่าโดยรวม แม้จะรวมการคัดลอกครั้งสุดท้ายแล้วก็ตาม
    • ผมเรียนรู้วิธีนี้จากการเขียนโปรแกรม ComputerCraft และหลังจากนั้นมันก็มีประโยชน์หลายครั้ง บางครั้งยังถูกใช้ในงานด้วย
      อย่างไรก็ตาม ผมมองว่าความสามารถในการบอกเทอร์มินัลถึงจุดเริ่มต้นและจุดสิ้นสุดของเฟรมนั้นทรงพลังกว่ามาก
  • ผมไม่เข้าใจจริง ๆ ว่าทำไมวิศวกรซอฟต์แวร์ถึงสนใจ TUI กันมากขนาดนั้น ผมชอบ โปรแกรมบรรทัดคำสั่ง ที่ดี แต่ TUI ไม่ดึงดูดผม

    • หากไม่นับเว็บ TUI ก็แทบจะเป็น ชุดเครื่องมือ GUI ข้ามแพลตฟอร์มที่ติดตั้งอยู่ทั่วไป อีกแบบหนึ่ง
      แถมยังมีกลิ่นอายแฮ็กเกอร์ด้วย สไตล์ไม่ได้ถูกแยกออกจากคอนเทนต์อย่างเข้มงวด และตัวเลือกสไตล์ที่ปรับได้ก็มีจำกัด แอป TUI จึงมักบรรจบไปที่สไตล์เดียวกัน สไตล์นั้นทำให้นึกถึงหนังแฮ็กเกอร์และไซไฟเท่ ๆ
      มันไม่ใช่พื้นที่ที่ดีไซเนอร์องค์กรชอบ และบริษัทต่าง ๆ ก็ไม่ได้ใช้ TUI เป็นเหตุผลในการปิดการขายกับองค์กรหรือผู้บริโภค พอไม่มีแรงกดดันเชิงพาณิชย์แบบนั้น TUI จึงถูกออกแบบโดยนักพัฒนาเพื่อนักพัฒนา
      ดังนั้นมีม TUI จึงเสริมแรงตัวเอง นักพัฒนาเห็นและใช้ TUI แล้วรู้สึกว่ามันเป็นเครื่องมือที่มักทำโดยคำนึงถึงนักพัฒนา จากนั้นก็อยากสร้าง TUI ของตัวเองขึ้นมาอีก
    • เป็นเรื่องของรสนิยม แต่ถึงอย่างนั้น การที่รันแอป ผ่าน SSH ได้ก็เป็นข้อดีใหญ่ คนอย่างผมชอบประสบการณ์ที่รวดเร็วและเน้นคีย์บอร์ด ซึ่งแม้แอป GUI ก็อาจทำได้ แต่โดยปกติมักไม่ทำ
    • ประโยชน์ที่ชัดเจนของการใช้ TUI อาจมีไม่มาก แต่การเขียน TUI มีข้อดีใหญ่ เพราะในหลายแง่มันง่ายกว่า
      การข้ามแพลตฟอร์มแทบได้มาฟรี ๆ ไม่ต้องสร้าง GUI ที่สมบูรณ์แบบระดับพิกเซล และที่จริงก็ทำไม่ได้อยู่แล้ว อีกทั้งไม่ต้องมีไอคอนหรือกราฟิก เพราะแสดงกราฟิกไม่ได้
    • เหมาะเมื่อรันอยู่ในเทอร์มินัลและต้องการ อินเทอร์เฟซผู้ใช้ ที่มากกว่าบรรทัดคำสั่ง บางครั้ง TUI เร็วกว่าบรรทัดคำสั่งและแสดงภาพรวมของสถานการณ์ได้ดีกว่า
    • ผมใช้ CLI เยอะ แต่บางงานเหมาะกับ GUI มากกว่า และ TUI คือพื้นที่กึ่งกลางระหว่าง GUI กับ CLI
      คุณยังใช้ terminal emulator พร้อมฟอนต์ที่ชอบต่อไปได้ ขณะเดียวกันก็มีอินเทอร์เฟซแบบ GUI
      แอป TUI ทั้งหมดที่ผมเคยใช้จนถึงตอนนี้มีเวลาตอบสนองต่ำ แอป GUI ส่วนใหญ่ก็เร็วเช่นกัน แต่แอปที่ช้าจนน่าหงุดหงิดทั้งหมดที่เคยเจอล้วนเป็นแอป GUI
  • มี ascii-draw เป็นทางเลือกแทน Monodraw
    https://github.com/Nokse22/ascii-draw

  • หลังจาก TurboVision แทบทุกอย่างที่ผมเห็นแม้จะได้รับแรงบันดาลใจมา แต่ในทางปฏิบัติกลับยังไม่สมบูรณ์พอ พอลองใช้ toolkit จริง ๆ ก็น่ารักดี แต่รู้สึกเหมือนยังทำไม่เสร็จ
    พูดอีกอย่างได้ว่า TUI framework จำนวนมากที่ผมเห็นเป็นเฟรมเวิร์กแบบ “มีแนวทางชัดเจน”
    บางทีผมอาจจะทึ่มและไม่ค่อยสร้างสรรค์ก็ได้ แต่ตั้งแต่ย้ายจาก DOS ไป Linux ในยุค 90 ผมก็ไม่เคยทำงานได้มีประสิทธิภาพเท่าตอนทำกับ B800 อีกเลย
    เป็นไปได้ว่าผมใช้เวลานานกว่าจะเข้าใจความจำเป็นของ double buffering, ความต่างระหว่าง text mode แบบ local direct กับ terminal รวมถึง escape sequence แต่ถึงอย่างนั้น ทุกครั้งที่พยายามทำอะไรเองด้วย ncurses ก็แทบจะยอมแพ้เพราะความไม่พอใจที่ชัดเจน มันต่างกันสิ้นเชิงกับสิ่งที่ทำได้ด้วยอุดมคติอันเรียบง่ายของ B800

    • ผมเรียนเขียนโปรแกรม GUI ด้วย Win16 แล้วต่อด้วย Win32 ในช่วงที่กำลังเปลี่ยนไปเป็น WinXP
      ไม่รู้ว่ามุมมองของผมถูกบดบังไปทั้งเมืองหรือเปล่า แต่ GUI framework หลังยุค message pump ทั้งหมดนี่เข้าใจยากเหลือเกิน
      โดยเฉพาะผมไม่เข้าใจว่า framework เชิงวัตถุแก้ปัญหา UI แบบหลายเธรดให้จริง ๆ ได้อย่างไร ใน Win32 ผมใส่ renderer หลักไว้ในเธรด แล้วให้ renderer รอง ๆ สร้าง model อยู่ข้าง ๆ จากนั้นอัปเดตเฉพาะส่วนต่าง โค้ดก็ไม่ได้ใหญ่จนรับมือไม่ไหวแต่อย่างใด
    • รู้ว่า Turbo Vision คืออะไร แต่สงสัยว่า B800 คืออะไร คงไม่ได้หมายถึงโปรเซสเซอร์ Celeron แน่ ๆ ค้นหาก็ยาก และดูเหมือนจะไม่มีหน้า wiki ด้วย
  • ถ้าจะรัน kitty ก็ทำอะไรได้มากกว่านั้นอีกเยอะ: https://m.youtube.com/watch?v=ft1Q-DwGWIs
    https://notcurses.com/

    • ผมชอบ WezTerm มากกว่า Kitty เพราะท่าทีของผู้เขียน Kitty ต่อ feature request หรือ pull request
      ทั้งสองตัวใช้ protocol เดียวกันเพื่อแสดงกราฟิกได้ ถ้าจำเป็นต้องใช้กราฟิกจริง ๆ terminal แทบจะไม่ใช่คำตอบที่ถูกต้องอยู่แล้ว แต่บางครั้งก็มีประโยชน์กับของเล็ก ๆ อย่างไอคอน
  • น่าสนใจตรงที่กำลังรับสมัครงานอยู่ อยากรู้ว่าจะวางแผนหาเงินจาก TUI framework อย่างไร

    • สุดท้ายก็มีพูดถึงการรันบนเว็บด้วย ผมเลยเดาว่าตั้งใจจะช่วย migrate TUI เก่า ๆ งาน consulting สำหรับ การบำรุงรักษาซอฟต์แวร์องค์กร รุ่นเก่ามีเงินอยู่พอสมควร
    • ตำแหน่งเหล่านั้นถูกเติมเต็มแล้วภายหลังก็ถูกถอดออกไป: https://blog.davep.org/2024/03/28/goodbye-textualize.html#go...
    • ลิงก์รับสมัครงานขึ้น error 404
    • สงสัยเหมือนกัน ดูเหมือนจะทำซอฟต์แวร์ที่เจ๋งพอสมควร แต่ engineer มีค่าใช้จ่ายสูง และ framework อื่น ๆ ก็มีอยู่แล้ว
  • เผื่อเป็นข้อมูล ผมลองประเมินไลบรารี TUI แบบคอมไพล์ได้ราว 12 ตัว และ FTXUI ใช้ง่ายและเสถียรที่สุด
    https://github.com/ArthurSonzogni/FTXUI
    เป็นเครื่องมือที่ดีสำหรับทำ dashboard แบบ interactive ที่รองรับทั้งคีย์บอร์ดและเมาส์