Example #1
0
def gen_source(out_src, files):

    with open(out_src, 'w') as f:
        f.write('// #version:{}#\n'.format(Version))
        f.write('// machine generated, do not edit!\n')
        f.write('#include "{}.h"\n'.format(
            os.path.splitext(os.path.basename(out_src))[0]))
        f.write('namespace Oryol {\n')
        for file in files:
            file_path = get_file_path(file, out_src)
            if os.path.isfile(file_path):
                with open(file_path, 'rb') as src_file:
                    file_data = src_file.read()
                    file_name = get_file_cname(file)
                    file_size = os.path.getsize(file_path)
                    f.write('unsigned char {}[{}] = {{\n'.format(
                        file_name, file_size))
                    num = 0
                    for byte in file_data:
                        f.write(hex(ord(byte)) + ', ')
                        num += 1
                        if 0 == num % 16:
                            f.write('\n')
                    f.write('\n};\n')
            else:
                genutil.fmtError(
                    "Input file not found: '{}'".format(file_path))
        f.write('} // namespace Oryol\n')
Example #2
0
def gen_source(out_src, files):

    with open(out_src, 'w') as f:
        f.write('// #version:{}#\n'.format(Version))
        f.write('// machine generated, do not edit!\n')
        f.write('#include "{}.h"\n'.format(
            os.path.splitext(os.path.basename(out_src))[0]))
        items = {}
        for file in files:
            file_path = get_file_path(file, out_src)
            if os.path.isfile(file_path):
                with open(file_path, 'rb') as src_file:
                    file_data = src_file.read()
                    file_name = get_file_cname(file)
                    file_size = os.path.getsize(file_path)
                    items[file_name] = file_size
                    f.write('unsigned char {}[{}] = {{\n'.format(
                        file_name, file_size))
                    num = 0
                    for byte in file_data:
                        f.write(hex(ord(byte)) + ', ')
                        num += 1
                        if 0 == num % 16:
                            f.write('\n')
                    f.write('\n};\n')
            else:
                genutil.fmtError(
                    "Input file not found: '{}'".format(file_path))
        f.write('dump_item dump_items[DUMP_NUM_ITEMS] = {\n')
        for name, size in items.items():
            f.write('{{ "{}", {}, {} }},\n'.format(name[5:], name, size))
        f.write('};\n')
Example #3
0
def generate(input, out_src, out_hdr, args):
    with open(input, 'r') as f:
        try:
            yml = yaml.load(f)
        except yaml.YAMLError as exc:
            # show a proper error if YAML parsing fails
            util.setErrorLocation(exc.problem_mark.name,
                                  exc.problem_mark.line - 1)
            util.fmtError('YAML error: {}'.format(exc.problem))
    util.setErrorLocation(input, 1)
    src_root_path = os.path.dirname(input) + '/'
    dst_dir = args['deploy_dir'] + '/'
    if 'options' in yml:
        if 'src_dir' in yml['options']:
            src_root_path += yml['options']['src_dir'] + '/'
        if util.getEnv('target_platform') == 'ios' and 'ios' in yml['options']:
            if 'dst_dir' in yml['options']['ios']:
                dst_dir += yml['options']['ios']['dst_dir'] + '/'
        elif util.getEnv(
                'target_platform') == 'osx' and 'macos' in yml['options']:
            if 'dst_dir' in yml['options']['macos']:
                dst_dir += yml['options']['macos']['dst_dir'] + '/'
        elif 'dst_dir' in yml['options']:
            dst_dir += yml['options']['dst_dir']
        del yml['options']
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    if check_dirty(src_root_path, input, out_hdr, yml):
        copy_files(src_root_path, dst_dir, yml)
        gen_header(out_hdr, yml)
Example #4
0
 def __init__(self, propertyName, prop):
     self.propertyName = propertyName
     self.variables = list()
     self.isFlag = False
     self.isStruct = False
     self.isResource = False
     if isinstance(prop, dict):
         if not "_type_" in prop:
             for varName, var in prop.items():
                 self.variables.append(GetVariableFromEntry(varName, var))
             self.isStruct = True
         else:
             var = GetVariableFromEntry(propertyName, prop)
             if var.type is None:
                 self.isFlag = True
             self.variables.append(var)
     else:
         var = GetVariableFromEntry(propertyName, prop)
         if var.type is None:
             self.isFlag = True
         self.variables.append(GetVariableFromEntry(propertyName, prop))
     # Check to see if any of the types within the struct are resource.
     for var in self.variables:
         if var.type == IDLTypes.GetTypeString("resource"):
             if self.isStruct:
                 util.fmtError(
                     "Structs containing resources not supported!")
             self.isResource = True
Example #5
0
def compile(lines, base_path, type, c_name, args) :
    fxcPath = findFxc()
    if not fxcPath :
        util.fmtError("fxc.exe not found!\n")

    ext = {
        'vs': '.vsh',
        'fs': '.psh'
    }
    profile = {
        'vs': 'vs_5_0',
        'fs': 'ps_5_0'
    }
    hlsl_src_path = base_path + '.hlsl'
    out_path = base_path + '.hlsl.h'

    # /Gec is backward compatibility mode
    cmd = [fxcPath, '/T', profile[type], '/Fh', out_path, '/Vn', c_name, '/Gec']
    if 'debug' in args and args['debug'] == 'true' :
        cmd.extend(['/Zi', '/Od'])
    else :
        cmd.append('/O3')
    cmd.append(hlsl_src_path)
    
    output = callFxc(cmd)
    parseOutput(output, lines)
