วันเสาร์ที่ 29 มกราคม พ.ศ. 2565

Logical operator!!!

พอดีว่าผมต้องทำ method GetDown เอาไว้ใช้เอง เพราะว่าหาใน doc แล้วมันไม่เจอ มีแต่ get value แบบต่อเนื่อง frame by frame

หลักการของมันก็คือจะ return true ก็ต่อเมื่อ state ก่อนหน้าไม่เป็นจริง แต่ state ปัจจุบันเป็นจริง ที่เหลือคือ return  false ทั้งหมด

ตัวอย่าง

ตะกี้ยังไม่ได้กด key A แต่ตอนนี้กด key A แล้ว

แต่มันก็ไม่ได้ง่ายปานนั้น เพราะผมจะต้องเปลี่ยน state เดิมด้วย

ต่อจากตัวอย่างข้างบน

พอตอนนี้กด key A แล้วแต่ไม่ยอมปล่อยมือ ในระหว่างที่กด key A ค้าง ผมก็ไม่ควรได้ return value เป็น true เพราะถ้าได้ true มันก็คือกันกับ get value แบบต่อเนื่อง ใช่มะ

เราก็จะเห็นภาพคร่าวๆแล้วว่า method นี้มันทำงานประมาณนี้

  1. อัพเดต state เสมอ
  2. return true เมื่อ state ก่อนหน้าเป็น false และ state ปัจจุบันเป็น true

ทีนี้พอวิเคราะห์ดูดีๆ จะเห็นว่ามันไม่จำเป็นต้องอัพเดต state ตลอดเวลาหรอก เราแค่ไปอัพเดตมันตอนกด key A ครั้งแรก กับตอนปล่อย key A ก็ได้นี่

สุดท้าย ท้ายสุด method นี้มันก็จะทำงานแบบนี้ 

  1. อัพเดต state เมื่อ state ก่อนหน้า ไม่เท่ากับ state ปัจจุบัน
  2. return true เมื่อ state ก่อนหน้าเป็น false และ state ปัจจุบันเป็น true

ด้วยความมึนของผม ผมเขียนโค้ดออกมาเป็นแบบนี้

โค้ดผมเป็น c# นะ เผื่อวาน syntax ภาษาอื่นมันไม่เหมือนกัน

//
bool prev
bool current
if (!prev && current) {
	prev = true
} else if (prev && !current) {
	prev = false
}
//

พอเห็นมันมี if รุงรังขนาดนี้ก็เลยอยากลดโค้ดลง พอดีนึกถึง logical operator ได้พอดี ในเคสที่เราดูกันนี้มันจะเปลี่ยน state ก็ต่อเมื่อ prev กับ current ไม่เท่ากัน มันก็จะมี operator ตัวนึงที่จะได้ผลเป็น true เมื่อ value ทั้งสองฝั่งไม่เหมือนกันด้วย

มันก็คือ XOR นั่นเอง!!

พอรู้แบบนี้แล้วก็ต้องจัดเลย โอ้แม่เจ้า

//
bool prev
bool current
if (prev ^ current) {
	prev = current
}
//

ซึ่งเอาจริงๆแล้ว มันเขียนแค่นี้ก็ได้คือกัน 555

//
bool prev
bool current
if (prev != current) {
	prev = current
}

ผมควรไปนอนแหละ😴

วันศุกร์ที่ 28 มกราคม พ.ศ. 2565

Code duplication

กลับมาดูโค้ดตัวเอง แล้วก็ตะลึงกับโค้ดที่เขียนซ้ำกันเยอะแยะมาก ลักษณะท่าทางมันก็จะประมาณนี้ 

private void ControllerRaycast(Vector3 origin, Quaternion rot) {
    RaycastHit hit;
    if (Physics.Raycast(origin, rot * Vector3.forward, out hit, 100f, culling))
        // blah
    if (Physics.Raycast(origin, rot * Vector3.forward, out hit, 100f, layerMask)) {
        // blah
    }
}

อันที่จริงรู้สึกว่าจะ concern เรื่อง method ซ้ำมานานแล้ว แต่จำไม่ได้ว่าทำไมตอนนั้นไม่ทำ interface มาให้ class อื่น implement กัน แต่คงเป็นเพราะว่ามี method ชื่อเดียวกันนี้แหละ อันนึงมันรับ argument ไม่เหมือนพวก

วันนี้ก็จัดการรื้อซะเลย ทำ interface มาแล้วก็ implement interface นี้ซะ

