Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The SketchUp C API is much more limmited than the ruby api. There is no gui eve

# Fully implemented classes
* Attribute Dictionary
* Attribute Dictionaries
* Color
* Component Definition
* Definition List
Expand All @@ -16,7 +17,6 @@ The SketchUp C API is much more limmited than the ruby api. There is no gui eve
* Texture

# Partially implemented classes
* Attribute Dictionaries
* Behavior
* Component Instance
* Entities
Expand Down
99 changes: 95 additions & 4 deletions ext/attribute_dictionaries.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,37 @@
#include <utils.h>
#include <SketchUpAPI/sketchup.h>

struct AttributeDictionaryStringIterationContext
{
VALUE key;
SUAttributeDictionaryRef dictionary;
};

void Sketchup_AttributeDictionaries_Get_By_String_Iterator(SUAttributeDictionaryRef dictionary, struct AttributeDictionaryStringIterationContext* dictionary_struct)
{
VALUE output;
GETSTRING(SUAttributeDictionaryGetName, dictionary, output);
if (strcmp(StringValuePtr(output), StringValuePtr(dictionary_struct->key)) == 0)
dictionary_struct->dictionary = dictionary;
}

static VALUE Sketchup_AttributeDictionaries_get(VALUE self, VALUE key)
{
SUModelRef model = {DATA_PTR(self)};
SUAttributeDictionaryRef dictionary = SU_INVALID;
enum SUResult result = SUModelGetAttributeDictionary(model, StringValuePtr(key), &dictionary);
if (result != SU_ERROR_NONE)
return Qnil;
if (rb_ivar_defined(self, rb_intern("@is_model")) == Qtrue && RTEST(rb_iv_get(self, "@is_model")))
{
SUModelRef model = {DATA_PTR(self)};
enum SUResult result = SUModelGetAttributeDictionary(model, StringValuePtr(key), &dictionary);
if (result != SU_ERROR_NONE)
return Qnil;
}
else
{
SUEntityRef entity = {DATA_PTR(self)};
enum SUResult result = SUEntityGetAttributeDictionary(entity, StringValuePtr(key), &dictionary);
if (result != SU_ERROR_NONE)
return Qnil;
}
return Data_Wrap_Struct(rb_path2class(SKETCHUP_ATTRIBUTEDICTIONARY), 0, 0, dictionary.ptr);
}

Expand All @@ -33,6 +57,72 @@ static VALUE Sketchup_AttributeDictionaries_length(VALUE self)
return ULL2NUM(count);
}

static VALUE Sketchup_AttributeDictionaries_delete(VALUE self, VALUE dictionary)
{
if (rb_ivar_defined(self, rb_intern("@is_model")) == Qtrue && RTEST(rb_iv_get(self, "@is_model")))
{
SUModelRef model = {DATA_PTR(self)};
if (rb_type(dictionary) == T_STRING)
{
struct AttributeDictionaryStringIterationContext dictionary_struct = {dictionary, SU_INVALID};
FOREACH(SUModelGetNumAttributeDictionaries, SUModelGetAttributeDictionaries, SUAttributeDictionaryRef, model, Sketchup_AttributeDictionaries_Get_By_String_Iterator, &dictionary_struct);
if (SUIsInvalid(dictionary_struct.dictionary))
return Qnil;
SUAttributeDictionaryRelease(&dictionary_struct.dictionary);
size_t ad_count = 0;
size_t ad_len = 0;
SUModelGetNumAttributeDictionaries(model, &ad_len);
SUAttributeDictionaryRef* dictionaries;
SUModelGetAttributeDictionaries(model, ad_len, dictionaries, &ad_count);
return Data_Wrap_Struct(rb_path2class(SKETCHUP_ATTRIBUTEDICTIONARIES), 0, 0, dictionaries);
}
else if (rb_obj_is_kind_of(dictionary, rb_path2class(SKETCHUP_ATTRIBUTEDICTIONARY)))
{
SUAttributeDictionaryRef dictionary_ref = {DATA_PTR(dictionary)};
SUAttributeDictionaryRelease(&dictionary_ref);
size_t ad_count = 0;
size_t ad_len = 0;
SUModelGetNumAttributeDictionaries(model, &ad_len);
SUAttributeDictionaryRef* dictionaries;
SUModelGetAttributeDictionaries(model, ad_len, dictionaries, &ad_count);
return Data_Wrap_Struct(rb_path2class(SKETCHUP_ATTRIBUTEDICTIONARIES), 0, 0, dictionaries);
}
else
rb_raise(rb_eArgError, "Wrong argument type. Expected String or AttributeDictionary");
}
else
{
SUEntityRef entity = {DATA_PTR(self)};
if (rb_type(dictionary) == T_STRING)
{
struct AttributeDictionaryStringIterationContext dictionary_struct = {dictionary, SU_INVALID};
FOREACH(SUEntityGetNumAttributeDictionaries, SUEntityGetAttributeDictionaries, SUAttributeDictionaryRef, entity, Sketchup_AttributeDictionaries_Get_By_String_Iterator, &dictionary_struct);
if (SUIsInvalid(dictionary_struct.dictionary))
return Qnil;
SUAttributeDictionaryRelease(&dictionary_struct.dictionary);
size_t ad_count = 0;
size_t ad_len = 0;
SUEntityGetNumAttributeDictionaries(entity, &ad_len);
SUAttributeDictionaryRef* dictionaries;
SUEntityGetAttributeDictionaries(entity, ad_len, dictionaries, &ad_count);
return Data_Wrap_Struct(rb_path2class(SKETCHUP_ATTRIBUTEDICTIONARIES), 0, 0, dictionaries);
}
else if (rb_obj_is_kind_of(dictionary, rb_path2class(SKETCHUP_ATTRIBUTEDICTIONARY)))
{
SUAttributeDictionaryRef dictionary_ref = {DATA_PTR(self)};
SUAttributeDictionaryRelease(&dictionary_ref);
size_t ad_count = 0;
size_t ad_len = 0;
SUEntityGetNumAttributeDictionaries(entity, &ad_len);
SUAttributeDictionaryRef* dictionaries;
SUEntityGetAttributeDictionaries(entity, ad_len, dictionaries, &ad_count);
return Data_Wrap_Struct(rb_path2class(SKETCHUP_ATTRIBUTEDICTIONARIES), 0, 0, dictionaries);
}
else
rb_raise(rb_eArgError, "Wrong argument type. Expected String or AttributeDictionary");
}
}