Example #6
0
def gen_source(out_src, files) :

    with open(out_src, 'w') as f:
        f.write('// #version:{}#\n'.format(Version))
        f.write('// machine generated, do not edit!\n')
        f.write('#include "{}.h"\n'.format(os.path.splitext(os.path.basename(out_src))[0]))
        f.write('namespace YAKC {\n')
        for file in files :
            file_path = get_file_path(file, out_src)
            if os.path.isfile(file_path) :
                with open(file_path, 'rb') as src_file:
                    file_data = src_file.read()
                    file_name = get_file_cname(file)
                    file_size = os.path.getsize(file_path)
                    f.write('unsigned char {}[{}] = {{\n'.format(file_name, file_size))               
                    num = 0
                    for byte in file_data :
                        f.write(hex(ord(byte)) + ', ')
                        num += 1
                        if 0 == num%16:
                            f.write('\n')
                    f.write('\n};\n')
            else :
                genutil.fmtError("Input file not found: '{}'".format(file_path))
        f.write('} // namespace YAKC\n')
Example #7
0
 def onUse(self, args) :
     if not self.current or not self.current.getTag() in ['block', 'vs', 'fs'] :
         util.fmtError("@use must come after @block, @vs or @fs!")
     if len(args) < 1:
         util.fmtError("@use must have at least one arg!")
     for arg in args :
         self.current.dependencies.append(Reference(arg, self.fileName, self.lineNumber))
Example #8
0
def validate(lines, type, slVersion, outPath, cName) :
    '''
    Validate a vertex-/fragment-shader pair.
    '''
    fxcPath = findFxc()
    if not fxcPath :
        util.fmtError("fxc.exe not found!\n")

    ext = {
        'vs': '.vsh',
        'fs': '.psh'
    }
    profile = {
        'vs': 'vs_5_0',
        'fs': 'ps_5_0'
    }
    rootPath = os.path.splitext(outPath)[0]
    hlsl_src_path = rootPath + '.{}{}'.format(profile[type], ext[type])
    with open(hlsl_src_path, 'w') as f :
        writeFile(f, lines)

    cmd = [fxcPath, '/T', profile[type], '/O3', '/Fh', outPath, '/Vn', cName, hlsl_src_path]
    print(cmd);
    output = callFxc(cmd)
    parseOutput(output, lines)
Example #9
0
def validate(lines, type, slVersion, outPath, cName, args) :
    '''
    Validate a vertex-/fragment-shader pair.
    '''
    fxcPath = findFxc()
    if not fxcPath :
        util.fmtError("fxc.exe not found!\n")

    ext = {
        'vs': '.vsh',
        'fs': '.psh'
    }
    profile = {
        'vs': 'vs_5_0',
        'fs': 'ps_5_0'
    }
    rootPath = os.path.splitext(outPath)[0]
    hlsl_src_path = rootPath + '.{}{}'.format(profile[type], ext[type])
    with open(hlsl_src_path, 'w') as f :
        writeFile(f, lines)

    cmd = [fxcPath, '/T', profile[type], '/Fh', outPath, '/Vn', cName]
    if 'debug' in args and args['debug'] == 'true' :
        cmd.extend(['/Zi', '/Od'])
    else :
        cmd.append('/O3')
    cmd.append(hlsl_src_path)
    
    output = callFxc(cmd)
    parseOutput(output, lines)
Example #10
0
def validate(lines, type, slVersion, outPath, cName) :
    '''
    Validate a vertex-/fragment-shader pair.
    '''
    fxcPath = findFxc()
    if not fxcPath :
        util.fmtError("fxc.exe not found!\n")

    ext = {
        'vs': '.vsh',
        'fs': '.psh'
    }
    profile = {
        'vs': 'vs_5_0',
        'fs': 'ps_5_0'
    }

    f = tempfile.NamedTemporaryFile(suffix=ext[type], delete=False)
    writeFile(f, lines)
    f.close()

    cmd = [fxcPath, '/T', profile[type], '/O3', '/Fh', outPath, '/Vn', cName, f.name]
    output = callFxc(cmd)
    os.unlink(f.name)
    parseOutput(output, lines)
Example #11
0
def AccessModeToClassString(accessMode):
    access = accessMode.lower()
    if (access == "rw"):
        return "Attr::ReadWrite"
    elif (access == "r"):
        return "Attr::ReadOnly"
    else:
        util.fmtError('"{}" is not a valid access mode!'.format(access))
Example #12
0
 def onProgram(self, args) :
     if not self.current or self.current.getTag() != 'bundle' :
         util.fmtError("@program must come after @bundle!")
     if len(args) != 2:
         util.fmtError("@program must have 2 args (vs fs)")
     vs = args[0]
     fs = args[1]
     self.current.programs.append(Program(vs, fs, self.fileName, self.lineNumber))
Example #13
0
 def load(self) :
     with open(self.vox_file, 'rb') as f :
         magic = f.read(4)
         if magic != 'VOX ':
             util.fmtError('{} is not a VOX file!'.format(self.vox_file))
         version = struct.unpack('<I', f.read(4))[0]
         print("VOX file '{}' version={}".format(self.vox_file, version))
         self.load_chunk(f)
Example #14
0
 def load(self):
     with open(self.vox_file, 'rb') as f:
         magic = f.read(4)
         if magic != 'VOX ':
             util.fmtError('{} is not a VOX file!'.format(self.vox_file))
         version = struct.unpack('<I', f.read(4))[0]
         print("VOX file '{}' version={}".format(self.vox_file, version))
         self.load_chunk(f)
Example #15
0
 def __init__(self, T, name, defVal):
     if not isinstance(T, str) and T is not None:
         util.fmtError('_type_ value is not a string value!')
     self.type = T
     if not isinstance(name, str):
         util.fmtError('_name_ value is not a string value!')
     self.name = name
     self.defaultValue = defVal
Example #16
0
 def onEnd(self, args):
     if not self.current or not self.current.getTag() in [
             'block', 'vs', 'fs', 'bundle'
     ]:
         util.fmtError("@end must come after @block, @vs, @fs or @bundle!")
     if len(args) != 0:
         util.fmtError("@end must not have arguments")
     self.current = None
