php – Db class improvements

Hell guys,
does anyone have some improvements for my class ?

<?php

class DB {

    public static function connect(){

        if($GLOBALS("db") != NULL){
            return $GLOBALS("db");
        }

        try{

            $pdo = new PDO("mysql:host=" . DB_SERVER . ";dbname=" . DB_NAME . ";charset=utf8", DB_USERNAME, DB_PASSWORD);
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
            // $pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

        } catch(Exception $e){

            echo($e->getMessage());
            exit;

        }

        $GLOBALS("db") = $pdo;

        return $pdo;

    }

    public static function query($sqlquery, $inserts = array()){

        if($GLOBALS("db") != NULL){
            $db = $GLOBALS("db");
        } else {
            $db = DB::connect();
        }

        $db = DB::connect();

        try {

            $stmt = $db->prepare($sqlquery);
            $stmt->execute($inserts);

        } catch(PDOException $e) {

            echo($e);
            exit;

        }

        //Close DB connection
        $db = null;

        return;

    }

    public static function getDataRows($sqlquery, $inserts = array()){

        if($GLOBALS("db") != NULL){
            $db = $GLOBALS("db");
        } else {
            $db = DB::connect();
        }


        $stmt = $db->prepare($sqlquery);
        $stmt->execute($inserts);

        $fetch = $stmt->fetchAll(PDO::FETCH_ASSOC);

        //Close DB connection
        $db = null;

        return $fetch;
    }

    public static function getDataRow($sqlquery, $inserts = array()){

        if($GLOBALS("db") != NULL){
            $db = $GLOBALS("db");
        } else {
            $db = DB::connect();
        }

        $stmt = $db->prepare($sqlquery);
        $stmt->execute($inserts);

        $fetch = $stmt->fetch(PDO::FETCH_ASSOC);

        //Close DB connection
        $db = null;

        return $fetch;
    }

}

the class works fine at all but i want maybe to improve my class

User Expectation – UX improvements for tabs with access control

Suppose a tab menu like the following example was used.

https://www.w3schools.com/howto/howto_js_tab_header.asp

Each tab has access controls. Some users can see all of the tabs, some users can only see some of the tabs, but all users have permission to at least one of the tabs.

To complicate matters, each tab is part of a single large process. For example, if the page contains multiple tabs, the first tab is used for the first part of a process, the second tab for the second part, and the last tab for the last stage of a process.

Access control is used to control who is involved in each tab.

What is a good user experience for this type of system if the user cannot access these pages / tabs? For example, should the tabs that the user cannot access be removed? The problem with tab removal is that tab continuity is broken.

A simple prototype was created to illustrate the problem.

  1. User1 can access all tabs. This simulates a power user.
  2. User2 can only access tabs 1 and 2. This simulates the user who needs to complete the start part of a particular business process.
  3. User3 can only access tabs 2 and 3. This simulates the user who needs to run the middle part of a particular business process.
  4. User4 can only access tabs 3 and 4. This simulates the user who needs to run the last part of a particular business process.

The query string "User" in the URL is used to determine the current user.

As user 1:
https://yuanfa-ho.outsystemscloud.com/TabswithAccessControl/SimpleForm1.aspx?user=user1

As user 2:
https://yuanfa-ho.outsystemscloud.com/TabswithAccessControl/SimpleForm1.aspx?user=user2

As user 3:
https://yuanfa-ho.outsystemscloud.com/TabswithAccessControl/SimpleForm2.aspx?user=user3

As user 4:
https://yuanfa-ho.outsystemscloud.com/TabswithAccessControl/SimpleForm3.aspx?user=user4

As shown in this example, the Access Denied page works properly so that only the right users can access it. However, the user experience is not good. The user may be confused as to why this is happening and believes that a system error has occurred.

python – pyopenGL OBJ Loader improvements

With the obj loader from pygame as a basis, I created a new obj loader for Python openGL. The loader contains the following functions:

  1. Collect corner points, normals and textures for drawing
  2. Share objects based on materials
  3. Save the vertices, normals, colors and textures of each material in
    separate VAOs
  4. Have an instance of vbo ready for each material
  5. Call up a suitable shader for each material
  6. Draw the entire object as if it were an object

This means that you can call up a single object to be drawn once, i.e. H.

    obj_m = ObjLoader()
    obj_m.load_model("C:/Projects/PythonScripts/GIS/obj_pins/KFC.obj")
    obj_KFC = obj_m.load_obj()

Or, you can use the instance to draw the object in multiple places. H.

    instance_list = ((0,0,0), (-10,0,0), (10,0,0))
    obj_m = ObjLoader()
    obj_m.load_model("C:/Projects/PythonScripts/GIS/obj_pins/KFC.obj", *instance_list)
    obj_KFC = obj_m.load_obj()

Then you can call the object in your drawing loop with or without transformation, i. H.

    obj_m.draw_call(obj_KFC, view, projection, model)

or

    transform = glm.mat4(1.0)
    transform = glm.rotate(transform, glfw.get_time(), glm.vec3(0.0, 1.0, 1.0))
    transform = glm.scale(transform, glm.vec3(1.0, 1.0, 1.0))

    obj_m.draw_call(obj_KFC, view, projection, model, transform)

Output:
Instantiated object

I recently started using OpenGL for fun and am not a programmer per se. So over time, I've implemented features for the object loader. The code is therefore neither "pretty" nor extensively tested and mostly without an additional error checking code. These are the known disadvantages:

  1. The OBJ file should be triangulated, i.e. H. With a mixer:

Triangulate object

  1. The .obj, .mtl and the image (if a material contains a texture) must be
    be in the same folder
  2. The link to the texture in the .mtl folder should be relative and therefore only contain the name of the image, i.e. H. map_Kd 3D_kfc.png

I thought I would share the code because, as I said, I'm not a programmer per se, but I think others can benefit, especially if the code is "cleaner". So the questions:

  1. Are there any obvious structural improvements?
  2. Are there any obvious improvements to the code?
  3. Are there any desired improvements, e.g. B. lighting?
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader
import os
import glm
from PIL import Image


