속성 개요
이용가능한 속성 타입들은 API_AttrTypeID structure에 열거되어 있습니다. 속성의 정의는 API_Attribute structure에 설명되어 있습니다. 이것들은 실제로 모든 속성 타입들의 union입니다. 모든 속성 structure들은 API_Attr_Head라는 이름의 공통 헤더 structure로 시작합니다.
typeID
필드는 속성의 타입을 식별합니다.index
필드는 주어진 속성의 현재 데이터베이스 인덱스를 제공합니다. 속성에 대한 참조는 그것들의 인덱스를 통해 이루어집니다.guid
필드는 주어진 속성의 글로벌 유일 ID를 제공합니다. 당신은 또한 guid를 통해서도 속성을 참조할 수 있습니다.flags
필드는 일부 속성 타입 의존적인 정보를 설명합니다. 가능한 값들은 주어진 속성 structure와 동일한 곳에 목록으로 나와 있습니다.name
필드는 적절한 다이얼로그들에 나타나는 속성의 이름을 제공합니다.modiTime
필드는 속성이 최근 변경된 시간을 당신에게 알려줍니다.
많은 속성 관련 함수들은 파라미터 리스트의 API_Attribute structure를 사용합니다.
일반적으로 당신은 union에서 필요한 필드들을 채워야 합니다. 그러면 ArchiCAD는 그 값들을 기반으로 요청을 파싱하고 동일한 파라미터 안에 리턴 파라미터들을 전달합니다.
이것이 대부분의 함수들이 프로토타입에 const
지시어가 없는 이유입니다.
속성 가져오기
간단한 예제를 봅시다. 당신이 데이터 structure의 2번째 라인 타입의 정의에 관심이 있다고 가정하겠습니다. 이 경우, 당신은 API_Attribute structure 타입인 변수를 사용해야 합니다.
API_Attribute attrib; GSErrCode err; BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_LinetypeID; attrib.header.index = 2; err = ACAPI_Attribute_Get (&attrib);
속성의 설명은 union의 attrib.linetype
파트에 리턴됩니다.
이 함수를 호출하면, 당신은 주어진 속성의 기본 데이터를 얻을 수 있습니다. 예를 들면, 이름, flag, 정의된 스케일 등.
하지만 당신은 라인 타입의 실제 형태의 정의를 얻을 수 없습니다.
이 데이터를 만드는 것은 상대적으로 오랜 변환 프로세스가 될 수 있기 때문에, 이 정보는 추가적인 함수 호출로 얻을 수 있습니다.
API_AttributeDef defs; err = ACAPI_Attribute_GetDef (API_LinetypeID, 2, &defs);
이 경우, 당신은 특정 속성과 관련된 추가 데이터의 모든 것을 갖게 됩니다.
defs
structure는 여러 개의 핸들의 컬렉션입니다. (동적 메모리)
이 중 하나라도 할당되면 그것은 데이터를 포함하고 있습니다.
만약 당신이 더 이상 데이터를 필요로 하지 않는다면, 메모리 누출을 피하기 위해 반드시 할당된 메모리 블록들을 해제해야 합니다.
제안하는 방법은 다음과 같습니다:
ACAPI_DisposeAttrDefsHdls (&defs);
이 함수를 사용하면 모든 동적 데이터가 해제되고 애드온이 최신 버전의 ArchiCAD에 설치되어도 호환성 문제가 발생하지 않습니다.
API 함수들에 의해 리턴된 오류 코드들을 조사하고, 리턴된 값을 파싱하는 것은 매우 중요합니다.
일반적인 상황은 데이터베이스에서 특정 속성 타입의 인스턴스들을 검토하는 경우입니다. 다음 예제는 그것을 위한 좋은 템플릿을 제공합니다.
API_Attribute attrib; short nLin, i; GSErrCode err; BNZeroMemory (&attrib, sizeof (API_Attribute)); attrib.header.typeID = API_LinetypeID; err = ACAPI_Attribute_GetNum (API_LinetypeID, &nLin); for (i = 1; i <= nLin && err == NoError; i++) { attrib.header.index = i; err = ACAPI_Attribute_Get (&attrib); if (err == NoError) { /* 당신이 하고자 하는 것 */ } if (err == APIERR_DELETED) err = NoError; }
먼저 당신은 데이터베이스에서 라인 타입의 개수를 가져와야 합니다. ACAPI_Attribute_GetNum 함수로 그렇게 할 수 있지만, 조심하십시오. 이 함수는 인스턴스가 삭제될 수 있으므로 설치된 속성의 개수가 아닌 데이터베이스에서 사용되는 가장 큰 인덱스를 리턴합니다. 삭제된 속성들은 데이터베이스에서 즉시 삭제되지 않으므로 유효한 인덱스 범위가 (항상) 연속적이지 않다는 것을 의미합니다. 이것이 APIERR_DELETED 리턴 코드를 처리해야 하는 이유입니다.
속성 만들기
속성 생성 프로세스도 상당히 간단합니다. API_Attribute의 적절한 부분을 채우고, 선택적으로 API_AttributeDefExt structure를 채우기만 하면 됩니다. ACAPI_Attribute_CreateExt 함수는 다음과 같이 합니다:
- 가능한 불일치에 대한 데이터를 체크합니다. 만약 문제가 발생하면 자동으로 수정되거나 오류 코드가 생성될 수 있습니다.
- 예를 들면, 헤더 structure의
index
필드를 무시하므로 당신은 속성을 참조해야 하는 인덱스에 영향을 줄 수 없습니다. 이 값은 자동으로 생성되어 당신에게 리턴됩니다. - 만약 데이터베이스에 동일한 이름을 가진 속성이 있는 경우, 기존 인덱스가 리턴됩니다. 매칭 절차는 속성 정의의 차이를 무시합니다. 이름이 같은 여러 속성들은 허용되지 않습니다.
- 생성된 속성은 데이터 structure에 배치되고, 후속 API 호출에서 참조될 수 있습니다.
ArchiCAD는 당신이 할당하고 ArchiCAD에게 전달한 동적 데이터 structure를 아무 것도 해제하지 않는다는 것이 매우 중요합니다. 이것들은 당신의 코드에 의해 해제되어야 합니다.
또 다른 중요한 점은 다음과 같다. 향후 호환성을 위해 사용자가 채운 모든 데이터 structure를 0으로 초기화해야 합니다. Fillers는 API의 후기 버전에서 실제 데이터 필드들이 될 수 있으므로 이것들을 0으로 초기화하지 않으면 결과를 예측할 수 없습니다.
속성을 작성하는 템플릿은 다음과 같습니다:
API_Attribute attrib; API_AttributeDefsExt defs; short ltypeIndex; GSErrCode err; BNZeroMemory (&attrib, sizeof (API_Attribute)); BNZeroMemory (&defs, sizeof (API_AttributeDefsExt)); attrib.header.typeID = API_LinetypeID; /* attrib.linetype을 채움 */ /* dashed and symbol line types에 대한 defs 채우기 */ err = ACAPI_Attribute_CreateExt (&attrib, &defs); ltypeIndex = attrib.header.index; ACAPI_DisposeAttrDefsHdlsExt (&defs);