Example #17
0
def gen_header(out_hdr, src_dir, files):
    with open(out_hdr, 'w', encoding='utf-8') as f:
        f.write('#pragma once\n')
        f.write('// #version:{}#\n'.format(Version))
        f.write('// machine generated, do not edit!\n')
        items = {}
        for file in files:
            title = ''
            if isinstance(file, dict):
                for name, t in file.items():
                    file = name
                    title = t
                    print(name, t)
                    break
            file_path = get_file_path(file, src_dir, out_hdr)
            if os.path.isfile(file_path):
                with open(file_path, 'rb') as src_file:
                    file_data = src_file.read()
                    file_name = get_file_cname(file)
                    file_size = os.path.getsize(file_path)
                    if title != '' and (file_data[0] == 48
                                        or file_data[0] == 49):
                        file_data, file_size = tap2cas(file_data, file_size)
                    items[file_name] = [title, file_size]
                    print(items[file_name], file_name)
                    f.write('unsigned char {}[{}] = {{\n'.format(
                        file_name, file_size))
                    num = 0
                    for byte in file_data:
                        if sys.version_info[0] >= 3:
                            f.write("0x%02x" % byte + ', ')
                        else:
                            f.write(hex(ord(byte)) + ', ')
                        num += 1
                        if 0 == num % 16:
                            f.write('\n')
                    f.write('\n};\n')
            else:
                genutil.fmtError(
                    "Input file not found: '{}'".format(file_path))
        f.write('#define TAPE 1\n')
        f.write('#define BIN 0\n')
        f.write(
            'typedef struct { const char* name; const uint8_t* ptr; int size; const int type; } dump_item;\n'
        )
        f.write('#define DUMP_NUM_ITEMS ({})\n'.format(len(items)))
        f.write('dump_item dump_items[DUMP_NUM_ITEMS] = {\n')
        for name, value in items.items():
            size = value[1]
            if value[0] != '':
                title = value[0]
                type = 'TAPE'
            else:
                title = name[5:]
                type = 'BIN'
            f.write('{{ u8"{}", {}, {}, {} }},\n'.format(
                title, name, size, type))
        f.write('};\n')
Example #18
0
    def parseTags(self, line):
        # first check if the line contains a tag, the tag must be
        # alone on the line
        tagStartIndex = line.find('@')
        if tagStartIndex != -1:
            if tagStartIndex > 0:
                util.fmtError("only whitespace allowed in front of tag")
            if line.find(';') != -1:
                util.fmtError("no semicolons allowed in tag lines")

            tagAndArgs = line[tagStartIndex + 1:].split()
            tag = tagAndArgs[0]
            args = tagAndArgs[1:]
            if tag == 'block':
                self.onBlock(args)
            elif tag == 'vs':
                self.onVertexShader(args)
            elif tag == 'fs':
                self.onFragmentShader(args)
            elif tag == 'bundle':
                self.onBundle(args)
            elif tag == 'use':
                self.onUse(args)
            elif tag == 'in':
                self.onIn(args)
            elif tag == 'out':
                self.onOut(args)
            elif tag == 'uniform':
                self.onUniform(args)
            elif tag == 'highp':
                self.onPrecision(args)
            elif tag == 'program':
                self.onProgram(args)
            elif tag == 'end':
                self.onEnd(args)
            else:
                util.fmtError("unrecognized @ tag '{}'".format(tag))
            return ''

        # handle any $ macros
        for macro in macroKeywords:
            startIndex = line.find(macro)
            if startIndex != -1:
                if self.current is not None:
                    line = line.replace(macro, macroKeywords[macro])
                    if macroKeywords[macro] not in self.current.macros:
                        self.current.macros.append(macroKeywords[macro])
                else:
                    util.fmtError(
                        '$ tag must come after @block, @vs, @fs and before @end'
                    )

        # if there are still $ characters in the line, it must be an
        # unrecognized macro keyword (typo?)
        if '$' in line:
            util.fmtError('unrecognized $ keyword!')

        return line
Example #19
0
 def onProgram(self, args):
     if not self.current or self.current.getTag() != 'bundle':
         util.fmtError("@program must come after @bundle!")
     if len(args) != 2:
         util.fmtError("@program must have 2 args (vs fs)")
     vs = args[0]
     fs = args[1]
     self.current.programs.append(
         Program(vs, fs, self.fileName, self.lineNumber))
Example #20
0
 def onInclude(self, args):
     if len(args) != 1:
         util.fmtError("@include must have 1 arg (name of included block)")
     if not self.current or not self.current.getTag() in ['vs', 'fs']:
         util.fmtError("@include must come after @vs or @fs!")
     if self.current:
         l = Line(None, self.fileName, self.lineNumber)
         l.include = args[0]
         self.current.lines.append(l)
Example #21
0
    def parseTags(self, line) :
        # first check if the line contains a tag, the tag must be
        # alone on the line
        tagStartIndex = line.find('@')
        if tagStartIndex != -1 :
            if tagStartIndex > 0 :
                util.fmtError("only whitespace allowed in front of tag")
            if line.find(';') != -1 :
                util.fmtError("no semicolons allowed in tag lines")

            tagAndArgs = line[tagStartIndex+1 :].split()
            tag = tagAndArgs[0]
            args = tagAndArgs[1:]
            if tag == 'block':
                self.onBlock(args)
            elif tag == 'vs':
                self.onVertexShader(args)
            elif tag == 'fs':
                self.onFragmentShader(args)
            elif tag == 'bundle':
                self.onBundle(args)
            elif tag == 'use':
                self.onUse(args)
            elif tag == 'in':
                self.onIn(args)
            elif tag == 'out':
                self.onOut(args)
            elif tag == 'uniform':
                self.onUniform(args)
            elif tag == 'highp' :
                self.onPrecision(args)
            elif tag == 'program':
                self.onProgram(args)
            elif tag == 'end':
                self.onEnd(args)
            else :
                util.fmtError("unrecognized @ tag '{}'".format(tag))
            return ''

        # handle any $ macros
        for macro in macroKeywords :
            startIndex = line.find(macro)
            if startIndex != -1 :
                if self.current is not None:
                    line = line.replace(macro, macroKeywords[macro])
                    if macroKeywords[macro] not in self.current.macros :
                        self.current.macros.append(macroKeywords[macro])
                else :
                    util.fmtError('$ tag must come after @block, @vs, @fs and before @end')

        # if there are still $ characters in the line, it must be an 
        # unrecognized macro keyword (typo?)
        if '$' in line :
            util.fmtError('unrecognized $ keyword!')

        return line