class ObjLoader:
    def __init__(self):
        self.vert_coords = ()
        self.text_coords = ()
        self.norm_coords = ()
        self.object_parts = {}
        self.setup_index()
        self.obj_shaders()

    def setup_index(self):

        self.material_index = ()
        self.vertex_index = ()
        self.texture_index = ()
        self.normal_index = ()
        self.model = ()
        self.material_index = ()
        self.vertex_index = ()
        self.texture_index = ()
        self.normal_index = ()

    def load_model(self, file, *args):

        for line in open(file, 'r'):
            if line.startswith('#'): continue
            values = line.split()
            if not values: continue
            if values(0) == 'v':
                self.vert_coords.append(values(1:4))
            if values(0) == 'vt':
                self.text_coords.append(values(1:3))
            if values(0) == 'vn':
                self.norm_coords.append(values(1:4))
            if values(0) == 'mtllib':
                self.mtl = values(1)
                matarials = self.mat_in_file(file)


        m_counter = 0
        for line in open(file, 'r'):  # open(file, 'r'):
            if line.startswith('#'): continue
            values = line.split()
            if not values: continue
            if values(0) == 'usemtl':
                if values(1) != matarials(m_counter)(0):
                    self.define_i_t_u(file, matarials(m_counter), args)
                    m_counter += 1
                    self.setup_index()
            if values(0) == 'f':
                face_i = ()
                text_i = ()
                norm_i = ()
                for v in values(1:4):
                    w = v.split('/')
                    face_i.append(int(w(0)) - 1)
                    text_i.append(int(w(1)) - 1)
                    norm_i.append(int(w(2)) - 1)

                self.vertex_index.append(face_i)
                self.texture_index.append(text_i)
                self.normal_index.append(norm_i)

        self.define_i_t_u(file, matarials(m_counter), args)

    def define_i_t_u(self, file, mat, args):
        self.vertex_index = (y for x in self.vertex_index for y in x)
        self.texture_index = (y for x in self.texture_index for y in x)
        self.normal_index = (y for x in self.normal_index for y in x)

        for i in self.vertex_index:
            self.model.extend(self.vert_coords(i))
        for i in self.texture_index:
            self.model.extend(self.text_coords(i))
        for i in self.normal_index:
            self.model.extend(self.norm_coords(i))
        self.model = np.array(self.model, dtype='float32')

        glUseProgram(mat(1))
        texid = self.MTL(file)
        l_vao = self.vao_creator(self.vertex_index, self.model, mat(1), mat(2), texid, args)
        self.object_parts("{0}".format(mat(0))) = l_vao

    def MTL(self, filename):
        filename = os.path.splitext(filename)(0) + '.mtl'
        filepath = os.path.dirname(filename)
        base = os.path.basename(filename)
        file_only_name = os.path.splitext(base)(0)
        contents = {}
        mtl = None
        image = None
        texid = None
        surf = None
        values = ()
        for line in open(filename, "r"):
            if line.startswith('#'): continue
            values = line.split()
            if not values: continue
            if values(0) == 'newmtl':
                mtl = contents(values(1)) = {}
            elif mtl is None:
                raise ValueError("mtl file doesn't start with newmtl stmt")
            elif values(0) == 'map_Kd':
                self.object_shader = self.shader_obj_text
                # load the texture referred to by this declaration
                mtl(values(0)) = values(1)

                texid = mtl('texture_Kd') = glGenTextures(1)

                glBindTexture(GL_TEXTURE_2D, texid)

                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                                GL_LINEAR)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                                GL_LINEAR)

                image = Image.open(os.path.join(filepath, mtl('map_Kd')))
                flipped_image = image.transpose(Image.FLIP_TOP_BOTTOM)
                img_data = flipped_image.convert("RGBA").tobytes()
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                             img_data)

        return texid


    def vao_creator(self, vertex_index, model, shader, defuse_col, texid, args):
        texture_offset = len(vertex_index) * 12
        VAO = glGenVertexArrays(1)
        glBindVertexArray(VAO)
        VBO = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, VBO)
        glBufferData(GL_ARRAY_BUFFER, model.itemsize * len(model), model, GL_STATIC_DRAW)
        # position
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, model.itemsize * 3, ctypes.c_void_p(0))
        glEnableVertexAttribArray(0)
        # texture
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, model.itemsize * 2, ctypes.c_void_p(texture_offset))
        glEnableVertexAttribArray(1)
        # Normals
        glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, model.itemsize * 3, ctypes.c_void_p(12))
        glEnableVertexAttribArray(2)

        # Instancing
        if len(args) == 0:
            amount = 1
            vert_instance = np.array(((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)))
        else:
            amount = len(args)
            vert_instance = np.array(args)

        modelMatrices = ()
        # Storring the objects in a list
        for i in range(0, amount):
            mod_list = ()
            model_o = glm.mat4(1.0)
            model_o = glm.translate(model_o, glm.vec3(vert_instance(i)(0), vert_instance(i)(1), vert_instance(i)(2)))
            # model_o = glm.scale(model_o, glm.vec3(0.00005, 0.00005, 0.00005))
            for i in range(4):
                for j in range(4):
                    mod_list.append(model_o(i)(j))
            modelMatrices.append(mod_list)
        modelMatrices = np.array(modelMatrices, dtype="f")

        instanceVBO = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, instanceVBO)

        glBufferData(GL_ARRAY_BUFFER, amount * glm.sizeof(glm.mat4), modelMatrices, GL_STATIC_DRAW)
        # Bind each vertex attrib array of matrices (4 vectors in Matrix)
        glEnableVertexAttribArray(3)
        glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, glm.sizeof(glm.mat4), ctypes.c_void_p(0))
        glEnableVertexAttribArray(4)
        glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, glm.sizeof(glm.mat4), ctypes.c_void_p(glm.sizeof(glm.vec4)))
        glEnableVertexAttribArray(5)
        glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, glm.sizeof(glm.mat4),
                              ctypes.c_void_p((2 * glm.sizeof(glm.vec4))))
        glEnableVertexAttribArray(6)
        glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, glm.sizeof(glm.mat4),
                              ctypes.c_void_p((3 * glm.sizeof(glm.vec4))))
        # Set instancing
        glVertexAttribDivisor(3, 1)
        glVertexAttribDivisor(4, 1)
        glVertexAttribDivisor(5, 1)
        glVertexAttribDivisor(6, 1)

        glBindVertexArray(0)

        return ((VAO, len(vertex_index), shader, defuse_col, texid, len(vert_instance)))

    def mat_in_file(self, filename):
        filename = os.path.splitext(filename)(0) + '.mtl'
        mtl = None
        contents = {}
        mat_list = ()
        for line in open(filename, "r"):
            if line.startswith('#'): continue
            values = line.split()
            if not values: continue
            if values(0) == 'newmtl':
                object_shader = self.shader_obj
                mtl = contents(values(1)) = {}
                matname = values(1)

            elif mtl is None:
                raise ValueError("mtl file doesn't start with newmtl stmt")
            elif values(0) == 'Kd':
                defuse_col = (float(values(1)), float(values(2)), float(values(3)))
            elif values(0) == 'd':
                defuse_col = defuse_col + (float(values(1)))
                mat_list.append((matname, object_shader, defuse_col))
            elif values(0) == 'map_Kd':
                object_shader = self.shader_obj_text
                mat_list.pop()
                mat_list.append((matname, object_shader, defuse_col))


        return mat_list

    def load_obj(self):
        obj_list = (self.object_parts(ind) for ind in self.object_parts)
        return obj_list

    def draw_call(self, vao_list, view, projection, model, *transf):

        if len(transf) == 0:
            transform = glm.mat4(1.0)
        else:
            transform = transf(0)

        for key in vao_list:
            VAO = key(0)
            vertex_len = key(1)
            shader = key(2)
            d_colour = key(3)
            texid = key(4)
            len_instanced = key(5)

            glUseProgram(shader)
            glBindTexture(GL_TEXTURE_2D, texid)
            view_loc = glGetUniformLocation(shader, "view")
            proj_loc = glGetUniformLocation(shader, "projection")
            model_loc = glGetUniformLocation(shader, "model")
            col_loc = glGetUniformLocation(shader, "mycolor")

            glUniformMatrix4fv(view_loc, 1, GL_FALSE, view)
            glUniformMatrix4fv(proj_loc, 1, GL_FALSE, projection)
            glUniformMatrix4fv(model_loc, 1, GL_FALSE, model)

            glUniform4fv(col_loc, 1, glm.value_ptr(glm.vec4(d_colour)))

            transformLoc = glGetUniformLocation(shader, "transform")
            glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm.value_ptr(transform))

            glBindVertexArray(VAO)
            glDrawArraysInstanced(GL_TRIANGLES, 0, vertex_len, len_instanced)
            glBindVertexArray(0)

    def obj_shaders(self):
        vertex_obj = """
                                   # version 330
                                    in layout(location = 0) vec3 position;
                                    in layout(location = 1) vec2 textureCoords;
                                    in layout(location = 2) vec3 normalCoords;
                                    in layout (location = 3) mat4 instanceMatrix;

                                    uniform mat4 transform;

                                    uniform mat4 view;
                                    uniform mat4 model;
                                    uniform mat4 projection;

                                    out vec2 newTexture;
                                    out vec3 newNorm;


                                    void main()
                                    {
                                        gl_Position = projection * view *instanceMatrix *model * transform *vec4(position, 1.0f);
                                        newTexture = textureCoords;
                                        newNorm = normalCoords;

                                    }

                                   """
        fragment_obj = """
                                  #version 330
                                    in vec2 newTexture;
                                    in vec3 newNorm;

                                    uniform vec4 mycolor;

                                    out vec4 outColor;
                                    uniform sampler2D samplerTexture;
                                    void main()
                                    {
                                        outColor = mycolor;
                                        }
                                    """
        fragment_obj_text = """
                                          #version 330
                                            in vec2 newTexture;
                                            in vec3 newNorm;
                                            in vec3 out_colours;

                                            uniform vec4 mycolor;

                                            out vec4 outColor;
                                            uniform sampler2D samplerTexture;
                                            void main()
                                            {
                                                outColor = texture(samplerTexture, newTexture);

                                            }
                                            """

        self.shader_obj = compileProgram(compileShader(vertex_obj, GL_VERTEX_SHADER),
                                         compileShader(fragment_obj, GL_FRAGMENT_SHADER))

        self.shader_obj_text = compileProgram(compileShader(vertex_obj, GL_VERTEX_SHADER),
                                              compileShader(fragment_obj_text, GL_FRAGMENT_SHADER))
