@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 3.16 kB
JavaScript
const e=/[ \t]*#(ifn?def|if|endif|else|elif|define|undef|extension|include)/g,n=/define[ \t]+([^\n]+)\r?(?:\n|$)/g,t=/extension[ \t]+([\w-]+)[ \t]*:[ \t]*(enable|require)/g,s=/undef[ \t]+([^\n]+)\r?(?:\n|$)/g,r=/(ifdef|ifndef|if)[ \t]*([^\r\n]+)\r?\n/g,l=/(endif|else|elif)([ \t][^\r\n]+)?\r?(?:\n|$)/g,a=/([\w-]+)/,i=/(!|\s)?defined\(([\w-]+)\)/,c=/[><=|&+-]/g,d=/include[ \t]+"([\w-]+)"\r?(?:\n|$)/g;class o{static run(e,n=new Map,t=!1){e=(e=e.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm,"$1")).split(/\r?\n/).map((e=>e.trimEnd())).join("\n");const s=new Map;if(t){const n=new Map,t=/(pcFragColor[1-8])\b/g,r=e.match(t);null==r||r.forEach((e=>{var t;const s=parseInt(e.charAt(e.length-1),10);n.set(s,(null!=(t=n.get(s))?t:0)+1)})),n.forEach(((e,n)=>{1===e&&s.set(`REMOVE_COLOR_ATTACHMENT_${n}`,"")}))}e=this._preprocess(e,s,n);const r=new Map;return s.forEach(((e,n)=>{Number.isInteger(parseFloat(e))&&!e.includes(".")&&r.set(n,e)})),e=this.RemoveEmptyLines(e),e=this.processArraySize(e,r)}static processArraySize(e,n){return null!==e&&n.forEach(((n,t)=>{e=e.replace(new RegExp(`\\[${t}\\]`,"g"),`[${n}]`)})),e}static RemoveEmptyLines(e){return null!==e&&(e=(e=e.split(/\r?\n/).map((e=>""===e.trim()?"":e)).join("\n")).replace(/(\n\n){3,}/g,"\n\n")),e}static _preprocess(i,c=new Map,x){const u=i,p=[];let f,g=!1;for(;null!==(f=e.exec(i));){const u=f[1];switch(u){case"define":{n.lastIndex=f.index;const t=n.exec(i);g||(g=null===t);const s=t[1];a.lastIndex=t.index;const r=a.exec(s)[1];let l=s.substring(r.length).trim();""===l&&(l="true");o._keep(p)&&c.set(r,l),e.lastIndex=t.index+t[0].length;break}case"undef":{s.lastIndex=f.index;const n=s.exec(i),t=n[1].trim();o._keep(p)&&c.delete(t),e.lastIndex=n.index+n[0].length;break}case"extension":{t.lastIndex=f.index;const n=t.exec(i);if(g||(g=null===n),n){const e=n[1];o._keep(p)&&c.set(e,"true")}e.lastIndex=n.index+n[0].length;break}case"ifdef":case"ifndef":case"if":{r.lastIndex=f.index;const n=r.exec(i),t=n[2],s=o.evaluate(t,c);g||(g=s.error);let l=s.result;"ifndef"===u&&(l=!l),p.push({anyKeep:l,keep:l,start:f.index,end:r.lastIndex}),e.lastIndex=n.index+n[0].length;break}case"endif":case"else":case"elif":{l.lastIndex=f.index;const n=l.exec(i),t=p.pop(),s=t.keep?i.substring(t.end,f.index):"";i=i.substring(0,t.start)+s+i.substring(l.lastIndex),e.lastIndex=t.start+s.length;const r=n[1];if("else"===r||"elif"===r){let s=!1;if(!t.anyKeep)if("else"===r)s=!t.keep;else{const e=o.evaluate(n[2],c);s=e.result,g||(g=e.error)}p.push({anyKeep:t.anyKeep||s,keep:s,start:e.lastIndex,end:e.lastIndex})}break}case"include":{d.lastIndex=f.index;const n=d.exec(i);g||(g=null===n);const t=n[1].trim();if(o._keep(p)){const s=null==x?void 0:x.get(t);s?(i=i.substring(0,n.index-1)+s+i.substring(d.lastIndex),e.lastIndex=n.index):(console.error(`Include not found: ${t}`),g=!0)}break}}}return g?(console.warn("Failed to preprocess shader: ",{source:u}),u):i}static _keep(e){for(let n=0;n<e.length;n++)if(!e[n].keep)return!1;return!0}static evaluate(e,n){const t=null===c.exec(e);let s=!1;const r=i.exec(e);r&&(s="!"===r[1],e=r[2]),e=e.trim();let l=n.has(e);return s&&(l=!l),{result:l,error:!t}}}export{o as Preprocessor};