Example #22
0
 def onUse(self, args):
     if not self.current or not self.current.getTag() in [
             'block', 'vs', 'fs'
     ]:
         util.fmtError("@use must come after @block, @vs or @fs!")
     if len(args) < 1:
         util.fmtError("@use must have at least one arg!")
     for arg in args:
         self.current.dependencies.append(
             Reference(arg, self.fileName, self.lineNumber))
Example #23
0
def WriteMessageDeclarations(f, document):
    for messageName, message in document["messages"].items():
        if not "fourcc" in message:
            util.fmtError(
                'Message FourCC is required. Message "{}" does not have a fourcc!'
                .format(messageName))
        fourcc = message["fourcc"]

        templateArgs = ""
        messageParams = ""
        sendArgs = ""
        i = 1
        numArgs = len(document["messages"][messageName]["args"])
        for argName, T in document["messages"][messageName]["args"].items():
            typeString = IDLTypes.GetArgumentType(T)
            templateArgs += typeString
            messageParams += "{} {}".format(typeString, argName)
            sendArgs += argName
            if i < numArgs:
                templateArgs += ", "
                messageParams += ", "
                sendArgs += ", "
            i += 1

        f.InsertNebulaDivider()
        f.WriteLine(
            """class {MSG} : public Game::Message<{MSG}, {TemplateArguments}>
{{
public:
    {MSG}() = delete;
    ~{MSG}() = delete;
    constexpr static const char* GetName() {{ return \"{MSG}\"; }};
    constexpr static const uint GetFourCC()	{{ return \'{FOURCC}\'; }};
    static void Send({MessageParameters})
    {{
        auto instance = Instance();
        SizeT size = instance->callbacks.Size();
        for (SizeT i = 0; i < size; ++i)
            instance->callbacks.Get<1>(i)({SendArguments});
    }}
    static void Defer(MessageQueueId qid, {MessageParameters})
    {{
        auto instance = Instance();
        SizeT index = Ids::Index(qid.id);
        auto i = instance->messageQueues[index].Alloc();
        instance->messageQueues[index].Set(i, {SendArguments});
    }}
}};
        """.format(
                MSG=messageName,
                TemplateArguments=templateArgs,
                FOURCC=fourcc,
                MessageParameters=messageParams,
                SendArguments=sendArgs,
            ))
Example #24
0
def run(cmd):
    child = subprocess.Popen(cmd, stderr=subprocess.PIPE)
    out = ''
    while True:
        out += bytes.decode(child.stderr.read())
        if child.poll() != None:
            break
    for line in out.splitlines():
        util.fmtError(line, False)
    if child.returncode != 0:
        exit(child.returncode)
Example #25
0
File: shdc.py Project: floooh/oryol
def run(cmd):
    child = subprocess.Popen(cmd, stderr=subprocess.PIPE)
    out = ''
    while True :
        out += bytes.decode(child.stderr.read())
        if child.poll() != None :
            break
    for line in out.splitlines():
        util.fmtError(line, False)
    if child.returncode != 0:
        exit(child.returncode)
Example #26
0
 def parseSource(self, fileName):
     f = open(fileName, 'r')
     self.fileName = fileName
     self.lineNumber = 0
     for line in f:
         util.setErrorLocation(self.fileName, self.lineNumber)
         self.parseLine(line)
         self.lineNumber += 1
     f.close()
     if self.current is not None:
         util.fmtError('missing @end at end of file')
Example #27
0
def parseOutput(output, lines) :
    '''
    Parse error output lines from FXC, 
    map them to the original source code location and output
    an error message compatible with Xcode or VStudio
    '''
    hasError = False
    hasWarning = False
    outLines = output.splitlines()

    for outLine in outLines :

        # extract generated shader source column, line and message
        # format is 'filename(line,startcol-endcol): msg
        lineStartIndex = outLine.find('(', 0) + 1
        if lineStartIndex == 0 :
            continue
        lineEndIndex = outLine.find(',', lineStartIndex)
        if lineEndIndex == -1 :
            continue
        colStartIndex = lineEndIndex + 1
        colEndIndex = outLine.find('-', colStartIndex)
        if colEndIndex == -1 :
            colEndIndex = outLine.find(')', colStartIndex)
            if colEndIndex == -1 :
                continue
        msgStartIndex = outLine.find(':', colStartIndex+1)
        if msgStartIndex == -1 :
            continue

        colNr = int(outLine[colStartIndex:colEndIndex])
        lineNr = int(outLine[lineStartIndex:lineEndIndex])
        msg = outLine[msgStartIndex:]

        # map to original location
        lineIndex = lineNr - 1
        if lineIndex >= len(lines) :
            lineIndex = len(lines) - 1
        srcPath = lines[lineIndex].path
        srcLineNr = lines[lineIndex].lineNumber
        
        # and output...
        util.setErrorLocation(srcPath, srcLineNr)
        if 'error' in outLine :
            hasError = True
            util.fmtError(msg, False)
        elif 'warning' in outLine :
            hasWarning = True
            util.fmtWarning(msg)

    if hasError :
        for line in lines :
            print(line.content)
        sys.exit(10) 