ส่วนเรื่อง argument ไม่เหมือนกันก็แยกเป็น 2 interface ไปก่อน คิดว่าไม่ดีเท่าไหร่หรอก แต่ด้วย context มันต่างกันก็พอรับได้มั้ง จะเอามาใส่ใน interface เดียวกันก็แปลกๆที่เวลาจะใช้จะเลือกใช้แค่ method เดียวเท่านั้น

ก็จะได้ประมาณนี้

/// <summary>
/// A simple controller raycast
/// </summary>
public interface IController {
    public void ControllerRaycast(InputDevice device);
}

/// <summary>
/// Yet another simple controller raycast with line renderer
/// </summary>
public interface IRayController {
    public void ControllerRaycast(InputDevice device, LineRenderer line);
}

แต่ท้ายที่สุดแล้วอยากทำเป็น callback มากกว่า ทำการ raycast ครั้งเดียว แล้วก็เรียก callback เอา

ถ้ามีเวลาก็จะมารื้อกันอีกรอบ 😂

วันพฤหัสบดีที่ 27 มกราคม พ.ศ. 2565

รื้องานเก่าตัวเอง ต้อนรับกระแส Metaverse

ผมเพิ่งไปรับงานมา มันเป็นงานเดิมที่ทำเมื่อสมัยจบมหาลัย (คือทำมาตั้งแต่เป็นตัวจบ แล้วก็ได้เอาไปอัพเกรดต่อ โชคดีมากสำหรับงานนี้ ทำให้มีฐานเงินเดือนตั้งต้นโอเคทั้งๆที่มีประสบการณ์นิดหน่อย)

ช่วงนี้พอมีเวลาหน่อยก็เลยต้องปั่นก่อนล่วงหน้าเลย เพราะกลัวจะทำไม่ทัน ไม่ทันขึ้นมาตายแน่ๆ😔

สิ่งแรกที่ผมทำก็คืออัพเกรด version ของ tool ที่ผมใช้เป็นอันใหม่ที่สุด(ซึ่งก็ไม่รู้ว่าเป็นการตัดสินใจที่ฉลาดรึเปล่า แต่มีเวลา cut-off หนีกลับไปใช้อันเดิมอยู่) และแก้ exception มากมายที่แถมมากับการอัพเกรด

จากนั้นก็ทำการเปลี่ยน package สำหรับ VR จาก Oculus Integration -> Unity XR ทำแล้วก็แตกเลยตั้งแต่ใช้ครั้งแรก ทีแรกใช้ plugin provider เป็น oculus เวลาลองเล่นดูละจะเห็นภาพแค่เสี้ยวเดียวทำให้ต้องเทกลับไปใช้ OpenXR ซึ่งยังไม่เจอปัญหาอะไรในการเรนเดอร์ภาพ

หลังจากที่ตกลงปลงใจกับ OpenXR แล้วก็ต้องกลับมารื้อโค้ดส่วนของ input ซึ่งนอกจาก doc จะอ่านยาก(สำหรับผม)แล้ว วิธีการเขียนก็ต่างจากเดิมโดยสิ้นเชิงเหมือนกัน แต่ก็ค่อนข้างชอบเพราะลด code duplication ไปได้ค่อนข้างเยอะเลย

ไว้คราวหลังจะแปะรูปด้วย ตอนนี้ขี้เกียจเหลือหลาย💫

วันจันทร์ที่ 10 มกราคม พ.ศ. 2565

Postgresql's GRANT

ที่สุดความเจ็บปวดแห่งปีคือการเลือกใช้ postgresql
เพราะไม่ได้เลือกใช้ด้วย มันมี feature X, Y, Z ที่ db อื่นไม่มี แค่อยากลองของ

PAIN นึงที่เจอตลอดมาจนถึงตอนนี้เลยคือ user permission
GRANT ALL รอบแล้วรอบเล่าก็ยัง Permission denied!! อิหยังวะ

จนมาเจออันนี้

Make sure you log into psql as the owner of the tables. to find out who own the tables use \dt

psql -h CONNECTION_STRING DBNAME -U OWNER_OF_THE_TABLES

then you can run the GRANTS

คำตอบที่ upvote น้อยๆอันนึง

แม่เจ้า💢 

โพสแรกที่เขียนด้วยความตื้นตันใจและหวังว่าจะไม่ลืมมันอีก
styling ก็เลยจะป่วยๆด้วย แต่คงไม่แก้หรอก มั้ง

Logical operator!!!

พอดีว่าผมต้องทำ method GetDown เอาไว้ใช้เอง เพราะว่าหาใน doc แล้วมันไม่เจอ มีแต่ get value แบบต่อเนื่อง frame by frame หลักการของมันก็คือจะ ...