def make_impl_tmpl_file(cls):
    body = []

    body.append('using System;')
    body.append('using System.Collections.Generic;')
    body.append('using System.Diagnostics;')
    body.append('using System.Runtime.InteropServices;')
    # body.append('using System.Diagnostics.CodeAnalysis;')
    body.append('using %s;' % schema.interop_namespace)
    body.append('')

    append_xmldoc(body, cls.get_comment())

    if schema.is_proxy(cls):
        body.append('public sealed unsafe partial class %s' % schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append( indent + ('\n' + indent + indent).join( make_proxy_impl_tmpl_body(cls) ) )
        body.append('}')

    if schema.is_handler(cls):
        body.append('public abstract unsafe partial class %s' % schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append( indent + ('\n' + indent + indent).join( make_handler_impl_tmpl_body(cls) ) )
        body.append('}')

    return \
"""namespace %(namespace)s
{
%(body)s
}
""" % {
        'namespace': schema.namespace,
        'body': indent + ('\n'+indent).join(body)
      }
def make_wrapper_g_file(cls):
    body = []

    body.append('using System;')
    body.append('using System.Collections.Generic;')
    body.append('using System.Diagnostics;')
    body.append('using System.Runtime.InteropServices;')
    # body.append('using System.Diagnostics.CodeAnalysis;')
    body.append('using %s;' % schema.interop_namespace)
    body.append('')

    for line in schema.get_overview(cls):
        body.append('// %s' % line)

    if schema.is_proxy(cls):
        body.append('public sealed unsafe partial class %s : IDisposable' % schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append( indent + ('\n' + indent + indent).join( make_proxy_g_body(cls) ) )
        body.append('}')

    if schema.is_handler(cls):
        body.append('public abstract unsafe partial class %s' % schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append( indent + ('\n' + indent + indent).join( make_handler_g_body(cls) ) )
        body.append('}')

    return make_file_header() + \
"""namespace %(namespace)s
{
%(body)s
}
""" % {
        'namespace': schema.namespace,
        'body': indent + ('\n'+indent).join(body)
      }
def make_impl_tmpl_file(cls):
    body = []

    body.append('using System;')
    body.append('using System.Collections.Generic;')
    body.append('using System.Diagnostics;')
    body.append('using System.Runtime.InteropServices;')
    # body.append('using System.Diagnostics.CodeAnalysis;')
    body.append('using %s;' % schema.interop_namespace)
    body.append('')

    append_xmldoc(body, cls.get_comment())

    if schema.is_proxy(cls):
        body.append('public sealed unsafe partial class %s' % schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append( indent + ('\n' + indent + indent).join( make_proxy_impl_tmpl_body(cls) ) )
        body.append('}')

    if schema.is_handler(cls):
        body.append('public abstract unsafe partial class %s' % schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append( indent + ('\n' + indent + indent).join( make_handler_impl_tmpl_body(cls) ) )
        body.append('}')

    return \
"""namespace %(namespace)s
{
%(body)s
}
""" % {
        'namespace': schema.namespace,
        'body': indent + ('\n'+indent).join(body)
      }
def make_wrapper_g_file(cls):
    body = []

    body.append('using System;')
    body.append('using System.Collections.Generic;')
    body.append('using System.Diagnostics;')
    body.append('using System.Runtime.InteropServices;')
    # body.append('using System.Diagnostics.CodeAnalysis;')
    body.append('using %s;' % schema.interop_namespace)
    body.append('')

    for line in schema.get_overview(cls):
        body.append('// %s' % line)

    if schema.is_proxy(cls):
        body.append('public sealed unsafe partial class %s : IDisposable' % schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append( indent + ('\n' + indent + indent).join( make_proxy_g_body(cls) ) )
        body.append('}')

    if schema.is_handler(cls):
        body.append('public abstract unsafe partial class %s' % schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append( indent + ('\n' + indent + indent).join( make_handler_g_body(cls) ) )
        body.append('}')

    return make_file_header() + \
"""namespace %(namespace)s
{
%(body)s
}
""" % {
        'namespace': schema.namespace,
        'body': indent + ('\n'+indent).join(body)
      }
Exemple #5
0
def write_interop(header, filepath, backup, schema_name, cppheaderdir):
    writect = 0

    schema.load(schema_name, header)

    # validate: class role must be defined for all header classes
    for cls in header.get_classes():
        if not schema.is_handler(cls) and not schema.is_proxy(cls):
            msg = 'Class role must be defined. Class name %s.' % cls.get_name()
            sys.stdout.write('ERROR! %s\n' % msg)
            raise Exception(msg)

    # structs
    for cls in header.get_classes():
        content = make_struct_file(cls)
        writect += update_file(filepath + '/' + schema.struct_path,
                               cls.get_capi_name() + ".g.cs", content, backup)

    # libcef.g.cs
    writect += update_file(filepath + '/' + schema.libcef_path,
                           schema.libcef_filename, make_libcef_file(header),
                           backup)

    # wrapper
    for cls in header.get_classes():
        content = make_wrapper_g_file(cls)
        writect += update_file(filepath + '/' + schema.wrapper_g_path,
                               schema.cpp2csname(cls.get_name()) + ".g.cs",
                               content, backup)

    # userdata
    userdatacls = obj_class(header, 'CefUserData', '', 'CefUserData',
                            'CefBaseRefCounted', '', '', '', [])
    content = make_struct_file(userdatacls)
    writect += update_file(filepath + '/' + schema.struct_path,
                           userdatacls.get_capi_name() + ".g.cs", content,
                           backup)
    content = make_wrapper_g_file(userdatacls)
    writect += update_file(filepath + '/' + schema.wrapper_g_path,
                           schema.cpp2csname(userdatacls.get_name()) + ".g.cs",
                           content, backup)

    # impl template
    for cls in header.get_classes():
        content = make_impl_tmpl_file(cls)
        tmplpath = schema.handler_tmpl_path
        if schema.is_proxy(cls):
            tmplpath = schema.proxy_tmpl_path
        writect += update_file(
            './' + tmplpath,
            schema.cpp2csname(cls.get_name()) + ".tmpl.g.cs", content, backup)

    # process cef_version_h
    content = make_version_cs(read_file(cppheaderdir + '/' + 'cef_version.h'))
    writect += update_file(filepath + '/' + schema.libcef_path,
                           schema.libcef_version_filename, content, backup)

    return writect
def make_wrapper_g_file(cls):
    body = []

    body.append('using System;')
    body.append('using System.Collections.Generic;')
    body.append('using System.Diagnostics;')
    body.append('using System.Runtime.InteropServices;')
    # body.append('using System.Diagnostics.CodeAnalysis;')
    body.append('using %s;' % schema.interop_namespace)
    body.append('')

    for line in schema.get_overview(cls):
        body.append('// %s' % line)

    isRefCounted = cls.get_parent_capi_name() == "cef_base_ref_counted_t"
    isScoped = cls.get_parent_capi_name() == "cef_base_scoped_t"

    if schema.is_proxy(cls):
        proxyBase = None
        if isRefCounted:
            proxyBase = " : IDisposable"
        elif isScoped:
            proxyBase = ""
        else:
            raise Exception("Unknown base class type.")
        body.append(('public sealed unsafe partial class %s' + proxyBase) %
                    schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append(indent +
                    ('\n' + indent + indent).join(make_proxy_g_body(cls)))
        body.append('}')

    if schema.is_handler(cls):
        body.append('public abstract unsafe partial class %s' %
                    schema.cpp2csname(cls.get_name()))
        body.append('{')
        body.append(indent +
                    ('\n' + indent + indent).join(make_handler_g_body(cls)))
        body.append('}')

    return make_file_header() + \
"""namespace %(namespace)s
{
%(body)s
}
""" % {
        'namespace': schema.namespace,
        'body': indent + ('\n'+indent).join(body)
      }
def make_proxy_impl_tmpl_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)
    funcs = get_funcs(cls, False)
    static_funcs = []
    for func in cls.get_static_funcs():
        static_funcs.append( get_func_parts(func, 0) )

    result = []

    for func in static_funcs:
        append_xmldoc(result, func['obj'].get_comment())
        result.append('public static %(csn_retval)s %(name)s(%(csn_args_proto)s)' % func)
        result.append('{')
        result.append('    throw new NotImplementedException(); // TODO: %(csname)s.%(name)s' % { 'csname': csname, 'name' : func['name'] })
        result.append('}')
        result.append('')

    for func in funcs:
        name = func['name']
        retval = func['csn_retval']
        args = func['csn_args_proto']
        if func['csn_args'][0]['name'] == 'self':
            args = ', '.join(map(lambda x: '%s %s' % (x['type'], x['name']), func['csn_args'][1:]))

        append_xmldoc(result, func['obj'].get_comment())

        result.append('public %s %s(%s)' % (retval, name, args))
        result.append('{')
        result.append('    throw new NotImplementedException(); // TODO: %(csname)s.%(name)s' % { 'csname': csname, 'name' : func['name'] })
        result.append('}')
        result.append('')

    return result
def make_proxy_impl_tmpl_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)
    funcs = get_funcs(cls, False)
    static_funcs = []
    for func in cls.get_static_funcs():
        static_funcs.append( get_func_parts(func, 0) )

    result = []

    for func in static_funcs:
        append_xmldoc(result, func['obj'].get_comment())
        result.append('public static %(csn_retval)s %(name)s(%(csn_args_proto)s)' % func)
        result.append('{')
        result.append('    throw new NotImplementedException(); // TODO: %(csname)s.%(name)s' % { 'csname': csname, 'name' : func['name'] })
        result.append('}')
        result.append('')

    for func in funcs:
        name = func['name']
        retval = func['csn_retval']
        args = func['csn_args_proto']
        if func['csn_args'][0]['name'] == 'self':
            args = ', '.join(map(lambda x: '%s %s' % (x['type'], x['name']), func['csn_args'][1:]))

        append_xmldoc(result, func['obj'].get_comment())

        result.append('public %s %s(%s)' % (retval, name, args))
        result.append('{')
        result.append('    throw new NotImplementedException(); // TODO: %(csname)s.%(name)s' % { 'csname': csname, 'name' : func['name'] })
        result.append('}')
        result.append('')

    return result
def write_interop(header, filepath, backup, schema_name, cppheaderdir):
    writect = 0

    schema.load(schema_name, header)

    # validate: class role must be defined for all header classes
    for cls in header.get_classes():
        if not schema.is_handler(cls) and not schema.is_proxy(cls):
            msg = 'Class role must be defined. Class name %s.' % cls.get_name()
            sys.stdout.write('ERROR! %s\n' % msg)
            raise Exception(msg)

    # structs
    for cls in header.get_classes():
        content = make_struct_file(cls)
        writect += update_file(filepath + '/' + schema.struct_path, cls.get_capi_name() + ".g.cs", content, backup)

    # libcef.g.cs
    writect += update_file(filepath + '/' + schema.libcef_path, schema.libcef_filename, make_libcef_file(header), backup)
    
    # wrapper
    for cls in header.get_classes():
        content = make_wrapper_g_file(cls)
        writect += update_file(filepath + '/' + schema.wrapper_g_path, schema.cpp2csname(cls.get_name()) + ".g.cs", content, backup)

    # userdata    
    userdatacls = obj_class(header, 'CefUserData', '', 'CefUserData', '', '', '')
    content = make_struct_file(userdatacls)
    writect += update_file(filepath + '/' + schema.struct_path, userdatacls.get_capi_name() + ".g.cs", content, backup)
    content = make_wrapper_g_file(userdatacls)
    writect += update_file(filepath + '/' + schema.wrapper_g_path, schema.cpp2csname(userdatacls.get_name()) + ".g.cs", content, backup)
    
    # impl template
    for cls in header.get_classes():
        content = make_impl_tmpl_file(cls)
        tmplpath = schema.handler_tmpl_path
        if schema.is_proxy(cls):
            tmplpath = schema.proxy_tmpl_path
        writect += update_file('./' + tmplpath, schema.cpp2csname(cls.get_name()) + ".tmpl.g.cs", content, backup)

    # process cef_version_h
    content = make_version_cs(read_file(cppheaderdir + '/' + 'cef_version.h'))
    writect += update_file(filepath + '/' + schema.libcef_path, schema.libcef_version_filename, content, backup)

    return writect
def make_handler_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    funcs = get_funcs(cls)

    result = []

    # this dictionary used to keep object alive even when we doesn't reference object directly, but it can be referenced only from native side
    result.append(
        'private static Dictionary<IntPtr, %(csname)s> _roots = new Dictionary<IntPtr, %(csname)s>();'
        % {'csname': csname})
    result.append('')

    result.append('private int _refct;')
    result.append('private %s* _self;' % iname)
    # result.append('private bool _disposed;')
    result.append('')

    result.append('protected object SyncRoot { get { return this; } }')
    result.append('')

    if schema.is_reversible(cls):
        result.append('internal static %s FromNativeOrNull(%s* ptr)' %
                      (csname, iname))
        result.append('{')
        result.append(indent + '%s value = null;' % csname)
        result.append(indent + 'bool found;')
        result.append(indent + 'lock (_roots)')
        result.append(indent + '{')
        result.append(indent + indent +
                      'found = _roots.TryGetValue((IntPtr)ptr, out value);')
        result.append(indent + '}')
        result.append(indent + 'return found ? value : null;')
        result.append('}')
        result.append('')

        result.append('internal static %s FromNative(%s* ptr)' %
                      (csname, iname))
        result.append('{')
        result.append(indent + 'var value = FromNativeOrNull(ptr);')
        result.append(
            indent +
            'if (value == null) throw ExceptionBuilder.ObjectNotFound();')
        result.append(indent + 'return value;')
        result.append('}')
        result.append('')

    for func in funcs:
        result.append(
            'private %(iname)s.%(delegate_type)s %(delegate_slot)s;' % func)
    result.append('')

    # ctor
    result.append('protected %s()' % csname)
    result.append('{')
    result.append(indent + '_self = %s.Alloc();' % iname)
    result.append('')
    for func in funcs:
        result.append(
            indent +
            '%(delegate_slot)s = new %(iname)s.%(delegate_type)s(%(csn_name)s);'
            % func)
        result.append(
            indent +
            '_self->%(field_name)s = Marshal.GetFunctionPointerForDelegate(%(delegate_slot)s);'
            % func)
    result.append('}')
    result.append('')

    # finalizer & dispose
    result.append('~%s()' % csname)
    result.append('{')
    result.append(indent + 'Dispose(false);')
    result.append('}')
    result.append('')

    if schema.is_autodispose(cls):
        result.append('private void Dispose()')
        result.append('{')
        result.append(indent + 'Dispose(true);')
        result.append(indent + 'GC.SuppressFinalize(this);')
        result.append('}')
        result.append('')

    result.append('protected virtual void Dispose(bool disposing)')
    result.append('{')
    # result.append(indent + '_disposed = true;')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + '%s.Free(_self);' % iname)
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    # todo: this methods must throw exception if object already disposed
    # todo: verify self pointer in debug
    result.append('private void add_ref(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot)')
    result.append(indent + '{')
    result.append(indent + indent + 'var result = ++_refct;')
    result.append(indent + indent + 'if (result == 1)')
    result.append(indent + indent + '{')
    result.append(indent + indent + indent +
                  'lock (_roots) { _roots.Add((IntPtr)_self, this); }')
    result.append(indent + indent + '}')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('private int release(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot)')
    result.append(indent + '{')
    result.append(indent + indent + 'var result = --_refct;')
    result.append(indent + indent + 'if (result == 0)')
    result.append(indent + indent + '{')
    result.append(indent + indent + indent +
                  'lock (_roots) { _roots.Remove((IntPtr)_self); }')
    if schema.is_autodispose(cls):
        result.append(indent + indent + indent + 'Dispose();')
    result.append(indent + indent + indent + 'return 1;')
    result.append(indent + indent + '}')
    result.append(indent + indent + 'return 0;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('private int has_one_ref(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot) { return _refct == 1 ? 1 : 0; }')
    result.append('}')
    result.append('')

    result.append('private int has_at_least_one_ref(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot) { return _refct != 0 ? 1 : 0; }')
    result.append('}')
    result.append('')

    result.append('internal %s* ToNative()' % iname)
    result.append('{')
    result.append(indent + 'add_ref(_self);')
    result.append(indent + 'return _self;')
    result.append('}')
    result.append('')

    result.append('[Conditional("DEBUG")]')
    result.append('private void CheckSelf(%s* self)' % iname)
    result.append('{')
    result.append(
        indent +
        'if (_self != self) throw ExceptionBuilder.InvalidSelfReference();')
    result.append('}')
    result.append('')

    return result
def make_proxy_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    result = []

    # result.append('#if DEBUG')
    # result.append('private static int _objCt;')
    # result.append('internal static int ObjCt { get { return _objCt; } }')
    # result.append('#endif')
    # result.append('')

    # static methods
    result.append('internal static %(csname)s FromNative(%(iname)s* ptr)' % {
        'csname': csname,
        'iname': iname
    })
    result.append('{')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    result.append(
        'internal static %(csname)s FromNativeOrNull(%(iname)s* ptr)' % {
            'csname': csname,
            'iname': iname
        })
    result.append('{')
    result.append(indent + 'if (ptr == null) return null;')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    # private fields
    result.append('private %s* _self;' % iname)
    result.append('')

    # ctor
    result.append('private %(csname)s(%(iname)s* ptr)' % {
        'csname': csname,
        'iname': iname
    })
    result.append('{')
    result.append(indent +
                  'if (ptr == null) throw new ArgumentNullException("ptr");')
    result.append(indent + '_self = ptr;')
    #
    # todo: diagnostics code: Interlocked.Increment(ref _objCt);
    #
    result.append('}')
    result.append('')

    isRefCounted = cls.get_parent_capi_name() == "cef_base_ref_counted_t"
    isScoped = cls.get_parent_capi_name() == "cef_base_scoped_t"

    if isRefCounted:
        # disposable
        result.append('~%s()' % csname)
        result.append('{')
        result.append(indent + 'if (_self != null)')
        result.append(indent + '{')
        result.append(indent + indent + 'Release();')
        result.append(indent + indent + '_self = null;')
        result.append(indent + '}')
        result.append('}')
        result.append('')

        result.append('public void Dispose()')
        result.append('{')
        result.append(indent + 'if (_self != null)')
        result.append(indent + '{')
        result.append(indent + indent + 'Release();')
        result.append(indent + indent + '_self = null;')
        result.append(indent + '}')
        result.append(indent + 'GC.SuppressFinalize(this);')
        result.append('}')
        result.append('')

        result.append('internal void AddRef()')
        result.append('{')
        result.append(indent + '%(iname)s.add_ref(_self);' % {'iname': iname})
        result.append('}')
        result.append('')

        result.append('internal bool Release()')
        result.append('{')
        result.append(indent + 'return %(iname)s.release(_self) != 0;' %
                      {'iname': iname})
        result.append('}')
        result.append('')

        result.append('internal bool HasOneRef')
        result.append('{')
        result.append(indent +
                      'get { return %(iname)s.has_one_ref(_self) != 0; }' %
                      {'iname': iname})
        result.append('}')
        result.append('')

        result.append('internal bool HasAtLeastOneRef')
        result.append('{')
        result.append(
            indent +
            'get { return %(iname)s.has_at_least_one_ref(_self) != 0; }' %
            {'iname': iname})
        result.append('}')
        result.append('')
    elif isScoped:
        result.append("// FIXME: code for CefBaseScoped is not generated")
        result.append("")
    else:
        raise Exception("Unsupported base class name.")

    # TODO: use it only if it is really necessary!
    # result.append('internal %(iname)s* Pointer' % { 'iname' : iname })
    # result.append('{')
    # result.append(indent + 'get { return _self; }')
    # result.append('}')
    # result.append('')

    result.append('internal %(iname)s* ToNative()' % {'iname': iname})
    result.append('{')
    if isRefCounted:
        result.append(indent + 'AddRef();')
    result.append(indent + 'return _self;')
    result.append('}')

    return result
def make_handler_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    funcs = get_funcs(cls)

    result = []

    # this dictionary used to keep object alive even when we doesn't reference object directly, but it can be referenced only from native side
    result.append('private static Dictionary<IntPtr, %(csname)s> _roots = new Dictionary<IntPtr, %(csname)s>();' % { 'csname' : csname })
    result.append('')

    result.append('private int _refct;')
    result.append('private %s* _self;' % iname)
    # result.append('private bool _disposed;')
    result.append('')

    result.append('protected object SyncRoot { get { return this; } }')
    result.append('')

    if schema.is_reversible(cls):
        result.append('internal static %s FromNativeOrNull(%s* ptr)' % (csname, iname))
        result.append('{')
        result.append(indent + '%s value = null;' % csname)
        result.append(indent + 'bool found;')
        result.append(indent + 'lock (_roots)')
        result.append(indent + '{')
        result.append(indent + indent + 'found = _roots.TryGetValue((IntPtr)ptr, out value);')
        result.append(indent + '}')
        result.append(indent + 'return found ? value : null;')
        result.append('}')
        result.append('')

        result.append('internal static %s FromNative(%s* ptr)' % (csname, iname))
        result.append('{')
        result.append(indent + 'var value = FromNativeOrNull(ptr);')
        result.append(indent + 'if (value == null) throw ExceptionBuilder.ObjectNotFound();')
        result.append(indent + 'return value;')
        result.append('}')
        result.append('')

    for func in funcs:
        result.append('private %(iname)s.%(delegate_type)s %(delegate_slot)s;' % func)
    result.append('')

    # ctor
    result.append('protected %s()' % csname)
    result.append('{')
    result.append(indent + '_self = %s.Alloc();' % iname)
    result.append('');
    for func in funcs:
        result.append(indent + '%(delegate_slot)s = new %(iname)s.%(delegate_type)s(%(csn_name)s);' % func)
        result.append(indent + '_self->%(field_name)s = Marshal.GetFunctionPointerForDelegate(%(delegate_slot)s);' % func)
    result.append('}')
    result.append('')

    # finalizer & dispose
    result.append('~%s()' % csname)
    result.append('{')
    result.append(indent + 'Dispose(false);')
    result.append('}')
    result.append('')

    result.append('protected virtual void Dispose(bool disposing)')
    result.append('{')
    # result.append(indent + '_disposed = true;')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + '%s.Free(_self);' % iname)
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    # todo: this methods must throw exception if object already disposed
    # todo: verify self pointer in debug
    result.append('private int add_ref(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot)')
    result.append(indent + '{')
    result.append(indent + indent + 'var result = ++_refct;')
    result.append(indent + indent + 'if (result == 1)')
    result.append(indent + indent + '{')
    result.append(indent + indent + indent + 'lock (_roots) { _roots.Add((IntPtr)_self, this); }')
    result.append(indent + indent + '}')
    result.append(indent + indent + 'return result;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('private int release(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'lock (SyncRoot)')
    result.append(indent + '{')
    result.append(indent + indent + 'var result = --_refct;')
    result.append(indent + indent + 'if (result == 0)')
    result.append(indent + indent + '{')
    result.append(indent + indent + indent + 'lock (_roots) { _roots.Remove((IntPtr)_self); }')
    result.append(indent + indent + '}')
    result.append(indent + indent + 'return result;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('private int get_refct(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'return _refct;')
    result.append('}')
    result.append('')

    result.append('internal %s* ToNative()' % iname)
    result.append('{')
    result.append(indent + 'add_ref(_self);')
    result.append(indent + 'return _self;')
    result.append('}')
    result.append('')

    result.append('[Conditional("DEBUG")]')
    result.append('private void CheckSelf(%s* self)' % iname)
    result.append('{')
    result.append(indent + 'if (_self != self) throw ExceptionBuilder.InvalidSelfReference();')
    result.append('}')
    result.append('')

    return result
def make_proxy_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    result = []

    # result.append('#if DEBUG')
    # result.append('private static int _objCt;')
    # result.append('internal static int ObjCt { get { return _objCt; } }')
    # result.append('#endif')
    # result.append('')

    # static methods
    result.append('internal static %(csname)s FromNative(%(iname)s* ptr)' % { 'csname' : csname, 'iname' : iname })
    result.append('{')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    result.append('internal static %(csname)s FromNativeOrNull(%(iname)s* ptr)' % { 'csname' : csname, 'iname' : iname })
    result.append('{')
    result.append(indent + 'if (ptr == null) return null;')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    # private fields
    result.append('private %s* _self;' % iname)
    result.append('')

    # ctor
    result.append('private %(csname)s(%(iname)s* ptr)' % { 'csname' : csname, 'iname' : iname })
    result.append('{')
    result.append(indent + 'if (ptr == null) throw new ArgumentNullException("ptr");')
    result.append(indent + '_self = ptr;')
    #
    # todo: diagnostics code: Interlocked.Increment(ref _objCt);
    #
    result.append('}')
    result.append('')

    # disposable
    result.append('~%s()' % csname)
    result.append('{')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + 'Release();')
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('public void Dispose()')
    result.append('{')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + 'Release();')
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append(indent + 'GC.SuppressFinalize(this);')
    result.append('}')
    result.append('')

    result.append('internal int AddRef()')
    result.append('{')
    result.append(indent + 'return %(iname)s.add_ref(_self);' % { 'iname': iname })
    result.append('}')
    result.append('')

    result.append('internal int Release()')
    result.append('{')
    result.append(indent + 'return %(iname)s.release(_self);' % { 'iname': iname })
    result.append('}')
    result.append('')

    result.append('internal int RefCt')
    result.append('{')
    result.append(indent + 'get { return %(iname)s.get_refct(_self); }' % { 'iname': iname })
    result.append('}')
    result.append('')

    # TODO: use it only if it is really necessary!
    # result.append('internal %(iname)s* Pointer' % { 'iname' : iname })
    # result.append('{')
    # result.append(indent + 'get { return _self; }')
    # result.append('}')
    # result.append('')

    result.append('internal %(iname)s* ToNative()' % { 'iname' : iname })
    result.append('{')
    result.append(indent + 'AddRef();')
    result.append(indent + 'return _self;')
    result.append('}')

    return result
Exemple #14
0
def make_proxy_g_body(cls):
    csname = schema.cpp2csname(cls.get_name())
    iname = schema.get_iname(cls)

    result = []

    # result.append('#if DEBUG')
    # result.append('private static int _objCt;')
    # result.append('internal static int ObjCt { get { return _objCt; } }')
    # result.append('#endif')
    # result.append('')

    # static methods
    result.append('internal static %(csname)s FromNative(%(iname)s* ptr)' % {
        'csname': csname,
        'iname': iname
    })
    result.append('{')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    result.append(
        'internal static %(csname)s FromNativeOrNull(%(iname)s* ptr)' % {
            'csname': csname,
            'iname': iname
        })
    result.append('{')
    result.append(indent + 'if (ptr == null) return null;')
    result.append(indent + 'return new %s(ptr);' % csname)
    result.append('}')
    result.append('')

    # private fields
    result.append('private %s* _self;' % iname)
    result.append('')

    # ctor
    result.append('private %(csname)s(%(iname)s* ptr)' % {
        'csname': csname,
        'iname': iname
    })
    result.append('{')
    result.append(indent +
                  'if (ptr == null) throw new ArgumentNullException("ptr");')
    result.append(indent + '_self = ptr;')
    #
    # todo: diagnostics code: Interlocked.Increment(ref _objCt);
    #
    result.append('}')
    result.append('')

    # disposable
    result.append('~%s()' % csname)
    result.append('{')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + 'Release();')
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append('}')
    result.append('')

    result.append('public void Dispose()')
    result.append('{')
    result.append(indent + 'if (_self != null)')
    result.append(indent + '{')
    result.append(indent + indent + 'Release();')
    result.append(indent + indent + '_self = null;')
    result.append(indent + '}')
    result.append(indent + 'GC.SuppressFinalize(this);')
    result.append('}')
    result.append('')

    result.append('internal void AddRef()')
    result.append('{')
    result.append(indent + '%(iname)s.add_ref(_self);' % {'iname': iname})
    result.append('}')
    result.append('')

    result.append('internal bool Release()')
    result.append('{')
    result.append(indent +
                  'return %(iname)s.release(_self) != 0;' % {'iname': iname})
    result.append('}')
    result.append('')

    result.append('internal bool HasOneRef')
    result.append('{')
    result.append(indent +
                  'get { return %(iname)s.has_one_ref(_self) != 0; }' %
                  {'iname': iname})
    result.append('}')
    result.append('')

    # TODO: use it only if it is really necessary!
    # result.append('internal %(iname)s* Pointer' % { 'iname' : iname })
    # result.append('{')
    # result.append(indent + 'get { return _self; }')
    # result.append('}')
    # result.append('')

    result.append('internal %(iname)s* ToNative()' % {'iname': iname})
    result.append('{')
    result.append(indent + 'AddRef();')
    result.append(indent + 'return _self;')
    result.append('}')

    return result