import glfw
import pyrr
from ObjLoader import *

def window_resize(window, width, height):
    glViewport(0, 0, width, height)

def main():

    # initialize glfw
    if not glfw.init():
        return

    w_width, w_height = 800, 600
    window = glfw.create_window(w_width, w_height, "My OpenGL window", None, None)

    if not window:
        glfw.terminate()
        return

    glfw.make_context_current(window)
    glfw.set_window_size_callback(window, window_resize)


    instance_list = ((0,0,0), (-10,0,0), (10,0,0))
    obj_m = ObjLoader()
    obj_m.load_model("C:/Projects/PythonScripts/GIS/obj_pins/KFC.obj", *instance_list)
    obj_KFC = obj_m.load_obj()


    glClearColor(0.2, 0.3, 0.2, 1.0)
    glEnable(GL_DEPTH_TEST)


    view = pyrr.matrix44.create_from_translation(pyrr.Vector3((0.0, 0.0, -20.0)))
    projection = pyrr.matrix44.create_perspective_projection_matrix(65.0, w_width / w_height, 0.1, 100.0)
    model = pyrr.matrix44.create_from_translation(pyrr.Vector3((0.0, 0.0, 0.0)))

    while not glfw.window_should_close(window):
        glfw.poll_events()
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)


        #obj_m.draw_call(obj_KFC, view, projection, model)

        transform = glm.mat4(1.0)
        transform = glm.rotate(transform, glfw.get_time(), glm.vec3(0.0, 1.0, 1.0))
        transform = glm.scale(transform, glm.vec3(1.0, 1.0, 1.0))
        obj_m.draw_call(obj_KFC, view, projection, model, transform)



        glfw.swap_buffers(window)

    glfw.terminate()

if __name__ == "__main__":
    main()

unit – Unity3D, modification of the voxel-chunk network: further performance improvements

I flattened my 3D chunk array (nice speed of 20 ms) and changed my VertexData structure (which I use as a key in the dictionary) to include a custom hash code (another 20 ms and -2.7 MB GC .alloc data speed). But I'm not sure what to do next, since 40 ms still feel long for such a small part (in fact, it's twice the size of Minecraft's 16x256x16 and still manages to be slower).

My biggest bottleneck still seems to be the dictionary.

This is the current performance profile:

Enter the image description here

The code:

public void MakeChunk()
    {

        vertexCount = 0;
        //these are all Lists except verticesDictionary
        vertices.Clear();
        normals.Clear();
        verticesDict.Clear();
        uvs.Clear();
        triangles.Clear();

        int len = 32 * 32 * 32;

        for (int i = 0; i < len; i++)
        {
            int cubeType = data.raw(i);
            if (cubeType != 0)
            {
                int x = i % 32;
                int y = (i / 32) % 32;
                int z = i / (32 * 32);
                MakeCube(x, y, z, cubeType);
                blocksGenerated++;
            }
        }
    }
    void MakeCube(int x, int y, int z, int cubeType)
    {
        for (int i = 0; i < 6; i++)
        {
            Direction dir = (Direction)i;
            if (data.GetNeighbor(x, y, z, dir) == 0)
            {
                MakeFace(dir, x, y, z, cubeType);
            }
        }
    }
    void MakeFace(Direction dir, int x, int y, int z, int cubeType)
    {
        VertexSignature signature;
        signature.normal = dir;

        Vector3() faceVertices = CubeMeshData.faceVertices((int)dir, x, y, z);
        int() triangleIndices = new int(4);
        signature.cubeType = cubeType;

        for (int i = 0; i < 4; i++)
        {
            signature.position = faceVertices(i);
            Vector3 uv = CubeMeshData.ProjectPositionToUV(signature.position, dir);
            uv.z = signature.cubeType;

            int vertex = GetVertexIndex(signature);
            triangleIndices(i) = vertex;
        }

        triangles.AddRange(new int(6) {
            triangleIndices(0),
            triangleIndices(1),
            triangleIndices(2),
            triangleIndices(0),
            triangleIndices(2),
            triangleIndices(3)
            }
        );


    }
    void PrepareMeshData()
    {
        foreach (var pair in verticesDict)
        {
            int index = pair.Value;
            vertices.Add(pair.Key.position);
            CubeMeshData.DataCoordinate coord = CubeMeshData.offsets((int)pair.Key.normal);
            normals.Add(new Vector3(coord.x, coord.y, coord.z));

            Vector3 uv = CubeMeshData.ProjectPositionToUV(pair.Key.position, pair.Key.normal);
            uv.z = pair.Key.cubeType;
            uvs.Add(uv);
        }
    }

Hashing:

 struct VertexSignature
    {
        public Vector3 position;
        public Direction normal;
        public int cubeType;

        public override int GetHashCode()
        {
            uint h = 0x811c9dc5;
            h = (h ^ (uint)position.x) * 0x01000193;
            h = (h ^ (uint)position.y) * 0x01000193;
            h = (h ^ (uint)position.z) * 0x01000193;
            h = (h ^ (uint)normal) * 0x01000193;
            h = (h ^ (uint)cubeType) * 0x01000193;

            return (int)h;
        }
    };

Then I do this:

    Vector3() vertexArr = vertices.ToArray();
    int() triArr = triangles.ToArray();
    Vector3() normalsArr = normals.ToArray();

I really have no more ideas on how to further improve performance.

Any help is welcome.