Example #28
0
def parseOutput(output, lines):
    '''
    Parse error output lines from FXC, 
    map them to the original source code location and output
    an error message compatible with Xcode or VStudio
    '''
    hasError = False
    hasWarning = False
    outLines = output.splitlines()

    for outLine in outLines:

        # extract generated shader source column, line and message
        # format is 'filename(line,startcol-endcol): msg
        lineStartIndex = outLine.find('(', 0) + 1
        if lineStartIndex == 0:
            continue
        lineEndIndex = outLine.find(',', lineStartIndex)
        if lineEndIndex == -1:
            continue
        colStartIndex = lineEndIndex + 1
        colEndIndex = outLine.find('-', colStartIndex)
        if colEndIndex == -1:
            colEndIndex = outLine.find(')', colStartIndex)
            if colEndIndex == -1:
                continue
        msgStartIndex = outLine.find(':', colStartIndex + 1)
        if msgStartIndex == -1:
            continue

        colNr = int(outLine[colStartIndex:colEndIndex])
        lineNr = int(outLine[lineStartIndex:lineEndIndex])
        msg = outLine[msgStartIndex:]

        # map to original location
        lineIndex = lineNr - 1
        if lineIndex >= len(lines):
            lineIndex = len(lines) - 1
        srcPath = lines[lineIndex].path
        srcLineNr = lines[lineIndex].lineNumber

        # and output...
        util.setErrorLocation(srcPath, srcLineNr)
        if 'error' in outLine:
            hasError = True
            util.fmtError(msg, False)
        elif 'warning' in outLine:
            hasWarning = True
            util.fmtWarning(msg)

    if hasError:
        for line in lines:
            print(line.content)
        sys.exit(10)
Example #29
0
 def resolveDeps(self, shd, dep) :
     '''
     Recursively resolve dependencies for a shader.
     '''
     # just add new dependencies at the end of resolvedDeps,
     # and remove dups in a second pass after recursion
     if not dep.name in self.blocks :
         util.setErrorLocation(dep.path, dep.lineNumber)
         util.fmtError("unknown block dependency '{}'".format(dep.name))
     shd.resolvedDeps.append(dep.name)
     for depdep in self.blocks[dep.name].dependencies :
         self.resolveDeps(shd, depdep)
Example #30
0
 def onProgram(self, args):
     if len(args) != 3:
         util.fmtError("@program must have 3 args (name vs fs)")
     if self.current is not None:
         util.fmtError(
             "cannot nest @program (missing @end tag in '{}'?)".format(
                 self.current.name))
     name = args[0]
     vs = args[1]
     fs = args[2]
     prog = Program(name, vs, fs, self.fileName, self.lineNumber)
     self.shaderLib.programs[name] = prog
Example #31
0
 def resolveDeps(self, shd, dep):
     '''
     Recursively resolve dependencies for a shader.
     '''
     # just add new dependencies at the end of resolvedDeps,
     # and remove dups in a second pass after recursion
     if not dep.name in self.blocks:
         util.setErrorLocation(dep.path, dep.lineNumber)
         util.fmtError("unknown block dependency '{}'".format(dep.name))
     shd.resolvedDeps.append(dep.name)
     for depdep in self.blocks[dep.name].dependencies:
         self.resolveDeps(shd, depdep)
Example #32
0
def copy_files(src_dir, dst_dir, yml):
    for filename in yml['files']:
        src = src_dir + filename
        dst = dst_dir + filename
        print("## cp '{}' => '{}'".format(filename, dst))
        if not os.path.exists(os.path.dirname(dst)):
            os.makedirs(os.path.dirname(dst))
        try:
            shutil.copyfile(src, dst)
        except IOError as err:
            # show a proper error if file copying fails
            util.fmtError("Failed to copy file '{}' with '{}'".format(
                err.filename, err.strerror))
Example #33
0
 def checkAddUniform(self, uniform, list):
     '''
     Check if uniform already exists in list, if yes
     check if type and binding matches, if not write error.
     If uniform doesn't exist yet in list, add it.
     '''
     listUniform = findByName(uniform.name, list)
     if listUniform is not None:
         # redundant uniform, check if type and binding name match
         if listUniform.type != uniform.type:
             util.setErrorLocation(uniform.filePath, uniform.lineNumber)
             util.fmtError(
                 "uniform type mismatch '{}' vs '{}'".format(
                     uniform.type, listUniform.type), False)
             util.setErrorLocation(listUniform.filePath,
                                   listUniform.lineNumber)
             util.fmtError("uniform type mismatch '{}' vs '{}'".format(
                 listUniform.type, uniform.type))
         if listUniform.bind != uniform.bind:
             util.setErrorLocation(uniform.filePath, uniform.lineNumber)
             util.fmtError(
                 "uniform bind name mismatch '{}' vs '{}'".format(
                     uniform.bind, listUniform.bind), False)
             util.setErrorLocation(listUniform.filePath,
                                   listUniform.lineNumber)
             util.fmtError("uniform bind name mismatch '{}' vs '{}'".format(
                 listUniform.bind, uniform.bind))
     else:
         # new uniform from block, add to list
         list.append(uniform)
Example #34
0
    def WriteAttributeAccessDeclarations(self):
        if self.hasAttributes:
            self.f.WriteLine("/// Attribute access methods")
            for attributeName in self.component["attributes"]:
                if not attributeName in self.document["attributes"]:
                    util.fmtError(AttributeNotFoundError.format(attributeName))

                returnType = IDLTypes.GetTypeString(
                    self.document["attributes"][attributeName]["type"])
                attributeName = Capitalize(attributeName)

                self.f.WriteLine(
                    "{retval}& {attributeName}(Game::InstanceId instance);".
                    format(retval=returnType, attributeName=attributeName))