VALUE AttributeDictionaries_Init(VALUE Sketchup, VALUE Sketchup_Entity)
{
VALUE Sketchup_AttributeDictionaries = rb_define_class_under(Sketchup, ATTRIBUTEDICTIONARIES, Sketchup_Entity);
Expand All @@ -42,5 +132,6 @@ VALUE AttributeDictionaries_Init(VALUE Sketchup, VALUE Sketchup_Entity)
rb_define_method(Sketchup_AttributeDictionaries, "each", Sketchup_AttributeDictionaries_each, 0);
rb_define_method(Sketchup_AttributeDictionaries, "length", Sketchup_AttributeDictionaries_length, 0);
rb_define_method(Sketchup_AttributeDictionaries, "size", Sketchup_AttributeDictionaries_length, 0);
rb_define_method(Sketchup_AttributeDictionaries, "delete", Sketchup_AttributeDictionaries_delete, 1);
return Sketchup_AttributeDictionaries;
}
4 changes: 3 additions & 1 deletion ext/model.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ static VALUE Sketchup_Model_definitions(VALUE self)

static VALUE Sketchup_Model_attribute_dictionaries(VALUE self)
{
return Data_Wrap_Struct(rb_path2class(SKETCHUP_ATTRIBUTEDICTIONARIES), 0, 0, DATA_PTR(self));
VALUE obj = Data_Wrap_Struct(rb_path2class(SKETCHUP_ATTRIBUTEDICTIONARIES), 0, 0, DATA_PTR(self));
rb_iv_set(obj, "@is_model", Qtrue);
return obj;
}

VALUE Model_Init(VALUE Sketchup, VALUE rb_cObject)
Expand Down
21 changes: 17 additions & 4 deletions test/test_attribute_dictionaries.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,26 @@ def test_object
end

def test_accessor
skip
assert_instance_of(Sketchup::AttributeDictionary, @attribute_dictionaries['GeoReference'])
assert_instance_of(Sketchup::AttributeDictionary, @attribute_dictionaries[@attribute_dictionaries['GeoReference']])
entity = Sketchup.active_model.definitions.find { |d| d.name == 'Heather' }
entity.attribute_dictionary('Age', 42)
assert_instance_of(Sketchup::AttributeDictionary, entity.attribute_dictionaries['Age'])
end

def test_count
assert_equal(3, @attribute_dictionaries.count)
end

def test_delete
skip
def test_delete_by_dictionary
assert_equal(3, @attribute_dictionaries.length)
@attribute_dictionaries.delete(@attribute_dictionaries['GeoReference'])
assert_equal(2, @attribute_dictionaries.length)
end

def test_delete_by_name
assert_equal(3, @attribute_dictionaries.length)
@attribute_dictionaries.delete('GeoReference')
assert_equal(2, @attribute_dictionaries.length)
end

def test_each
Expand All @@ -40,6 +49,10 @@ def test_length
assert_equal(3, @attribute_dictionaries.length)
end

def test_count
assert_equal(3, @attribute_dictionaries.count)
end

def test_size
assert_equal(3, @attribute_dictionaries.size)
end
Expand Down
Loading