C # – Data access layer improvements

 public class EmployeeDBHandler
    {
        public List GetEmployees()
        {
            List empList = new List();
            string sqlConnstr = Utils.GetDBConnection();
            SqlConnection sqlConn = new SqlConnection(sqlConnstr);
            SqlCommand sqlCmd = new SqlCommand("GetAllEmployee", sqlConn);
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlConn.Open();
            using (SqlDataReader reader = sqlCmd.ExecuteReader())
            { 
                while (reader.Read())
                {
                    var emp = new Employee()
                    {
                        EId = (int)(reader("EmpID")),
                        FirstName = Convert.ToString(reader("FirstName")),
                        LastName = Convert.ToString(reader("LastName"))                        
                    };
                    empList.Add(emp);
                }
            }
            return empList;
        }
        public List FetchEmployee(int empid)
        {
            List empList = new List();
            string sqlConnstr = Utils.GetDBConnection();
            SqlConnection sqlConn = new SqlConnection(sqlConnstr);
            SqlCommand sqlCmd = new SqlCommand("usp_FetchEmployeeDetails", sqlConn);
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlCmd.Parameters.AddWithValue("@EmpID", empid);
            sqlConn.Open();
            using (SqlDataReader reader = sqlCmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    var emp = new Employee()
                    {
                        EId = (int)(reader("EmpID")),
                        FirstName = (reader("FirstName").ToString()),
                        LastName = (reader("LastName").ToString())
                    };
                    empList.Add(emp);
                }
            }
            return empList;
        }
        public void AddEmployeeInfo(string firstname, string lastname)
        {
            string sqlConnstr = Utils.GetDBConnection();
            SqlConnection sqlConn = new SqlConnection(sqlConnstr);
            SqlCommand sqlCmd = new SqlCommand("AddEmployee", sqlConn);
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlCmd.Parameters.AddWithValue("@FirstName", firstname);
            sqlCmd.Parameters.AddWithValue("@LastName", lastname);
            sqlConn.Open();
            sqlCmd.ExecuteNonQuery();
            sqlConn.Close();
        }
        public void UpdateEmployee(int empid,string firstname, string lastname)
        {
            string sqlConnstr = Utils.GetDBConnection();
            SqlConnection sqlConn = new SqlConnection(sqlConnstr);
            SqlCommand sqlCmd = new SqlCommand("usp_UpdateEmployeeDetails", sqlConn);
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlCmd.Parameters.AddWithValue("@EmpID", empid);
            sqlCmd.Parameters.AddWithValue("@FirstName", firstname);
            sqlCmd.Parameters.AddWithValue("@LastName", lastname);
            sqlConn.Open();
            sqlCmd.ExecuteNonQuery();
            sqlConn.Close();
        }
        public void DeleteEmployee(int empid)
        {
            string sqlConnstr = Utils.GetDBConnection();
            SqlConnection sqlConn = new SqlConnection(sqlConnstr);
            SqlCommand sqlCmd = new SqlCommand("usp_DeleteEmployeeDetails", sqlConn);
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlCmd.Parameters.AddWithValue("@EmpID",empid);
            sqlConn.Open();
            sqlCmd.ExecuteNonQuery();
            sqlConn.Close();
        }

    }

I am trying to build a three-level arch. However, I think this code can be improvised. So please check the data access layer code above and make suggestions and corrections if necessary to improvise my code.

mesh – Unity: Improvements in the performance of skinnedMeshRender.BakeMesh or alternatives?

I run into a situation where I have to do some manual deformation at the mesh vertices of a skinnedMeshRenderer after doing some blend skinning. I find the code below takes ~ 15ms to run. I calculated the time by running it 100 times and measuring the time difference and using the Unity Profiler.

Mesh bakedMesh = new Mesh();
skinnedMeshRenderer.BakeMesh(bakedMesh);

The network has ~ 7000 corner points.

I just need a loop through each vertex to get its current (combination skin) position relative to the local origin of its gameObject. The goal is to calculate the amount of deformation it has experienced.

something like (pseudocode):

for i in vertices
    deformation(i) = originalVerticies(i) - bakedCertices(i)

It is the call BakeMesh that slows down the things that are needed to get bakedVertices(i),

Is there any other way to get backedVerticies (i) without actually baking the net? Maybe a kind of manual calculation to simulate baking, but only on the corner points? or maybe a way to speed up the baking process?


Additional information:

The reason why I calculate the deformation is to undo the automatic linear crossfading of Unity because I want to move some bones at runtime without affecting the mesh. However, when I move the bones, Unity's automatic linear blend skinning activates and deforms the mesh. This way it can be calculated how much it has been deformed, so that I can "undo" this blend skinning by adding the deformation back to the vertices. Perhaps there is a more elegant solution, but I cannot find a way to temporarily switch off automatic linear combination skin formation. Note that I have to do this for each frame individually.

I am currently at 15ms for this script that is really pushing the 16ms limit to maintain 60fps. If I add other scripts, etc. to the scene, it is definitely delayed. I also want it to run at a minimum of 90 fps as I hope to use this script in VR in the future.

ide – AI code completion: productivity improvements in real life

I have read interesting material about AI-based autocompletion (e.g.: (Deep TabNine)(1)). The advantage is that integrating these tools into an IDE improves developer productivity.

My question is, has anyone used any of these tools on large projects for a significant amount of time? If so, what was your experience like, where have there been real productivity improvements? I want to hear both positive and negative experiences.

Where is the risk of incremental improvements compared to redesigning the entire app?

I am working on legacy software based on Java 6, the design is old and the components look like Windows 98. We are introducing a new major feature and one of the requirements is to make the feature more functional 2020 look and feel trendy. (to show that something is changing)

I fear that if we start a function that looks completely different from anything else in the application, this could affect the consistency and user experience. Should we design the new function with the components that we currently have in the current app? In this way, we focus more on value than aesthetics and can redesign everything once and for all later this year

Javascript – Prettier Pug Plugin – performance, documentation, division, regex improvements

import { Doc, FastPath, format, Options, Parser, ParserOptions, Plugin, util } from 'prettier';
import * as lex from 'pug-lexer';
import { AttributeToken, EndAttributesToken, Token } from 'pug-lexer';
import { DOCTYPE_SHORTCUT_REGISTRY } from './doctype-shortcut-registry';
import { createLogger, Logger, LogLevel } from './logger';
import {
  formatCommentPreserveSpaces,
  options as pugOptions,
  PugParserOptions,
  resolveAttributeSeparatorOption
} from './options';

const { makeString } = util;

const logger: Logger = createLogger(console);
if (process.env.NODE_ENV === 'test') {
  logger.setLogLevel(LogLevel.DEBUG);
}

function previousNormalAttributeToken(tokens: Token(), index: number): AttributeToken | undefined {
  for (let i: number = index - 1; i > 0; i--) {
    const token: Token = tokens(i);
    if (token.type === 'start-attributes') {
      return;
    }
    if (token.type === 'attribute') {
      if (token.name !== 'class' && token.name !== 'id') {
        return token;
      }
    }
  }
  return;
}

function printIndent(previousToken: Token, indent: string, indentLevel: number): string {
  switch (previousToken?.type) {
    case 'newline':
    case 'outdent':
      return indent.repeat(indentLevel);
    case 'indent':
      return indent;
  }
  return '';
}

function formatText(text: string, singleQuote: boolean): string {
  let result: string = '';
  while (text) {
    const start = text.indexOf('{{');
    if (start !== -1) {
      result += text.slice(0, start);
      text = text.substring(start + 2);
      const end = text.indexOf('}}');
      if (end !== -1) {
        let code = text.slice(0, end);
        code = code.trim();
        code = format(code, { parser: 'babel', singleQuote: !singleQuote, printWidth: 9000 });
        if (code.endsWith(';n')) {
          code = code.slice(0, -2);
        }
        result += `{{ ${code} }}`;
        text = text.slice(end + 2);
      } else {
        result += '{{';
        result += text;
        text = '';
      }
    } else {
      result += text;
      text = '';
    }
  }
  return result;
}

function unwrapLineFeeds(value: string): string {
  return value.includes('n')
    ? value
        .split('n')
        .map((part) => part.trim())
        .join('')
    : value;
}

