แก้ไป 2 จุด ครับ
– จุดแรกใช้ and (&) เช็คกับ mask 0x0E00 แทนเช็คด้วยช่วง เพราะตามทฤษฎี bitwise operator จะเร็วกว่า
– จุดสอง แก้บั๊กตาม code review ไปทั้ง 2 ที่ครับ
patch ใหม่: http://review.source.android.com/2894
depends on: http://review.source.android.com/2862
โอเคเลยครับ เร็วขึ้นแน่นอน
อ้อ! เดี๋ยวจะงงกัน อันนี้เป็น Source Code สำหรับนักพัฒนานะครับ ใครโหลด Source ของ Android มาคอมไพล์เองก็สามารถเอา Patch นี้ไปร่วม Compile ได้ครับ
ไว้เดี๋ยวจะเขียนวิธีลงตัว Source Code อีกที ^^
เข้าไปดูแล้ว เหมือนยังตก shift สระอำ หรือปล่าวครับ if-else level แรกน่าจะมี
else if (ch == SARA_AM)
กำลังคิดจะออกแบบใหม่โดยใช้ FSM มาจับครับ คิดว่าน่าจะเร็วขึ้นอีก แต่ต้องแปลง if-else structure กันแบบยกเครื่องครับ
ตัวนี้ผมตั้งใจจะให้แปลงทีหลังอยู่แล้วครับ เพราะผมเน้นที่อ่านง่ายแล้วดูได้ง่ายๆว่า case ครบหรือปล่าวโดย if level แรกมันจะบอกตัวที่ต้องแปลง level สองจะบอกว่า case นี้มี condition ยังไงบ้างและแปลงยังไง ดูแล้วเป็นแบบถึกที่สุดแล้วครับ
ใช่ครับ เพราะมัน maintain ง่ายนี่แหละครับ เลยแก้กันมาได้ขนาดนี้ 🙂
วันนี้ได้ดู code ส่วนอื่นๆที่นอกจาก patch ด้วย พบว่า patch นี้อาจจะมี bug เกี่ยวกับการเก็บสถานะไว้ใน ThaiPreprocessor เพราะ SkGlyphCache จะถูก cache เป็น global และจะถูกเรียกใช้และคืนค่าด้วย attach/detach ดังนั้นสถานะที่อยู่ใน TextPreprocessor จะไม่ถูก reset เมื่อ detach จาก global ทำให้เวลาใช้อาจจะมีค่าเริ่มต้นที่ไม่ถูก ดังนั้นผมเสนอให้เพิ่ม การ reset สถานะของ ThaiPreprocessor ก่อนหรือหลังใช้ทุกครั้ง(attach/detach) เพื่อที่เวลาถูกเรียกด้วยตัวอักษรตัวแรก จะได้มีสถานะที่ถูกต้อง
อันข้างบนเป็นข้อเสนอสำหรับแนวทางเก่า
ถ้าพูดถึงเรื่อง design แล้ว SkGlyphCache ตัวเดิมจะรู้จักแค่ ch ที่ขอ Glyph จาก cache แต่เราได้เพิ่ม ThaiPreprocessor เข้าไปนะลักษณะฝาก instance ไว้เท่านั้น เพราะ ThaiPreprocessor ไม่ได้มีการทำงานร่วมกับข้อมูลใน SkGlyphCache อยู่เลย เหมือนจะอิงแค่ life cycle ของ SkGlyphCache เท่านั้น
ผมเสนอให้ย้าย ThaiPreprocessor instance หรือการทำงานลักษณะที่คล้ายกัน(ถ้าจะเปลี่ยนแปลง)มาไว้ที่ SkPaint เลย เพราะตอนนี้ SkPaint ได้เรียก preprocess method จาก SkGlyphCache แล้ว SkGlyphCache ส่งต่อให้ ThaiPreprocessor อีกที่ซึ่งกลายเป็นว่าทั้งสองตัวต้องผูกกับการ Preprocess
ตัว SkPaint ดูจะสมเหตุสมผล เพราะตัวมันเองรู้จัก Text อยู่แล้ว แต่ SkGlyphCache ไม่ได้รู้จัก text มาก่อน แล้วการเรียกใช้ preprocess ตัว SkGlyphCache ก็ไม่ได้ใช้แต่ได้ส่งต่อให้ ThaiPreprocessor ทำให้เกิด dependency โดยไม่จำเป็นและต้องแก้ code ส่วนนี้ด้วย
จากเรื่องสถานะด้านบน รวมกับจะดึง Preprocessor ออกมาจาก Glyph ผมจึงเสนอดังนี้
1 ย้าย ThaiPreprocessor มาไว้ที่ SkPaint
2 เมื่อไหร่ก็ตามที่มีการเรียก SkPaint::detachCache ให้ reset ThaiPreprocessor
ผมแยกเป็น 2 ประเด็นครับ
1. เรื่องไม่ reset เห็นด้วยว่าอาจจะทำให้เกิด bug
2. ย้าย ThaiPreprocessor มาไว้ที่ SkPaint เป็น instance variable น่าจะทำไม่ได้เพราะว่า SkPaint คุยกับ cache ผ่านการ callback ครับ ไม่ได้เรียกใช้โดยตรง จึงเป็นเหตุผลว่าทำไม่ผมถึงต้องเอา preprocessor ไปฝากไว้กับ cache
ดูตรง code ที่แทรกเข้าไปจะเห็นว่ามีการใช้ trick เรื่อง pointer ดึง static method ออกมากแล้วค่อน pass instance ของ cache เข้าไป
ตรงนี้ hack ได้ถ้าไปแก้ interface ของ static method พวกนั้นครับ
แต่เป็นเรื่องที่ต้องคุยกันยาวหน่อย
พยายามคิดกรณีย้ายไปที่อื่นดูแล้ว หาวิธีที่ clean กว่าวิธีเดิมไม่ได้เลย code ยิ่งจะเละไปใหญ่