commit 32208ee7a1c84f91578b934fe0308d1927e43885 Author: Rico Schüller Date: Thu Apr 21 11:05:17 2011 +0200 d3dx9: Improve get_parameter_by_name(). diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index 0f65df7..b4ffc37 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -107,6 +107,11 @@ struct ID3DXEffectCompilerImpl ID3DXBaseEffect *base_effect; }; +static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base, + struct d3dx_parameter *parameter, LPCSTR name); +static struct d3dx_parameter *get_parameter_annotation_by_name(struct ID3DXBaseEffectImpl *base, + struct d3dx_parameter *parameter, LPCSTR name); + static inline void read_dword(const char **ptr, DWORD *d) { memcpy(d, *ptr, sizeof(*d)); @@ -436,151 +441,160 @@ static void free_effect_compiler(struct ID3DXEffectCompilerImpl *compiler) } } -static LPSTR get_partial_string(LPCSTR name, char initial, char final) +static UINT name_length(LPCSTR name) { - UINT length; - LPCSTR begin; - LPSTR part; + UINT length, i; + const char chars[] = {'[', '.', '@'}; - TRACE("name %s, initial %c, final %c\n", debugstr_a(name), initial, final); + length = strlen(name); - begin = initial ? (strchr(name, initial) + 1) : name; - length = strchr(name, final) - begin; - if (length < 1) + for (i = 0; i < sizeof(chars); ++i) { - WARN("Invalied argument specified.\n"); - return NULL; - } + LPCSTR found = strchr(name, chars[i]); - part = HeapAlloc(GetProcessHeap(), 0, length + 1); - if (!part) - { - ERR("Out of memory\n"); - return NULL; + if (found) + { + length = min(length, found - name); + } } - memcpy(part, begin, length); - part[length] = 0; - TRACE("part %s\n", debugstr_a(part)); - return part; + return length; } -static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base, struct d3dx_parameter *parameter, LPCSTR name, BOOL is_annotation) +static struct d3dx_parameter *get_parameter_element_by_name(struct ID3DXBaseEffectImpl *base, + struct d3dx_parameter *parameter, LPCSTR name) { - unsigned int i; + UINT element; struct d3dx_parameter *temp_parameter; - LPSTR part; + LPCSTR part; - TRACE("base %p, parameter %p, name %s, is_annotation %s\n", base, parameter, debugstr_a(name), is_annotation ? "YES" : "NO"); + TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name)); - if (!name) return NULL; + if (!name || !*name) return parameter; - /* members */ - if (strchr(name, '.')) + element = atoi(name); + part = strchr(name, ']') + 1; + + if (parameter->element_count > element) { - part = get_partial_string(name, 0, '.'); - temp_parameter = get_parameter_by_name(base, parameter, part, is_annotation); - HeapFree(GetProcessHeap(), 0, part); + temp_parameter = get_parameter_struct(parameter->member_handles[element]); - if (temp_parameter) + switch (*part++) { - temp_parameter = get_parameter_by_name(base, temp_parameter, strchr(name, '.') + 1, FALSE); - TRACE("Returning sub parameter %p\n", temp_parameter); - return temp_parameter; - } + case '.': + return get_parameter_by_name(base, temp_parameter, part); - TRACE("Sub parameter not found\n"); - return NULL; - } + case '@': + return get_parameter_annotation_by_name(base, temp_parameter, part); - /* annotations */ - if (strchr(name, '@')) - { - part = get_partial_string(name, 0, '@'); - temp_parameter = get_parameter_by_name(base, parameter, part, is_annotation); - HeapFree(GetProcessHeap(), 0, part); + case '\0': + return temp_parameter; - if (temp_parameter) - { - temp_parameter = get_parameter_by_name(base, temp_parameter, strchr(name, '@') + 1, TRUE); - TRACE("Returning sub parameter %p\n", temp_parameter); - return temp_parameter; + default: + FIXME("Unhandled case \"%c\"\n", *--part); + break; } - - TRACE("Sub parameter not found\n"); - return NULL; } - /* elements */ - if (strchr(name, '[')) + TRACE("Parameter not found\n"); + return NULL; +} + +static struct d3dx_parameter *get_parameter_annotation_by_name(struct ID3DXBaseEffectImpl *base, + struct d3dx_parameter *parameter, LPCSTR name) +{ + UINT i, length; + struct d3dx_parameter *temp_parameter; + LPCSTR part; + + TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name)); + + if (!name || !*name) return parameter; + + length = name_length(name); + part = name + length; + + for (i = 0; i < parameter->annotation_count; ++i) { - part = get_partial_string(name, 0, '['); - temp_parameter = get_parameter_by_name(base, parameter, part, is_annotation); - HeapFree(GetProcessHeap(), 0, part); + temp_parameter = get_parameter_struct(parameter->annotation_handles[i]); - if (temp_parameter) + if (!strcmp(temp_parameter->name, name)) + { + TRACE("Returning parameter %p\n", temp_parameter); + return temp_parameter; + } + else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length)) { - unsigned int index; + switch (*part++) + { + case '.': + return get_parameter_by_name(base, temp_parameter, part); - part = get_partial_string(name, '[', ']'); - index = atoi(part); - HeapFree(GetProcessHeap(), 0, part); + case '[': + return get_parameter_element_by_name(base, temp_parameter, part); - if (index < temp_parameter->element_count) - { - TRACE("Returning sub parameter %p\n", get_parameter_struct(temp_parameter->member_handles[index])); - return get_parameter_struct(temp_parameter->member_handles[index]); + default: + FIXME("Unhandled case \"%c\"\n", *--part); + break; } } - - TRACE("Sub parameter not found\n"); - return NULL; } + TRACE("Parameter not found\n"); + return NULL; +} + +static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base, + struct d3dx_parameter *parameter, LPCSTR name) +{ + UINT i, count, length; + struct d3dx_parameter *temp_parameter; + D3DXHANDLE *handles; + LPCSTR part; + + TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name)); + + if (!name || !*name) return parameter; + if (!parameter) { - for (i=0; i < base->parameter_count; i++) - { - temp_parameter = get_parameter_struct(base->parameter_handles[i]); - - if (!strcmp(temp_parameter->name, name)) - { - TRACE("Returning parameter %p\n", temp_parameter); - return temp_parameter; - } - } + count = base->parameter_count; + handles = base->parameter_handles; } else { - if (is_annotation) - { - for (i = 0; i < parameter->annotation_count; i++) - { - temp_parameter = get_parameter_struct(parameter->annotation_handles[i]); + count = parameter->member_count; + handles = parameter->member_handles; + } - if (!strcmp(temp_parameter->name, name)) - { - TRACE("Returning parameter %p\n", temp_parameter); - return temp_parameter; - } - } + length = name_length(name); + part = name + length; + + for (i = 0; i < count; i++) + { + temp_parameter = get_parameter_struct(handles[i]); + + if (!strcmp(temp_parameter->name, name)) + { + TRACE("Returning parameter %p\n", temp_parameter); + return temp_parameter; } - else + else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length)) { - unsigned int count; + switch (*part++) + { + case '.': + return get_parameter_by_name(base, temp_parameter, part); - if (parameter->element_count) count = parameter->element_count; - else count = parameter->member_count; + case '@': + return get_parameter_annotation_by_name(base, temp_parameter, part); - for (i = 0; i < count; i++) - { - temp_parameter = get_parameter_struct(parameter->member_handles[i]); + case '[': + return get_parameter_element_by_name(base, temp_parameter, part); - if (!strcmp(temp_parameter->name, name)) - { - TRACE("Returning parameter %p\n", temp_parameter); - return temp_parameter; - } + default: + FIXME("Unhandled case \"%c\"\n", *--part); + break; } } } @@ -743,7 +757,7 @@ static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect *iface TRACE("iface %p, parameter %p, index %u\n", This, parameter, index); - if (!param) param = get_parameter_by_name(This, NULL, parameter, FALSE); + if (!param) param = get_parameter_by_name(This, NULL, parameter); if (!parameter) { @@ -775,7 +789,7 @@ static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterByName(ID3DXBaseEffect TRACE("iface %p, parameter %p, name %s\n", This, parameter, debugstr_a(name)); - if (!param) param = get_parameter_by_name(This, NULL, parameter, FALSE); + if (!param) param = get_parameter_by_name(This, NULL, parameter); if (!name) { @@ -784,7 +798,7 @@ static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterByName(ID3DXBaseEffect return handle; } - handle = get_parameter_handle(get_parameter_by_name(This, param, name, FALSE)); + handle = get_parameter_handle(get_parameter_by_name(This, param, name)); TRACE("Returning parameter %p\n", handle); return handle; @@ -806,7 +820,7 @@ static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterElement(ID3DXBaseEffect TRACE("iface %p, parameter %p, index %u\n", This, parameter, index); - if (!param) param = get_parameter_by_name(This, NULL, parameter, FALSE); + if (!param) param = get_parameter_by_name(This, NULL, parameter); if (!param) { commit 55ac28b2b6ca4442441042f65bd2f9eb05b7e7bb Author: Rico Schüller Date: Wed Apr 20 21:58:25 2011 +0200 d3dx9: Improve ID3DXBaseEffect::GetParameter(). diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c index d44616c..0f65df7 100644 --- a/dlls/d3dx9_36/effect.c +++ b/dlls/d3dx9_36/effect.c @@ -739,9 +739,12 @@ static HRESULT WINAPI ID3DXBaseEffectImpl_GetFunctionDesc(ID3DXBaseEffect *iface static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT index) { struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface); + struct d3dx_parameter *param = is_valid_parameter(This, parameter); TRACE("iface %p, parameter %p, index %u\n", This, parameter, index); + if (!param) param = get_parameter_by_name(This, NULL, parameter, FALSE); + if (!parameter) { if (index < This->parameter_count) @@ -752,8 +755,6 @@ static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect *iface } else { - struct d3dx_parameter *param = is_valid_parameter(This, parameter); - if (param && !param->element_count && index < param->member_count) { TRACE("Returning parameter %p\n", param->member_handles[index]);