Example #35
0
    def parseSource(self, fileName) :
        '''
        Parse a single file and populate shader lib
        '''
        f = open(fileName, 'r')
        self.fileName = fileName
        self.lineNumber = 0
        for line in f :
            util.setErrorLocation(self.fileName, self.lineNumber)
            self.parseLine(line)
            self.lineNumber += 1
        f.close()

        # all blocks must be closed
        if self.current is not None :
            util.fmtError('missing @end at end of file')
Example #36
0
    def resolveBundleUniforms(self, bundle) :
        '''
        Gathers all uniforms from all shaders in the bundle.
        '''
        for program in bundle.programs :
            if program.vs not in self.vertexShaders :
                util.setErrorLocation(program.filePath, program.lineNumber)
                util.fmtError("unknown vertex shader '{}'".format(program.vs))
            for uniform in self.vertexShaders[program.vs].uniforms :
                self.checkAddUniform(uniform, bundle.uniforms)

            if program.fs not in self.fragmentShaders :
                util.setErrorLocation(program.filePath, program.lineNumber)
                util.fmtError("unknown fragment shader '{}'".format(program.fs))
            for uniform in self.fragmentShaders[program.fs].uniforms :
                self.checkAddUniform(uniform, bundle.uniforms)
Example #37
0
 def generateShaderSources(self):
     for shd in self.shaders:
         lines = []
         for l in shd.lines:
             # @include statement?
             if l.include:
                 if l.include not in self.blocks:
                     util.setErrorLocation(incl.path, incl.lineNumber)
                     util.fmtError(
                         "included block '{}' doesn't exist".format(
                             incl.name))
                 for lb in self.blocks[l.include].lines:
                     lines.append(lb)
             else:
                 lines.append(l)
         shd.generatedSource = lines
Example #38
0
    def parseSource(self, fileName):
        '''
        Parse a single file and populate shader lib
        '''
        f = open(fileName, 'r')
        self.fileName = fileName
        self.lineNumber = 0
        for line in f:
            util.setErrorLocation(self.fileName, self.lineNumber)
            self.parseLine(line)
            self.lineNumber += 1
        f.close()

        # all blocks must be closed
        if self.current is not None:
            util.fmtError('missing @end at end of file')
Example #39
0
def GetTypeCamelNotation(attributeName, attribute, document):
    if not "type" in attribute:
        util.fmtError(
            'Attribute type is required. Attribute "{}" does not name a type!'.
            format(attributeName))
    typeString = IDLTypes.ConvertToCamelNotation(attribute["type"])

    if not typeString:
        # Figure out what type it actually is.
        if attribute["type"] in document["enums"]:
            typeString = IDLTypes.ConvertToCamelNotation(
                "uint")  # type for enums is uint
        else:
            util.fmtError('"{}" is not a valid type!'.format(
                attribute["type"]))
    return typeString
Example #40
0
def gen_header(out_hdr, files) :
    
    with open(out_hdr, 'w') as f:
        f.write('#pragma once\n')
        f.write('// #version:{}#\n'.format(Version))
        f.write('// machine generated, do not edit!\n')
        f.write('namespace YAKC {\n')
        for file in files :
            file_path = get_file_path(file, out_hdr)
            if os.path.isfile(file_path) :
                file_name = get_file_cname(file)
                file_size = os.path.getsize(file_path)
                f.write('extern unsigned char {}[{}];\n'.format(file_name, file_size))
            else :
                genutil.fmtError("Input file not found: '{}'".format(file_path))
        f.write('} // namespace YAKC\n')
Example #41
0
 def AsTypeDefString(self):
     if self.isFlag:
         return ""
     numVars = len(self.variables)
     if numVars == 0:
         util.fmtError(
             "PropertyDefinition does not contain a single variable!")
     elif numVars == 1 and not self.isStruct:
         return 'typedef {} {};\n'.format(self.variables[0].type,
                                          self.variables[0].name)
     else:
         varDefs = ""
         retVal = 'struct {}\n{{\n'.format(self.propertyName)
         for v in self.variables:
             retVal += '    {}\n'.format(v.AsString())
         retVal += "};\n"
         return retVal
Example #42
0
def generate(input, out_src, out_hdr, args):
    with open(input, 'r') as f:
        try:
            yml = yaml.load(f)
        except yaml.YAMLError as exc:
            # show a proper error if YAML parsing fails
            util.setErrorLocation(exc.problem_mark.name, exc.problem_mark.line-1)
            util.fmtError('YAML error: {}'.format(exc.problem))
    src_root_path = os.path.dirname(input) + '/'
    if 'root' in yml:
        src_root_path += yml['root'] + '/'
    deploy_dir = args['deploy_dir'] + '/'
    if not os.path.exists(deploy_dir):
        os.makedirs(deploy_dir)
    if check_dirty(src_root_path, input, out_hdr, yml):
        copy_files(src_root_path, deploy_dir, yml)
        gen_header(out_hdr, yml)
Example #43
0
    def stripComments(self, line) :
        '''
        Remove comments from a single line, can carry
        over to next or from previous line.
        '''
        done = False
        while not done :
            # if currently in comment, look for end-of-comment
            if self.inComment :
                endIndex = line.find('*/')
                if endIndex == -1 :
                    # entire line is comment
                    if '/*' in line or '//' in line :
                        util.fmtError('comment in comment!')
                    else :
                        return ''
                else :
                    comment = line[:endIndex+2]
                    if '/*' in comment or '//' in comment :
                        util.fmtError('comment in comment!')
                    else :
                        line = line[endIndex+2:]
                        self.inComment = False

            # clip off winged comment (if exists)
            wingedIndex = line.find('//')
            if wingedIndex != -1 :
                line = line[:wingedIndex]

            # look for start of comment
            startIndex = line.find('/*')
            if startIndex != -1 :
                # ...and for the matching end...
                endIndex = line.find('*/', startIndex)
                if endIndex != -1 :
                    line = line[:startIndex] + line[endIndex+2:]
                else :
                    # comment carries over to next line
                    self.inComment = True
                    line = line[:startIndex]
                    done = True
            else :
                # no comment until end of line, done
                done = True;
        line = line.strip(' \t\n\r')
        return line