export const plugin: Plugin = {
  languages: (
    {
      name: 'Pug',
      parsers: ('pug'),
      tmScope: 'text.jade',
      aceMode: 'jade',
      codemirrorMode: 'pug',
      codemirrorMimeType: 'text/x-pug',
      extensions: ('.jade', '.pug'),
      linguistLanguageId: 179,
      vscodeLanguageIds: ('jade')
    }
  ),
  parsers: {
    pug: {
      parse(text: string, parsers: { (parserName: string): Parser }, options: ParserOptions): Token() {
        logger.debug('(parsers:pug:parse):', { text });
        const tokens = lex(text);
        // logger.debug('(parsers:pug:parse): tokens', JSON.stringify(tokens, undefined, 2));
        // const ast: AST = parse(tokens, {});
        // logger.debug('(parsers:pug:parse): ast', JSON.stringify(ast, undefined, 2));
        return tokens;
      },
      astFormat: 'pug-ast',
      hasPragma(text: string): boolean {
        return text.startsWith('//- @prettiern') || text.startsWith('//- @formatn');
      },
      locStart(node: any): number {
        logger.debug('(parsers:pug:locStart):', { node });
        return 0;
      },
      locEnd(node: any): number {
        logger.debug('(parsers:pug:locEnd):', { node });
        return 0;
      },
      preprocess(text: string, options: ParserOptions): string {
        logger.debug('(parsers:pug:preprocess):', { text });
        return text;
      }
    }
  },
  printers: {
    'pug-ast': {
      print(
        path: FastPath,
        {
          printWidth,
          singleQuote,
          tabWidth,
          useTabs,
          attributeSeparator,
          commentPreserveSpaces,
          semi
        }: ParserOptions & PugParserOptions,
        print: (path: FastPath) => Doc
      ): Doc {
        const tokens: Token() = path.stack(0);

        let result: string = '';
        let indentLevel: number = 0;
        let indent: string = ' '.repeat(tabWidth);
        if (useTabs) {
          indent = 't';
        }
        let pipelessText: boolean = false;
        let pipelessComment: boolean = false;

        const alwaysUseAttributeSeparator: boolean = resolveAttributeSeparatorOption(attributeSeparator);

        let startTagPosition: number = 0;
        let startAttributePosition: number = 0;
        let previousAttributeRemapped: boolean = false;
        let wrapAttributes: boolean = false;

        const codeInterpolationOptions: Options = {
          singleQuote: !singleQuote,
          printWidth: 9000,
          endOfLine: 'lf'
        };

        if (tokens(0)?.type === 'text') {
          result += '| ';
        }

        for (let index: number = 0; index < tokens.length; index++) {
          const token: Token = tokens(index);
          const previousToken: Token | undefined = tokens(index - 1);
          const nextToken: Token | undefined = tokens(index + 1);
          logger.debug('(printers:pug-ast:print):', JSON.stringify(token));
          switch (token.type) {
            case 'tag':
              result += printIndent(previousToken, indent, indentLevel);
              if (!(token.val === 'div' && (nextToken.type === 'class' || nextToken.type === 'id'))) {
                result += token.val;
              }
              startTagPosition = result.length;
              break;
            case 'start-attributes':
              if (nextToken?.type === 'attribute') {
                previousAttributeRemapped = false;
                startAttributePosition = result.length;
                result += '(';
                const start: number = result.lastIndexOf('n') + 1;
                let lineLength: number = result.substring(start).length;
                logger.debug(lineLength, printWidth);
                let tempToken: AttributeToken | EndAttributesToken = nextToken;
                let tempIndex: number = index + 1;
                while (tempToken.type === 'attribute') {
                  lineLength += tempToken.name.length + 1 + tempToken.val.toString().length;
                  logger.debug(lineLength, printWidth);
                  tempToken = tokens(++tempIndex) as AttributeToken | EndAttributesToken;
                }
                if (lineLength > printWidth) {
                  wrapAttributes = true;
                }
              }
              break;
            case 'attribute': {
              if (typeof token.val === 'string') {
                const surroundedByQuotes: boolean =
                  (token.val.startsWith('"') && token.val.endsWith('"')) ||
                  (token.val.startsWith("'") && token.val.endsWith("'"));
                if (surroundedByQuotes) {
                  if (token.name === 'class') {
                    // Handle class attribute
                    let val = token.val;
                    val = val.substring(1, val.length - 1);
                    val = val.trim();
                    val = val.replace(/ss+/g, ' ');
                    const classes: string() = val.split(' ');
                    const specialClasses: string() = ();
                    const validClassNameRegex: RegExp = /^-?(_a-zA-Z)+(_a-zA-Z0-9-)*$/;
                    for (const className of classes) {
                      if (!validClassNameRegex.test(className)) {
                        specialClasses.push(className);
                        continue;
                      }
                      // Write css-class in front of attributes
                      const position: number = startAttributePosition;
                      result = (
                        result.slice(0, position),
                        `.${className}`,
                        result.slice(position)
                      ).join('');
                      startAttributePosition += 1 + className.length;
                      result = result.replace(/div./, '.');
                    }
                    if (specialClasses.length > 0) {
                      token.val = makeString(
                        specialClasses.join(' '),
                        singleQuote ? "'" : '"',
                        false
                      );
                      previousAttributeRemapped = false;
                    } else {
                      previousAttributeRemapped = true;
                      break;
                    }
                  } else if (token.name === 'id') {
                    // Handle id attribute
                    let val = token.val;
                    val = val.substring(1, val.length - 1);
                    val = val.trim();
                    const validIdNameRegex: RegExp = /^-?(_a-zA-Z)+(_a-zA-Z0-9-)*$/;
                    if (!validIdNameRegex.test(val)) {
                      val = makeString(val, singleQuote ? "'" : '"', false);
                      result += `id=${val}`;
                      break;
                    }
                    // Write css-id in front of css-classes
                    const position: number = startTagPosition;
                    result = (result.slice(0, position), `#${val}`, result.slice(position)).join(
                      ''
                    );
                    startAttributePosition += 1 + val.length;
                    result = result.replace(/div#/, '#');
                    if (previousToken.type === 'attribute' && previousToken.name !== 'class') {
                      previousAttributeRemapped = true;
                    }
                    break;
                  }
                }
              }

              const hasNormalPreviousToken: AttributeToken | undefined = previousNormalAttributeToken(
                tokens,
                index
              );
              if (
                previousToken?.type === 'attribute' &&
                (!previousAttributeRemapped || hasNormalPreviousToken)
              ) {
                if (alwaysUseAttributeSeparator || /^((|(|:).*/.test(token.name)) {
                  result += ',';
                }
                if (!wrapAttributes) {
                  result += ' ';
                }
              }
              previousAttributeRemapped = false;

              if (wrapAttributes) {
                result += 'n';
                result += indent.repeat(indentLevel + 1);
              }

              result += `${token.name}`;
              if (typeof token.val === 'boolean') {
                if (token.val !== true) {
                  result += `=${token.val}`;
                }
              } else {
                let val = token.val;
                if (/^((v-bind|v-on|v-slot)?:|v-model|v-on|@).*/.test(token.name)) {
                  // Format Vue expression
                  val = val.trim();
                  val = val.slice(1, -1);
                  val = format(val, {
                    parser: '__vue_expression' as any,
                    ...codeInterpolationOptions
                  });
                  val = unwrapLineFeeds(val);
                  const quotes: "'" | '"' = singleQuote ? "'" : '"';
                  val = `${quotes}${val}${quotes}`;
                } else if (/^((.*)|(.*))$/.test(token.name)) {
                  // Format Angular action or binding
                  val = val.trim();
                  val = val.slice(1, -1);
                  val = format(val, {
                    parser: '__ng_interpolation' as any,
                    ...codeInterpolationOptions
                  });
                  val = unwrapLineFeeds(val);
                  const quotes: "'" | '"' = singleQuote ? "'" : '"';
                  val = `${quotes}${val}${quotes}`;
                } else if (/^*.*$/.test(token.name)) {
                  // Format Angular directive
                  val = val.trim();
                  val = val.slice(1, -1);
                  val = format(val, { parser: '__ng_directive' as any, ...codeInterpolationOptions });
                  const quotes: "'" | '"' = singleQuote ? "'" : '"';
                  val = `${quotes}${val}${quotes}`;
                } else if (/^(("'){{)(.*)(}}("'))$/.test(val)) {
                  // Format Angular interpolation
                  val = val.slice(3, -3);
                  val = val.trim();
                  val = val.replace(/ss+/g, ' ');
                  // val = format(val, {
                  //   parser: '__ng_interpolation' as any,
                  //   ...codeInterpolationOptions
                  // });
                  const quotes: "'" | '"' = singleQuote ? "'" : '"';
                  val = `${quotes}{{ ${val} }}${quotes}`;
                } else if (/^("')(.*)("')$/.test(val)) {
                  val = makeString(val.slice(1, -1), singleQuote ? "'" : '"', false);
                } else if (val === 'true') {
                  // The value is exactly true and is not quoted
                  break;
                } else if (token.mustEscape) {
                  val = format(val, {
                    parser: '__js_expression' as any,
                    ...codeInterpolationOptions
                  });
                } else {
                  // The value is not quoted and may be js-code
                  val = val.trim();
                  val = val.replace(/ss+/g, ' ');
                  if (val.startsWith('{ ')) {
                    val = `{${val.substring(2, val.length)}`;
                  }
                }

                if (token.mustEscape === false) {
                  result += '!';
                }

                result += `=${val}`;
              }
              break;
            }
            case 'end-attributes':
              if (wrapAttributes) {
                result += 'n';
                result += indent.repeat(indentLevel);
              }
              wrapAttributes = false;
              if (result.endsWith('(')) {
                // There were no attributes
                result = result.substring(0, result.length - 1);
              } else if (previousToken?.type === 'attribute') {
                result += ')';
              }
              if (nextToken?.type === 'text' || nextToken?.type === 'path') {
                result += ' ';
              }
              break;
            case 'indent':
              result += 'n';
              result += indent.repeat(indentLevel);
              indentLevel++;
              break;
            case 'outdent':
              if (previousToken?.type !== 'outdent') {
                if (token.loc.start.line - previousToken.loc.end.line > 1) {
                  // Insert one extra blank line
                  result += 'n';
                }
                result += 'n';
              }
              indentLevel--;
              break;
            case 'class':
              result += printIndent(previousToken, indent, indentLevel);
              result += `.${token.val}`;
              if (nextToken?.type === 'text') {
                result += ' ';
              }
              break;
            case 'eos':
              // Remove all newlines at the end
              while (result.endsWith('n')) {
                result = result.substring(0, result.length - 1);
              }
              // Insert one newline
              result += 'n';
              break;
            case 'comment': {
              result += printIndent(previousToken, indent, indentLevel);
              if (previousToken && !('newline', 'indent', 'outdent').includes(previousToken.type)) {
                result += ' ';
              }
              result += '//';
              if (!token.buffer) {
                result += '-';
              }
              result += formatCommentPreserveSpaces(token.val, commentPreserveSpaces);
              if (nextToken.type === 'start-pipeless-text') {
                pipelessComment = true;
              }
              break;
            }
            case 'newline':
              if (previousToken && token.loc.start.line - previousToken.loc.end.line > 1) {
                // Insert one extra blank line
                result += 'n';
              }
              result += 'n';
              break;
            case 'text': {
              let val = token.val;
              let needsTrailingWhitespace: boolean = false;

              if (pipelessText) {
                switch (previousToken?.type) {
                  case 'newline':
                    result += indent.repeat(indentLevel);
                    result += indent;
                    break;
                  case 'start-pipeless-text':
                    result += indent;
                    break;
                }

                if (pipelessComment) {
                  val = formatCommentPreserveSpaces(val, commentPreserveSpaces, true);
                }
              } else {
                if (nextToken && val.endsWith(' ')) {
                  switch (nextToken.type) {
                    case 'interpolated-code':
                    case 'start-pug-interpolation':
                      needsTrailingWhitespace = true;
                      break;
                  }
                }

                val = val.replace(/ss+/g, ' ');

                switch (previousToken?.type) {
                  case 'newline':
                    result += indent.repeat(indentLevel);
                    if (/^ .+$/.test(val)) {
                      result += '|n';
                      result += indent.repeat(indentLevel);
                    }
                    result += '|';
                    if (/.*S.*/.test(token.val) || nextToken?.type === 'start-pug-interpolation') {
                      result += ' ';
                    }
                    break;
                  case 'indent':
                    result += indent;
                    result += '|';
                    if (/.*S.*/.test(token.val)) {
                      result += ' ';
                    }
                    break;
                  case 'interpolated-code':
                  case 'end-pug-interpolation':
                    if (/^ .+$/.test(val)) {
                      result += ' ';
                    }
                    break;
                }

                val = val.trim();
                val = formatText(val, singleQuote);

                val = val.replace(/#({|()/g, '\#$1');
              }

              if (
                ('tag', 'id', 'interpolation', 'call', '&attributes', 'filter').includes(
                  previousToken?.type
                )
              ) {
                val = ` ${val}`;
              }

              result += val;
              if (needsTrailingWhitespace) {
                result += ' ';
              }
              break;
            }
            case 'interpolated-code':
              switch (previousToken?.type) {
                case 'tag':
                case 'class':
                case 'id':
                case 'end-attributes':
                  result += ' ';
                  break;
                case 'start-pug-interpolation':
                  result += '| ';
                  break;
                case 'indent':
                case 'newline':
                case 'outdent':
                  result += printIndent(previousToken, indent, indentLevel);
                  result += '| ';
                  break;
              }
              result += token.mustEscape ? '#' : '!';
              result += `{${token.val}}`;
              break;
            case 'code': {
              result += printIndent(previousToken, indent, indentLevel);
              if (!token.mustEscape && token.buffer) {
                result += '!';
              }
              result += token.buffer ? '=' : '-';
              let useSemi = semi;
              if (useSemi && (token.mustEscape || token.buffer)) {
                useSemi = false;
              }
              let val = token.val;
              try {
                const valBackup = val;
                val = format(val, {
                  parser: 'babel',
                  ...codeInterpolationOptions,
                  semi: useSemi,
                  endOfLine: 'lf'
                });
                val = val.slice(0, -1);
                if (val.includes('n')) {
                  val = valBackup;
                }
              } catch (error) {
                logger.warn(error);
              }
              result += ` ${val}`;
              break;
            }
            case 'id': {
              // Handle id attribute
              // Write css-id in front of css-classes
              let lastPositionOfNewline = result.lastIndexOf('n');
              if (lastPositionOfNewline === -1) {
                // If no newline was found, set position to zero
                lastPositionOfNewline = 0;
              }
              let position: number = result.indexOf('.', lastPositionOfNewline);
              if (position === -1) {
                position = result.length;
              }
              let _indent = '';
              switch (previousToken?.type) {
                case 'newline':
                case 'outdent':
                  _indent = indent.repeat(indentLevel);
                  break;
                case 'indent':
                  _indent = indent;
                  break;
              }
              result = (result.slice(0, position), _indent, `#${token.val}`, result.slice(position)).join(
                ''
              );
              break;
            }
            case 'start-pipeless-text':
              pipelessText = true;
              result += 'n';
              result += indent.repeat(indentLevel);
              break;
            case 'end-pipeless-text':
              pipelessText = false;
              pipelessComment = false;
              break;
            case 'doctype':
              result += 'doctype';
              if (token.val) {
                result += ` ${token.val}`;
              }
              break;
            case 'dot':
              result += '.';
              break;
            case 'block':
              result += printIndent(previousToken, indent, indentLevel);
              result += 'block ';
              if (token.mode !== 'replace') {
                result += token.mode;
                result += ' ';
              }
              result += token.val;
              break;
            case 'extends':
              result += 'extends ';
              break;
            case 'path':
              if (('include', 'filter').includes(previousToken?.type)) {
                result += ' ';
              }
              result += token.val;
              break;
            case 'start-pug-interpolation':
              result += '#(';
              break;
            case 'end-pug-interpolation':
              result += ')';
              break;
            case 'interpolation':
              result += printIndent(previousToken, indent, indentLevel);
              result += `#{${token.val}}`;
              break;
            case 'include':
              result += printIndent(previousToken, indent, indentLevel);
              result += 'include';
              break;
            case 'filter':
              result += printIndent(previousToken, indent, indentLevel);
              result += `:${token.val}`;
              break;
            case 'call': {
              result += printIndent(previousToken, indent, indentLevel);
              result += `+${token.val}`;
              let args: string | null = token.args;
              if (args) {
                args = args.trim();
                args = args.replace(/ss+/g, ' ');
                result += `(${args})`;
              }
              break;
            }
            case 'mixin': {
              result += printIndent(previousToken, indent, indentLevel);
              result += `mixin ${token.val}`;
              let args: string | null = token.args;
              if (args) {
                args = args.trim();
                args = args.replace(/ss+/g, ' ');
                result += `(${args})`;
              }
              break;
            }
            case 'if': {
              result += printIndent(previousToken, indent, indentLevel);
              const match = /^!((.*))$/.exec(token.val);
              logger.debug(match);
              result += !match ? `if ${token.val}` : `unless ${match(1)}`;
              break;
            }
            case 'mixin-block':
              result += printIndent(previousToken, indent, indentLevel);
              result += 'block';
              break;
            case 'else':
              result += printIndent(previousToken, indent, indentLevel);
              result += 'else';
              break;
            case '&attributes':
              result += `&attributes(${token.val})`;
              break;
            case 'text-html': {
              result += printIndent(previousToken, indent, indentLevel);
              const match: RegExpExecArray | null = /^<(.*?)>(.*)$/.exec(token.val);
              logger.debug(match);
              if (match) {
                result += `${match(1)} ${match(2)}`;
                break;
              }
              const entry = Object.entries(DOCTYPE_SHORTCUT_REGISTRY).find(
                ((key)) => key === token.val.toLowerCase()
              );
              if (entry) {
                result += entry(1);
                break;
              }
              result += token.val;
              break;
            }
            case 'each':
              result += printIndent(previousToken, indent, indentLevel);
              result += `each ${token.val}`;
              if (token.key !== null) {
                result += `, ${token.key}`;
              }
              result += ` in ${token.code}`;
              break;
            case 'while':
              result += printIndent(previousToken, indent, indentLevel);
              result += `while ${token.val}`;
              break;
            case 'case':
              result += printIndent(previousToken, indent, indentLevel);
              result += `case ${token.val}`;
              break;
            case 'when':
              result += printIndent(previousToken, indent, indentLevel);
              result += `when ${token.val}`;
              break;
            case ':':
              result += ': ';
              break;
            case 'default':
              result += printIndent(previousToken, indent, indentLevel);
              result += 'default';
              break;
            case 'else-if':
              result += printIndent(previousToken, indent, indentLevel);
              result += `else if ${token.val}`;
              break;
            case 'blockcode':
              result += printIndent(previousToken, indent, indentLevel);
              result += '-';
              break;
            case 'yield':
              result += printIndent(previousToken, indent, indentLevel);
              result += 'yield';
              break;
            case 'slash':
              result += '/';
              break;
            default:
              throw new Error('Unhandled token: ' + JSON.stringify(token));
          }
        }

        logger.debug(result);
        return result;
      },
      embed(
        path: FastPath,
        print: (path: FastPath) => Doc,
        textToDoc: (text: string, options: Options) => Doc,
        options: ParserOptions
      ): Doc | null {
        // logger.debug('(printers:pug-ast:embed):', JSON.stringify(path, undefined, 2));
        return null;
      },
      insertPragma(text: string): string {
        return `//- @prettiern${text}`;
      }
    }
  },
  options: pugOptions as any,
  defaultOptions: {}
};

export const languages = plugin.languages;
export const parsers = plugin.parsers;
export const printers = plugin.printers;
export const options = plugin.options;
export const defaultOptions = plugin.defaultOptions;

Performance – Improvements to JQuery event handlers and IF statements

First of all, not the best with JQuery, but know enough to deal with it. I have a custom script for our WordPress site that is linked to a main plugin we use. I have a JSfiddle app that contains a list of tasks in addition to the staging site. My main goal at the moment is to improve the code. The main thing is to cut the fat and reduce the waiting time for the page to display properly.

Here is the JS

jQuery(function ($) {
    // Create Variables
    var stains = $(".stains-container");
    var radio_buttons = $("input(name='tmcp_radio_0'), input.wood-class");

    // Check if Oak is checked
    var oak_checked         = $(":radio(value^=Oak_), :radio(value*=Oak_), :radio(value^=Barnwood_)").is(":checked");
    var $oakchecked         = $("input.b-maple-stains, input.cherry-stains, input.qswo-stains, input.h-maple-stains, input.hickory-stains, input.walnut-stains");
    var $oakactive          = $(".b-maple-stains-div li, .cherry-stains-div li, .qswo-stains-div li, .h-maple-stains-div li, .hickory-stains-div li, .walnut-stains-div li");
    var $oakactivehide      = $(".b-maple-stains-div, .cherry-stains-div, .qswo-stains-div, .h-maple-stains-div, .hickory-stains-div, .walnut-stains-div");
    // Check if B. Maple is checked
    var bmaple_checked      = $(":radio(value^=Brown), :radio(value^=Wormy)").is(":checked");
    var $bmaplechecked      = $("input.oak-stains, input.cherry-stains, input.qswo-stains, input.h-maple-stains, input.hickory-stains, input.walnut-stains");
    var $bmapleactive       = $(".oak-stains-div li, .cherry-stains-div li, .qswo-stains-div li, .h-maple-stains-div li, .hickory-stains-div li, .walnut-stains-div li");
    var $bmapleactivehide   = $(".oak-stains-div, .cherry-stains-div, .qswo-stains-div, .h-maple-stains-div, .hickory-stains-div, .walnut-stains-div");
    // Check if Cherry is checked
    var cherry_checked      = $(":radio(value^=Cherry_), :radio(value*=Cherry_)").is(":checked");
    var $cherrychecked      = $("input.oak-stains, input.b-maple-stains, input.qswo-stains, input.h-maple-stains, input.hickory-stains, input.walnut-stains");
    var $cherryactive       = $(".oak-stains-div li, .b-maple-stains-div li, .qswo-stains-div li, .h-maple-stains-div li, .hickory-stains-div li, .walnut-stains-div li");
    var $cherryactivehide   = $(".oak-stains-div, .b-maple-stains-div, .qswo-stains-div, .h-maple-stains-div, .hickory-stains-div, .walnut-stains-div");
    // Check if QSWO is checked
    var qswo_checked        = $(":radio(value^=Quartersawn)").is(":checked");
    var $qswochecked        = $("input.oak-stains, input.b-maple-stains, input.cherry-stains, input.h-maple-stains, input.hickory-stains, input.walnut-stains");
    var $qswoactive         = $(".oak-stains-div li, .b-maple-stains-div li, .cherry-stains-div li, .h-maple-stains-div li, .hickory-stains-div li, .walnut-stains-div li");
    var $qswoactivehide     = $(".oak-stains-div, .b-maple-stains-div, .cherry-stains-div, .h-maple-stains-div, .hickory-stains-div, .walnut-stains-div");
    // Check if H. Maple is checked
    var hmaple_checked      = $(":radio(value^=Hard), :radio(value*=Hard)").is(":checked");
    var $hmaplechecked      = $("input.oak-stains, input.b-maple-stains, input.cherry-stains, input.qswo-stains, input.hickory-stains, input.walnut-stains");
    var $hmapleactive       = $(".oak-stains-div li, .b-maple-stains-div li, .cherry-stains-div li, .qswo-stains-div li, .hickory-stains-div li, .walnut-stains-div li");
    var $hmapleactivehide   = $(".oak-stains-div, .b-maple-stains-div, .qswo-stains-div, .cherry-stains-div, .hickory-stains-div, .walnut-stains-div");
    // Check if Hickory is checked
    var hickory_checked     = $(":radio(value^=Hickory_), :radio(value*=Hickory_)").is(":checked");
    var $hickorychecked     = $("input.oak-stains, input.b-maple-stains, input.cherry-stains, input.qswo-stains, input.h-maple-stains, input.walnut-stains");
    var $hickoryactive      = $(".oak-stains-div li, .b-maple-stains-div li, .cherry-stains-div li, .qswo-stains-div li, .h-maple-stains-div li, .walnut-stains-div li");
    var $hickoryactivehide  = $(".oak-stains-div, .b-maple-stains-div, .qswo-stains-div, .h-maple-stains-div, .cherry-stains-div, .walnut-stains-div");
    // Check if Walnut is checked
    var walnut_checked     = $(":radio(value^=Walnut_), :radio(value*=Walnut_)").is(":checked");
    var $walnutchecked     = $("input.oak-stains, input.b-maple-stains, input.cherry-stains, input.qswo-stains, input.h-maple-stains, input.hickory-stains");
    var $walnutactive      = $(".oak-stains-div li, .b-maple-stains-div li, .cherry-stains-div li, .qswo-stains-div li, .h-maple-stains-div li, .hickory-stains-div li");
    var $walnutactivehide  = $(".oak-stains-div, .b-maple-stains-div, .qswo-stains-div, .h-maple-stains-div, .cherry-stains-div, .hickory-stains-div");

    // Hide stains unless a wood is chosen
    if(oak_checked) {
        $(".oak-stains-div").show();
        $oakactivehide.hide();
        $oakchecked.prop('checked', false);
        $oakactive.removeClass( "tc-active" );
    } else if(bmaple_checked) {
        $(".b-maple-stains-div").show();
        $bmapleactivehide.hide();
        $bmaplechecked.prop('checked', false);
        $bmapleactive.removeClass( "tc-active" );
    } else if(cherry_checked) {
        $(".cherry-stains-div").show();
        $cherryactivehide.hide();
        $cherrychecked.prop('checked', false);
        $cherryactive.removeClass( "tc-active" );
    } else if(qswo_checked) {
        $(".qswo-stains-div").show();
        $qswoactivehide.hide();
        $qswochecked.prop('checked', false);
        $qswoactive.removeClass( "tc-active" );
    } else if(hmaple_checked) {
        $(".h-maple-stains-div").show();
        $hmapleactivehide.hide();
        $hmaplechecked.prop('checked', false);
        $hmapleactive.removeClass( "tc-active" );
    } else if(hickory_checked) {
        $(".hickory-stains-div").show();
        $hickoryactivehide.hide();
        $hickorychecked.prop('checked', false);
        $hickoryactive.removeClass( "tc-active" );
    } else if(walnut_checked) {
        $(".walnut-stains-div").show();
        $walnutactivehide.hide();
        $walnutchecked.prop('checked', false);
        $walnutactive.removeClass( "tc-active" );
    } else if(radio_buttons.is(":not(:checked)")) {
        $(".stains-container").hide();
    } 

    // Check if Oak is selected or pre-selected
    radio_buttons.on('change', function(e) {
      var oakRegExp = /^Oak_d$/;
      var reclaimedOakRegExp = /^Reclaimed Oak_d$/;
      var barnwoodOakRegExp = /^Reclaimed Barnwood_d$/;
      var rstHckOakRegExp = /^Rustic Hickory Twigs and Oak_d$/;

      if (oakRegExp.test(e.target.value) || reclaimedOakRegExp.test(e.target.value) || barnwoodOakRegExp.test(e.target.value) || rstHckOakRegExp.test(e.target.value)) {
        stains.show();
        $(".oak-stains-div").show();
        $oakchecked.prop('checked', false);
        $oakactive.removeClass("tc-active");
      } else {
        $(".oak-stains-div").hide();
      }
    });

    // Check if B. Maple is selected or pre-selected
    radio_buttons.on('change', function(e) {
      var brownMapleRegExp = /^Brown Maple_d$/;
      var wormyMapleRegExp = /^Wormy Maple_d$/;

      if (brownMapleRegExp.test(e.target.value) || wormyMapleRegExp.test(e.target.value)) {
        stains.show();
        $(".b-maple-stains-div").show();
        $bmaplechecked.prop('checked', false);
        $bmapleactive.removeClass("tc-active");
      } else {
        $(".b-maple-stains-div").hide();
      }
    });

    // Check if Cherry is selected or pre-selected
    radio_buttons.on('change', function(e) {
      var cherryRegExp = /^Cherry_d$/;
      var rusticCherryRegExp = /^Rustic Cherry_d$/;
      var rusticHickoryCherryRegExp = /^Rustic Hickory Twigs and Cherry_d$/;

      if (cherryRegExp.test(e.target.value) || rusticCherryRegExp.test(e.target.value) || rusticHickoryCherryRegExp.test(e.target.value)) {
        stains.show();
        $(".cherry-stains-div").show();
        $cherrychecked.prop('checked', false);
        $cherryactive.removeClass( "tc-active" );
      } else {
        $(".cherry-stains-div").hide();
      }
    });

    // Check if QSWO is selected or pre-selected
    radio_buttons.on('change', function(e) {
      var qswoRegExp = /^Quartersawn White Oak_d$/;

      if (qswoRegExp.test(e.target.value)) {
        stains.show();
        $(".qswo-stains-div").show();
        $qswochecked.prop('checked', false);
        $qswoactive.removeClass( "tc-active" );
      } else {
        $(".qswo-stains-div").hide();
      }
    });

    // Check if Hard Maple is selected or pre-selected
    radio_buttons.on('change', function(e) {
      var hMapleRegExp = /^Hard Maple_d$/;
      var rusticHickoryhMapleRegExp = /^Rustic Hickory Twigs and Hard Maple_d$/;

      if (hMapleRegExp.test(e.target.value) || rusticHickoryhMapleRegExp.test(e.target.value)) {
        stains.show();
        $(".h-maple-stains-div").show();
        $hmaplechecked.prop('checked', false);
        $hmapleactive.removeClass( "tc-active" );
      } else {
        $(".h-maple-stains-div").hide();
      }
    });

    // Check if Hickory is selected or pre-selected
    radio_buttons.on('change', function(e) {
      var hickoryRegExp = /^Hickory_d$/;
      var rusticHickoryTwigsHickoryRegExp = /^Rustic Hickory Twigs and Hickory_d$/;

      if (hickoryRegExp.test(e.target.value) || rusticHickoryTwigsHickoryRegExp.test(e.target.value)) {
        stains.show();
        $(".hickory-stains-div").show();
        $hickorychecked.prop('checked', false);
        $hickoryactive.removeClass( "tc-active" );
      } else {
        $(".hickory-stains-div").hide();
      }
    });

    // Check if Walnut is selected or pre-selected
    radio_buttons.on('change', function(e) {
      var walnutRegExp = /^Walnut_d$/;
      var rusticWalnutRegExp = /^Rustic Walnut_d$/;

      if (walnutRegExp.test(e.target.value) || rusticWalnutRegExp.test(e.target.value)) {
        stains.show();
        $(".walnut-stains-div").show();
        $walnutchecked.prop('checked', false);
        $walnutactive.removeClass( "tc-active" );
      } else {
        $(".walnut-stains-div").hide();
      }
    });
});

The HTML code was ripped from the staging site and is therefore very illegible. The best thing to do is drop the JSFiddle link here: JSFiddle link. If anyone has any suggestions on how to cut off some fat, I would very much appreciate it. Or if you have suggestions for reducing the page time (waiting (TTFB)). I tried to delay and / or asynchronize the JS and nothing seems to improve. Again open to suggestions. Thanks a lot!

Edit: Forgot staging site link: Staging site