Example #44
0
    def stripComments(self, line):
        '''
        Remove comments from a single line, can carry
        over to next or from previous line.
        '''
        done = False
        while not done:
            # if currently in comment, look for end-of-comment
            if self.inComment:
                endIndex = line.find('*/')
                if endIndex == -1:
                    # entire line is comment
                    if '/*' in line or '//' in line:
                        util.fmtError('comment in comment!')
                    else:
                        return ''
                else:
                    comment = line[:endIndex + 2]
                    if '/*' in comment or '//' in comment:
                        util.fmtError('comment in comment!')
                    else:
                        line = line[endIndex + 2:]
                        self.inComment = False

            # clip off winged comment (if exists)
            wingedIndex = line.find('//')
            if wingedIndex != -1:
                line = line[:wingedIndex]

            # look for start of comment
            startIndex = line.find('/*')
            if startIndex != -1:
                # ...and for the matching end...
                endIndex = line.find('*/', startIndex)
                if endIndex != -1:
                    line = line[:startIndex] + line[endIndex + 2:]
                else:
                    # comment carries over to next line
                    self.inComment = True
                    line = line[:startIndex]
                    done = True
            else:
                # no comment until end of line, done
                done = True
        line = line.strip(' \t\n\r')
        return line
Example #45
0
    def resolveBundleUniforms(self, bundle):
        '''
        Gathers all uniforms from all shaders in the bundle.
        '''
        for program in bundle.programs:
            if program.vs not in self.vertexShaders:
                util.setErrorLocation(program.filePath, program.lineNumber)
                util.fmtError("unknown vertex shader '{}'".format(program.vs))
            for uniform in self.vertexShaders[program.vs].uniforms:
                self.checkAddUniform(uniform, bundle.uniforms)

            if program.fs not in self.fragmentShaders:
                util.setErrorLocation(program.filePath, program.lineNumber)
                util.fmtError("unknown fragment shader '{}'".format(
                    program.fs))
            for uniform in self.fragmentShaders[program.fs].uniforms:
                self.checkAddUniform(uniform, bundle.uniforms)
Example #46
0
def gen_header(out_hdr, src_dir, files, prefix, list_items):
    with open(out_hdr, 'w') as f:
        f.write('#pragma once\n')
        f.write('// #version:{}#\n'.format(Version))
        f.write('// machine generated, do not edit!\n')
        items = {}
        for file in files:
            file_path = get_file_path(file, src_dir, out_hdr)
            print("## embed '{}'".format(file_path))
            if os.path.isfile(file_path):
                with open(file_path, 'rb') as src_file:
                    file_data = src_file.read()
                    file_cname = get_file_cname(file, prefix)
                    file_size = os.path.getsize(file_path)
                    items[file_cname] = [file, file_size]
                    f.write('unsigned char {}[{}] = {{\n'.format(
                        file_cname, file_size))
                    num = 0
                    for byte in file_data:
                        if sys.version_info[0] >= 3:
                            f.write(hex(ord(chr(byte))) + ', ')
                        else:
                            f.write(hex(ord(byte)) + ', ')
                        num += 1
                        if 0 == num % 16:
                            f.write('\n')
                    f.write('\n};\n')
            else:
                genutil.fmtError(
                    "Input file not found: '{}'".format(file_path))
        if list_items:
            f.write(
                'typedef struct {{ const char* name; const uint8_t* ptr; int size; }} {}item_t;\n'
                .format(prefix))
            f.write('#define {}NUM_ITEMS ({})\n'.format(
                prefix.upper(), len(items)))
            f.write('{}item_t {}items[{}NUM_ITEMS] = {{\n'.format(
                prefix, prefix, prefix.upper()))
            for name, item in sorted(items.items()):
                size = item[1]
                text = name[(len(prefix)):]
                if 'full' == list_items:
                    text = item[0]
                f.write('{{ "{}", {}, {} }},\n'.format(text, name, size))
            f.write('};\n')
Example #47
0
def parseOutput(output, lines) :
    '''
    Parse error output lines from the GLSL reference compiler,
    map them to the original source code location and output
    an error message compatible with Xcode or VStudio
    '''
    hasError = False
    outLines = output.splitlines()
    for outLine in outLines :
        if outLine.startswith('ERROR: ') :
            hasError = True

            # extract generated shader source column, line and message
            colStartIndex = 7
            colEndIndex = outLine.find(':', colStartIndex)
            if colEndIndex == -1 :
                continue
            lineStartIndex = colEndIndex + 1
            lineEndIndex = outLine.find(':', lineStartIndex)
            if lineEndIndex == -1 :
                continue
            msgStartIndex = lineEndIndex + 1
            colNr = int(outLine[colStartIndex:colEndIndex])
            lineNr = int(outLine[lineStartIndex:lineEndIndex])
            msg = outLine[msgStartIndex:]

            # map to original location
            lineIndex = lineNr - 1
            if lineIndex >= len(lines) :
                lineIndex = len(lines) - 1
            srcPath = lines[lineIndex].path
            srcLineNr = lines[lineIndex].lineNumber
            
            # and output...
            util.setErrorLocation(srcPath, srcLineNr)
            util.fmtError(msg, False)
            
    if hasError :
        for line in lines :
            print "{}\n".format(line.content)
        util.fmtError("Aborting.")
Example #48
0
 def onPrecision(self, args) :
     if not self.current or not self.current.getTag() in ['vs', 'fs'] :
         util.fmtError("@highp must come after @vs or @fs!")
     if len(args) != 1:
         util.fmtError("@highp must have 1 arg (type)")
     type = args[0]
     if checkListDup(type, self.current.highPrecision) :
         util.fmtError("@highp type '{}' already defined in '{}'!".format(type, self.current.name))
     self.current.highPrecision.append(type)
Example #49
0
def parseOutput(output, lines) :
    hasError = False
    hasWarnings = False
    outLines = output.splitlines()

    for outLine in outLines :
        if 'error:' in outLine or 'warning:' in outLine or 'note:' in outLine:
            tokens = outLine.split(':')
            metalSrcPath = tokens[0]
            lineNr = int(tokens[1])
            colNr = int(tokens[2])
            msgType = tokens[3]
            msg = tokens[4]

            if msgType == ' error':
                hasError = True
            if msgType == ' warning':
                hasWarning = True

            # map to original location
            lineIndex = lineNr - 1
            if lineIndex >= len(lines) :
                lineIndex = len(lines) - 1
            srcPath = lines[lineIndex].path
            srcLineNr = lines[lineIndex].lineNumber

            # and output...
            util.setErrorLocation(srcPath, srcLineNr)
            util.fmtError(msg, False)

    if hasError :
        for outLine in outLines :
            print(outLine)
        for line in lines :
            print(line.content)
        sys.exit(10) 
Example #50
0
 def onOut(self, args) :
     if not self.current or not self.current.getTag() in ['vs'] :
         util.fmtError("@out must come after @vs!")
     if len(args) != 2:
         util.fmtError("@out must have 2 args (type name)")
     type = args[0]
     name = args[1]
     if checkListDup(name, self.current.outputs) :
         util.fmtError("@out '{}' already defined in '{}'!".format(name, self.current.name))
     self.current.outputs.append(Attr(type, name, self.fileName, self.lineNumber))
Example #51
0
 def onBundle(self, args) :
     if len(args) != 1:
         util.fmtError("@bundle must have 1 arg (name)")
     if self.current is not None :
         util.fmtError("cannot nest @bundle (missing @end tag in '{}'?)".format(self.current.name))
     name = args[0]
     if name in self.shaderLib.bundles :
         util.fmtError("@bundle '{}' already defined!".format(name))
     bundle = Bundle(name)
     self.shaderLib.bundles[name] = bundle
     self.current = bundle            
Example #52
0
 def onBlock(self, args) :
     if len(args) != 1 :
         util.fmtError("@block must have 1 arg (name)")
     if self.current is not None :
         util.fmtError("cannot nest @block (missing @end in '{}'?)".format(self.current.name))
     name = args[0]
     if name in self.shaderLib.blocks :
         util.fmtError("@block '{}' already defined".format(name))
     block = Block(name)
     self.shaderLib.blocks[name] = block
     self.current = block
Example #53
0
 def onVertexShader(self, args) :
     if len(args) != 1:
         util.fmtError("@vs must have 1 arg (name)")
     if self.current is not None :
         util.fmtError("cannot nest @vs (missing @end in '{}'?)".format(self.current.name))
     name = args[0]
     if name in self.shaderLib.vertexShaders :
         util.fmtError("@vs '{}' already defined".format(name))
     vs = VertexShader(name)
     self.shaderLib.vertexShaders[name] = vs
     self.current = vs        
Example #54
0
 def onUniform(self, args) :
     if not self.current or not self.current.getTag() in ['block', 'vs', 'fs'] :
         util.fmtError("@uniform must come after @block, @vs or @fs tag!")
     if len(args) != 3:
         util.fmtError("@uniform must have 3 args (type name binding)")
     type = args[0]
     name = args[1]
     bind = args[2]
     if checkListDup(name, self.current.uniforms) :
         util.fmtError("@uniform '{}' already defined in '{}'!".format(name, self.current.name))
     self.current.uniforms.append(Uniform(type, name, bind, self.fileName, self.lineNumber))
Example #55
0
 def onFragmentShader(self, args) :
     if len(args) != 1:
         util.fmtError("@fs must have 1 arg (name)")
     if self.current is not None :
         util.fmtError("cannot nest @fs (missing @end in '{}'?)".format(self.current.name))
     name = args[0]
     if name in self.shaderLib.fragmentShaders :
         util.fmtError("@fs '{}' already defined!".format(name))
     fs = FragmentShader(name)
     self.shaderLib.fragmentShaders[name] = fs
     self.current = fs
Example #56
0
 def checkAddUniform(self, uniform, list) :
     '''
     Check if uniform already exists in list, if yes
     check if type and binding matches, if not write error.
     If uniform doesn't exist yet in list, add it.
     '''
     listUniform = findByName(uniform.name, list)
     if listUniform is not None:
         # redundant uniform, check if type and binding name match
         if listUniform.type != uniform.type :
             util.setErrorLocation(uniform.filePath, uniform.lineNumber)
             util.fmtError("uniform type mismatch '{}' vs '{}'".format(uniform.type, listUniform.type), False)
             util.setErrorLocation(listUniform.filePath, listUniform.lineNumber)
             util.fmtError("uniform type mismatch '{}' vs '{}'".format(listUniform.type, uniform.type))
         if listUniform.bind != uniform.bind :
             util.setErrorLocation(uniform.filePath, uniform.lineNumber)
             util.fmtError("uniform bind name mismatch '{}' vs '{}'".format(uniform.bind, listUniform.bind), False)
             util.setErrorLocation(listUniform.filePath, listUniform.lineNumber)
             util.fmtError("uniform bind name mismatch '{}' vs '{}'".format(listUniform.bind, uniform.bind))
     else :
         # new uniform from block, add to list
         list.append(uniform)
Example #57
0
 def onEnd(self, args) :
     if not self.current or not self.current.getTag() in ['block', 'vs', 'fs', 'bundle'] :
         util.fmtError("@end must come after @block, @vs, @fs or @bundle!")
     if len(args) != 0:
         util.fmtError("@end must not have arguments")
     self.current = None